From 9b73356f2831800d2328827998e1e5b2a1994b68 Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Sun, 15 May 2016 10:42:23 +0200 Subject: add simple filetransfer poc --- projects/cli-test/Makefile | 6 ++- projects/cli-test/cli-test.c | 57 +++++++++++++++++++++++---- projects/cli-test/crc32.c | 62 +++++++++++++++++++++++++++++ projects/cli-test/filetransfer | 89 ++++++++++++++++++++++++++++++++++++++++++ stm-init.c | 2 +- stm-uart.c | 11 ++++++ stm-uart.h | 5 ++- 7 files changed, 220 insertions(+), 12 deletions(-) create mode 100644 projects/cli-test/crc32.c create mode 100755 projects/cli-test/filetransfer diff --git a/projects/cli-test/Makefile b/projects/cli-test/Makefile index 1f1f890..d0fce70 100644 --- a/projects/cli-test/Makefile +++ b/projects/cli-test/Makefile @@ -1,11 +1,15 @@ TEST = cli-test +OBJS = crc32.o + +LIBCLI_DIR=/home/ft/work/others/libcli.arm + CFLAGS += -I$(LIBCLI_DIR) LIBS += $(LIBCLI_DIR)/libcli.a all: $(TEST:=.elf) -%.elf: %.o $(BOARD_OBJS) $(LIBS) +%.elf: %.o $(BOARD_OBJS) $(OBJS) $(LIBS) $(CC) $(CFLAGS) $^ -o $@ -T$(LDSCRIPT) -g -Wl,-Map=$*.map $(OBJCOPY) -O ihex $*.elf $*.hex $(OBJCOPY) -O binary $*.elf $*.bin diff --git a/projects/cli-test/cli-test.c b/projects/cli-test/cli-test.c index 2f246a5..0b54e7e 100644 --- a/projects/cli-test/cli-test.c +++ b/projects/cli-test/cli-test.c @@ -12,14 +12,6 @@ #define DELAY() HAL_Delay(250) -int cmd_show_cpuspeed(struct cli_def *cli, const char *command, char *argv[], int argc) -{ - volatile uint32_t hclk; - - hclk = HAL_RCC_GetHCLKFreq(); - cli_print(cli, "HCLK: %li (%i MHz)", hclk, (int) hclk / 1000 / 1000); - return CLI_OK; -} void uart_cli_print(struct cli_def *cli __attribute__ ((unused)), const char *buf) { @@ -42,6 +34,50 @@ int uart_cli_write(struct cli_def *cli __attribute__ ((unused)), const void *buf return (int) count; } +int cmd_show_cpuspeed(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + volatile uint32_t hclk; + + hclk = HAL_RCC_GetHCLKFreq(); + cli_print(cli, "HSE_VALUE: %li", HSE_VALUE); + cli_print(cli, "HCLK: %li (%i MHz)", hclk, (int) hclk / 1000 / 1000); + cli_print(cli, "SystemCoreClock: %li (%i MHz)", SystemCoreClock, (int) SystemCoreClock / 1000 / 1000); + return CLI_OK; +} + +extern uint32_t update_crc(uint32_t crc, uint8_t *buf, int len); + +int cmd_filetransfer(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + uint32_t filesize = 0, crc = 0, my_crc = 0, n = 4; + uint8_t buf[4]; + + cli_print(cli, "OK, write file size (4 bytes), data, CRC-32 (4 bytes)"); + + uart_receive_bytes(STM_UART_MGMT, (void *) &filesize, 4, 1000); + cli_print(cli, "Filesize %li", filesize); + + while (filesize) { + if (filesize < n) { + n = filesize; + } + + uart_receive_bytes(STM_UART_MGMT, (void *) &buf, n, 1000); + filesize -= n; + my_crc = update_crc(my_crc, buf, n); + } + + uart_receive_bytes(STM_UART_MGMT, (void *) &crc, 4, 1000); + cli_print(cli, "CRC-32 %li", crc); + if (crc == my_crc) { + cli_print(cli, "CRC checksum MATCHED"); + } else { + cli_print(cli, "CRC checksum did NOT match"); + } + + return CLI_OK; +} + int embedded_cli_loop(struct cli_def *cli) { unsigned char c; @@ -109,6 +145,9 @@ main() struct cli_command cmd_show_cpuspeed_s = {(char *) "cpuspeed", cmd_show_cpuspeed, 0, (char *) "Show the speed at which the CPU currently operates", PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL, NULL, NULL}; + struct cli_command cmd_filetransfer_s = {(char *) "filetransfer", cmd_filetransfer, 0, + (char *) "Test file transfering", + PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL, NULL, NULL}; char crlf[] = "\r\n"; uint8_t tx = 'A'; @@ -134,6 +173,8 @@ main() cli_register_command2(&cli, &cmd_show_s, NULL); cli_register_command2(&cli, &cmd_show_cpuspeed_s, &cmd_show_s); + cli_register_command2(&cli, &cmd_filetransfer_s, NULL); + HAL_GPIO_WritePin(LED_PORT, LED_RED, GPIO_PIN_RESET); HAL_GPIO_WritePin(LED_PORT, LED_GREEN, GPIO_PIN_SET); diff --git a/projects/cli-test/crc32.c b/projects/cli-test/crc32.c new file mode 100644 index 0000000..4d1a0bc --- /dev/null +++ b/projects/cli-test/crc32.c @@ -0,0 +1,62 @@ +/* Reference code from RFC1952. Not meant to be used outside test code. */ + +#include "stm32f4xx_hal.h" + + +/* Table of CRCs of all 8-bit messages. */ +unsigned long crc_table[256]; + +/* Flag: has the table been computed? Initially false. */ +int crc_table_computed = 0; + +/* Make the table for a fast CRC. */ +void make_crc_table(void) +{ + unsigned long c; + + int n, k; + for (n = 0; n < 256; n++) { + c = (unsigned long) n; + for (k = 0; k < 8; k++) { + if (c & 1) { + c = 0xedb88320L ^ (c >> 1); + } else { + c = c >> 1; + } + } + crc_table[n] = c; + } + crc_table_computed = 1; +} + +/* + Update a running crc with the bytes buf[0..len-1] and return + the updated crc. The crc should be initialized to zero. Pre- and + post-conditioning (one's complement) is performed within this + function so it shouldn't be done by the caller. Usage example: + + unsigned long crc = 0L; + + while (read_buffer(buffer, length) != EOF) { + crc = update_crc(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ +uint32_t update_crc(uint32_t crc, uint8_t *buf, int len) +{ + unsigned long c = crc ^ 0xffffffffL; + int n; + + if (!crc_table_computed) + make_crc_table(); + for (n = 0; n < len; n++) { + c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); + } + return c ^ 0xffffffffL; +} + +/* Return the CRC of the bytes buf[0..len-1]. */ +unsigned long crc(unsigned char *buf, int len) +{ + return update_crc(0L, buf, len); +} diff --git a/projects/cli-test/filetransfer b/projects/cli-test/filetransfer new file mode 100755 index 0000000..92b117f --- /dev/null +++ b/projects/cli-test/filetransfer @@ -0,0 +1,89 @@ +#!/usr/bin/python + +import os +import sys +import time +import struct +import serial + +from binascii import crc32 + + +def _write(dst, data): + dst.write(data) + if len(data) == 4: + print("Wrote 0x{:02x}{:02x}{:02x}{:02x}".format(ord(data[0]), ord(data[1]), ord(data[2]), ord(data[3]))) + else: + print("Wrote {!r}".format(data)) + + +def _read(dst): + res = '' + while True: + x = dst.read(1) + if not x: + break + res += x + print ("Read {!r}".format(res)) + return res + + +def _execute(dst, cmd): + _write(dst, '\r') + prompt = _read(dst) + if prompt.endswith('Username: '): + _write(dst, 'ct\r') + prompt = _read(dst) + if prompt.endswith('Password: '): + _write(dst, 'ct\r') + prompt = _read(dst) + if not prompt.endswith('> '): + sys.stderr.write('Device does not seem to be ready for a file transfer (got {!r})\n'.format(prompt)) + return False + _write(dst, cmd + '\r') + response = _read(dst) + return response + +def send_file(filename, device='/dev/ttyUSB0', initiate=True): + s = os.stat(filename) + size = s.st_size + src = open(filename, 'rb') + + dst = serial.Serial(device, 115200, timeout=0.5) + + if initiate: + response = _execute(dst, 'filetransfer') + if 'OK' not in response: + sys.stderr.write('Device did not accept the filetransfer command (got {!r})\n'.format(response)) + return False + + # 1. Write size of file (4 bytes) + _write(dst, struct.pack('