Commit 45954a09 by Enrico Pozzobon

arduino bluepill template

parent f6392362
NISTGCCFLAGS=-std=c99 -Wall -Wextra -Wshadow -fsanitize=address,undefined -O2
LFLAGS=-lm
all: bluepill_f103c8
bluepill_f103c8: .pioenvs/bluepill_f103c8/firmware.hex
.pioenvs/bluepill_f103c8/firmware.hex: FORCE
platformio run -e bluepill_f103c8
FORCE: ;
.PHONY: clean
clean:
-rm .pioenvs/uno/firmware.hex
#!/bin/bash
mv -n *.c *.C *.s *.S src/
mv -n *.inc *.h *.H include/
sed -i src/encrypt.c -e "s/\(\s\)init(/\1_init(/g"
exit 0
#ifdef __cplusplus
extern "C" {
#endif
int crypto_aead_encrypt(
unsigned char *c,unsigned long long *clen,
const unsigned char *m,unsigned long long mlen,
const unsigned char *ad,unsigned long long adlen,
const unsigned char *nsec,
const unsigned char *npub,
const unsigned char *k
);
int crypto_aead_decrypt(
unsigned char *m,unsigned long long *outputmlen,
unsigned char *nsec,
const unsigned char *c,unsigned long long clen,
const unsigned char *ad,unsigned long long adlen,
const unsigned char *npub,
const unsigned char *k
);
#ifdef __cplusplus
}
#endif
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void uartp_send(const void *src, uint16_t len);
uint16_t uartp_recv(void *dst, uint16_t buf_len);
#ifdef __cplusplus
}
#endif
[env:bluepill_f103c8]
platform = ststm32
framework = arduino
board = bluepill_f103c8_128k
upload_protocol = jlink
build_flags = -O2
-D NUM_ANALOG_INPUTS=10
-D NUM_ANALOG_FIRST=20
build_unflags = -Os
#include "crypto_aead.h"
#include "api.h"
#include "uartp.h"
#define MAX_BYTES 100
//#define DEBUG
#define CRYPTO_BUSY B11
uint8_t npub[CRYPTO_NPUBBYTES];
uint8_t nsec[CRYPTO_NSECBYTES];
uint8_t k[CRYPTO_KEYBYTES];
uint8_t ad[MAX_BYTES];
unsigned long long int adlen;
uint8_t m[MAX_BYTES];
unsigned long long int mlen;
uint8_t c[MAX_BYTES];
unsigned long long int clen;
int res;
void setup();
void loop();
#ifdef __cplusplus
extern "C" {
#endif
void uart_wbyte(uint8_t x) {
Serial1.write((uint8_t) (x));
}
uint8_t uart_rbyte() {
int r;
do {
r = Serial1.read();
} while (r == -1);
return (uint8_t) (0xff & r);
}
#ifdef __cplusplus
}
#endif
int dbg_printf(const char *format, ...) {
int r = 0;
#ifdef DEBUG
#define DEBUG_BUF_LEN 80
char printbuf[DEBUG_BUF_LEN+2];
va_list vargs;
va_start(vargs, format);
r = vsnprintf(printbuf+1, DEBUG_BUF_LEN, format, vargs);
va_end(vargs);
if (r < 0) {
memcpy(printbuf+1, "DEBUG ERROR\r\n", 13);
r = 13;
}
r = r > DEBUG_BUF_LEN ? DEBUG_BUF_LEN : r;
printbuf[0] = 0xde; // Debug messages should start with "\xde"
uartp_send(printbuf, r+1);
#endif
return r;
}
void my_assert(bool b) {
if (b)
return;
dbg_printf("Assertion failed\r\n");
for(;;)
yield();
}
void setup() {
Serial1.begin(115200);
pinMode(CRYPTO_BUSY, OUTPUT);
digitalWrite(CRYPTO_BUSY, HIGH);
delay(100);
Serial1.print("Hello, World!");
}
void loop() {
static uint8_t buf[256];
uint16_t len = uartp_recv(buf, 255);
uint8_t action = buf[0];
if (len == 0 || len > 255)
return;
uint16_t l = len - 1;
uint16_t rl = 0;
uint8_t *var = buf+1;
switch (action) {
case 'm': my_assert(l <= MAX_BYTES); memcpy(m, var, l); mlen = l; break;
case 'c': my_assert(l <= MAX_BYTES); memcpy(c, var, l); clen = l; break;
case 'a': my_assert(l <= MAX_BYTES); memcpy(ad, var, l); adlen = l; break;
case 'k': my_assert(l == CRYPTO_KEYBYTES); memcpy(k, var, l); break;
case 'p': my_assert(l == CRYPTO_NPUBBYTES); memcpy(npub, var, l); break;
case 's': my_assert(l == CRYPTO_NSECBYTES); memcpy(nsec, var, l); break;
case 'e':
noInterrupts();
asm("nop");
digitalWrite(CRYPTO_BUSY, LOW);
res = crypto_aead_encrypt(c, &clen, m, mlen, ad, adlen, nsec, npub, k);
digitalWrite(CRYPTO_BUSY, HIGH);
asm("nop");
interrupts();
break;
case 'd':
noInterrupts();
asm("nop");
digitalWrite(CRYPTO_BUSY, LOW);
res = crypto_aead_decrypt(m, &mlen, nsec, c, clen, ad, adlen, npub, k);
digitalWrite(CRYPTO_BUSY, HIGH);
asm("nop");
interrupts();
break;
case'M': var = m; rl = mlen; break;
case'C': var = c; rl = clen; break;
case'A': var = ad; rl = adlen; break;
case'K': var = k; rl = CRYPTO_KEYBYTES; break;
case'P': var = npub; rl = CRYPTO_NPUBBYTES; break;
case'S': var = nsec; rl = CRYPTO_NSECBYTES; break;
case'R': var = (uint8_t *) &res; rl = sizeof(res); break;
default:
dbg_printf("Unknown command\r\n");
my_assert(false);
}
buf[0] = action;
memcpy(buf+1, var, rl);
uartp_send(buf, rl+1);
}
#include <stdint.h>
#include "uartp.h"
extern void uart_wbyte(uint8_t x);
extern uint8_t uart_rbyte();
// Simple serial protocol with packets and checksum
const uint8_t AMUX_TAG = 0xf9;
const uint8_t AMUX_END = 0xf3;
const uint8_t AMUX_EXT = 0x80;
void uartp_send(const void *src, uint16_t len) {
uint8_t len_ind_0, len_ind_1, fcs, info;
const uint8_t *buf = (const uint8_t *) src;
uart_wbyte(AMUX_TAG);
len_ind_0 = (uint8_t) (0xff & len);
len_ind_1 = (uint8_t) (0xff & (len >> 7));
if (len < 128) {
uart_wbyte(len_ind_0);
} else {
uart_wbyte(len_ind_0 | AMUX_EXT);
uart_wbyte(len_ind_1);
}
fcs = 0;
for (uint16_t i = 0; i < len; i++) {
info = buf[i];
fcs += info;
uart_wbyte(buf[i]);
}
fcs = 255 - fcs;
uart_wbyte(fcs);
uart_wbyte(AMUX_END);
}
uint16_t uartp_recv(void *dst, uint16_t buf_len) {
uint8_t *buf = (uint8_t *) dst;
uint8_t tag_old, tag, info, cs;
uint16_t len;
tag = AMUX_END;
while (1) {
do {
tag_old = tag;
tag = uart_rbyte();
} while(tag != AMUX_TAG || tag_old != AMUX_END);
len = (uint16_t) uart_rbyte();
if (len & AMUX_EXT) {
len &= (~AMUX_EXT);
len |= (uint16_t) (uart_rbyte() << 7);
}
if (len > buf_len) {
return len;
}
uint16_t i = 0;
cs = 0;
for (i = 0; i < len; i++) {
info = uart_rbyte();
buf[i] = info;
cs += info;
}
cs += uart_rbyte();
tag = uart_rbyte();
if (0xff == cs) {
if (AMUX_END == tag) {
return len;
}
}
}
}
#!/usr/bin/env python3
import os
import sys
import time
import struct
import serial
import subprocess
def eprint(*args, **kargs):
print(*args, file=sys.stderr, **kargs)
def flash():
pipe = subprocess.PIPE
cmd = ['platformio', 'run', '-e', 'bluepill_f103c8', '--target', 'upload']
p = subprocess.Popen(cmd,
stdout=sys.stderr, stdin=pipe)
stdout, stderr = p.communicate("")
def get_serial():
import serial.tools.list_ports
ports = serial.tools.list_ports.comports()
devices = [ p.device for p in ports ]
devices.sort()
return devices[-1]
class UARTP:
def __init__(self, ser):
UARTP.SYN = 0xf9
UARTP.FIN = 0xf3
self.ser = ser
def uart_read(self):
r = self.ser.read(1)
if len(r) != 1:
raise Exception("Serial read error")
return r[0]
def uart_write(self, c):
b = struct.pack("B", c)
r = self.ser.write(b)
if r != len(b):
raise Exception("Serial write error")
return r
def send(self, buf):
self.uart_write(UARTP.SYN)
len_ind_0 = 0xff & len(buf)
len_ind_1 = 0xff & (len(buf) >> 7)
if len(buf) < 128:
self.uart_write(len_ind_0)
else:
self.uart_write(len_ind_0 | 0x80)
self.uart_write(len_ind_1)
fcs = 0
for i in range(len(buf)):
info = buf[i]
fcs = (fcs + info) & 0xff
self.uart_write(buf[i])
fcs = (0xff - fcs) & 0xff
self.uart_write(fcs)
self.uart_write(UARTP.FIN)
eprint("sent frame '%s'" % buf.hex())
def recv(self):
tag_old = UARTP.FIN
while 1:
tag = tag_old
while 1:
if tag_old == UARTP.FIN:
if tag == UARTP.SYN:
break
tag_old = tag
tag = self.uart_read()
tag_old = tag
l = self.uart_read()
if l & 0x80:
l &= 0x7f
l |= self.uart_read() << 7
fcs = 0
buf = []
for i in range(l):
info = self.uart_read()
buf.append(info)
fcs = (fcs + info) & 0xff
fcs = (fcs + self.uart_read()) & 0xff
tag = self.uart_read()
if fcs == 0xff:
if tag == UARTP.FIN:
buf = bytes(buf)
eprint("rcvd frame '%s'" % buf.hex())
if len(buf) >= 1 and buf[0] == 0xde:
sys.stderr.buffer.write(buf[1:])
sys.stderr.flush()
else:
return buf
def main(argv):
eprint(argv[0])
script_dir = os.path.split(argv[0])[0]
if len(script_dir) > 0:
os.chdir(script_dir)
dev = get_serial()
ser = serial.Serial(dev, baudrate=115200, timeout=5)
uartp = UARTP(ser)
flash()
eprint("Flashed")
time.sleep(0.1)
ser.setDTR(False) # IO0=HIGH
ser.setRTS(True) # EN=LOW, chip in reset
time.sleep(0.1)
ser.setDTR(False) # IO0=HIGH
ser.setRTS(False) # EN=HIGH, chip out of reset
time.sleep(1)
def stdin_read(n):
b = sys.stdin.buffer.read(n)
if len(b) != n:
sys.exit(1)
return b
def stdin_readvar():
l = stdin_read(4)
(l, ) = struct.unpack("<I", l)
v = stdin_read(l)
return v
exp_hello = b"Hello, World!"
hello = ser.read(ser.in_waiting)
if hello[-13:] != exp_hello:
eprint("Improper board initialization message: %s" % hello)
return 1
eprint("Board initialized properly")
sys.stdout.write("Hello, World!\n")
sys.stdout.flush()
while 1:
action = stdin_read(1)[0]
eprint("Command %c from stdin" % action)
if action in b"ackmps":
v = stdin_readvar()
uartp.send(struct.pack("B", action) + v)
ack = uartp.recv()
if len(ack) != 1 or ack[0] != action:
raise Exception("Unacknowledged variable transfer")
eprint("Var %c successfully sent to board" % action)
elif action in b"ACKMPS":
c = struct.pack("B", action)
uartp.send(c)
v = uartp.recv()
if len(v) < 1 or v[0] != action:
raise Exception("Could not obtain variable from board")
v = v[1:]
eprint("Var %c received from board: %s" % (action, v.hex()))
l = struct.pack("<I", len(v))
sys.stdout.buffer.write(l + v)
sys.stdout.flush()
elif action in b"ed":
c = struct.pack("B", action)
uartp.send(c)
ack = uartp.recv()
if len(ack) != 1 or ack[0] != action:
raise Exception("Unacknowledged variable transfer")
eprint("Operation %c completed successfully" % action)
else:
raise Exception("Unknown action %c" % action)
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment