aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFredrik Thulin <fredrik@thulin.net>2016-05-15 10:42:23 +0200
committerFredrik Thulin <fredrik@thulin.net>2016-05-15 10:43:03 +0200
commit9b73356f2831800d2328827998e1e5b2a1994b68 (patch)
tree194357028a78b8ef92e4914074c2b3c51df5b17b
parentcc07ee6bfcf4721254145ef388196be82532fd4a (diff)
add simple filetransfer poc
-rw-r--r--projects/cli-test/Makefile6
-rw-r--r--projects/cli-test/cli-test.c57
-rw-r--r--projects/cli-test/crc32.c62
-rwxr-xr-xprojects/cli-test/filetransfer89
-rw-r--r--stm-init.c2
-rw-r--r--stm-uart.c11
-rw-r--r--stm-uart.h5
7 files changed, 220 insertions, 12 deletions
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('<I', size))
+ _read(dst)
+ # 2. Write file contents while calculating CRC-32
+ crc = 0
+ while True:
+ data = src.read(1024)
+ if not data:
+ break
+ dst.write(data)
+ print("Wrote {!s} bytes".format(len(data)))
+ crc = crc32(data, crc) & 0xffffffff
+ # 3. Write CRC-32 (4 bytes)
+ _write(dst, struct.pack('<I', crc))
+ _read(dst)
+
+ src.close()
+ dst.close()
+ return True
+
+
+if len(sys.argv) != 2:
+ sys.stderr.write('Syntax: {!s} filename\n'.format(sys.argv[0]))
+ sys.exit(1)
+
+if send_file(sys.argv[1]):
+ sys.exit(0)
+
+sys.exit(1)
+
diff --git a/stm-init.c b/stm-init.c
index 809b976..2219d43 100644
--- a/stm-init.c
+++ b/stm-init.c
@@ -87,7 +87,7 @@ static void MX_USART1_UART_Init(void)
huart_mgmt.Init.StopBits = UART_STOPBITS_1;
huart_mgmt.Init.Parity = UART_PARITY_NONE;
huart_mgmt.Init.Mode = UART_MODE_TX_RX;
- huart_mgmt.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+ huart_mgmt.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS; //UART_HWCONTROL_NONE;
huart_mgmt.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart_mgmt) != HAL_OK) {
diff --git a/stm-uart.c b/stm-uart.c
index ce52ca0..2605f99 100644
--- a/stm-uart.c
+++ b/stm-uart.c
@@ -115,6 +115,17 @@ HAL_StatusTypeDef uart_send_bytes(enum stm_uart_port port, uint8_t *buf, size_t
return HAL_ERROR;
}
+/* receive raw bytes */
+HAL_StatusTypeDef uart_receive_bytes(enum stm_uart_port port, uint8_t *buf, size_t len, uint32_t timeout)
+{
+ UART_HandleTypeDef *uart = _which_uart(port);
+
+ if (uart)
+ return HAL_UART_Receive(uart, (uint8_t *) buf, (uint32_t) len, timeout);
+
+ return HAL_ERROR;
+}
+
/* Generalized routine to send binary, decimal, and hex integers.
* This code is adapted from Chris Giese's printf.c
*/
diff --git a/stm-uart.h b/stm-uart.h
index 2330c8b..21f3701 100644
--- a/stm-uart.h
+++ b/stm-uart.h
@@ -37,8 +37,8 @@
#include "stm32f4xx_hal.h"
-#define USART_MGMT_BAUD_RATE 9600
-#define USART_USER_BAUD_RATE 9600
+#define USART_MGMT_BAUD_RATE 115200
+#define USART_USER_BAUD_RATE 115200
enum stm_uart_port {
STM_UART_USER,
@@ -61,6 +61,7 @@ extern HAL_StatusTypeDef uart_send_string2(enum stm_uart_port port, const char *
extern HAL_StatusTypeDef uart_send_number2(enum stm_uart_port port, uint32_t num, uint8_t digits, uint8_t radix);
extern HAL_StatusTypeDef uart_send_bytes(enum stm_uart_port port, uint8_t *buf, size_t len);
+extern HAL_StatusTypeDef uart_receive_bytes(enum stm_uart_port port, uint8_t *buf, size_t len, uint32_t timeout);
#define uart_send_binary(num, bits) uart_send_number(num, bits, 2)
#define uart_send_integer(num, digits) uart_send_number(num, digits, 10)