[Cryptech-Commits] [sw/stm32] 12/12: add simple filetransfer poc

git at cryptech.is git at cryptech.is
Mon May 16 09:43:25 UTC 2016


This is an automated email from the git hooks/post-receive script.

fredrik at thulin.net pushed a commit to branch ft-alpha_board_bringup
in repository sw/stm32.

commit 9b73356f2831800d2328827998e1e5b2a1994b68
Author: Fredrik Thulin <fredrik at thulin.net>
AuthorDate: Sun May 15 10:42:23 2016 +0200

    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(-)

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)



More information about the Commits mailing list