[Cryptech-Commits] [sw/stm32] 01/01: Use a 1-byte DMA buffer for management UART receives.

git at cryptech.is git at cryptech.is
Wed Jun 15 05:50:59 UTC 2016


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

paul at psgd.org pushed a commit to branch alternate_dma
in repository sw/stm32.

commit c1d073875eea91c7f4e14b9aa0d7a9c12cf598c2
Author: Paul Selkirk <paul at psgd.org>
AuthorDate: Wed Jun 15 00:19:58 2016 -0400

    Use a 1-byte DMA buffer for management UART receives.
    
    It sounds silly, but this gives us completion callbacks, so we don't spend
    out entire time slice polling the receive buffer for new characters (which
    kills performance for tasks that are doing real work). Besides, libcli
    wants to process a character at a time, so uart_cli_read just waits on the
    completion callback.
---
 projects/hsm/mgmt-cli.c | 94 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 68 insertions(+), 26 deletions(-)

diff --git a/projects/hsm/mgmt-cli.c b/projects/hsm/mgmt-cli.c
index bef530e..d9c0bd9 100644
--- a/projects/hsm/mgmt-cli.c
+++ b/projects/hsm/mgmt-cli.c
@@ -34,6 +34,8 @@
 
 #include <string.h>
 
+#include "cmsis_os.h"
+
 #include "stm-init.h"
 #include "stm-uart.h"
 #include "stm-led.h"
@@ -44,26 +46,74 @@
 #include "mgmt-misc.h"
 #include "mgmt-show.h"
 
-/* MGMT UART interrupt receive buffer (data will be put in a larger ring buffer) */
-volatile uint8_t uart_rx;
-
 #ifndef CLI_UART_RECVBUF_SIZE
 #define CLI_UART_RECVBUF_SIZE  256  /* This must be a power of 2 */
 #endif
 #define CLI_UART_RECVBUF_MASK  (CLI_UART_RECVBUF_SIZE - 1)
 
 typedef struct {
-    uint32_t enabled, ridx;
+    int ridx;
+    int widx;	
     mgmt_cli_dma_state_t rx_state;
     uint8_t buf[CLI_UART_RECVBUF_SIZE];
-} uart_ringbuf_t;
+} ringbuf_t;
 
-volatile uart_ringbuf_t uart_ringbuf = {1, 0, DMA_RX_STOP, {0}};
+inline void ringbuf_init(ringbuf_t *rb)
+{
+    memset(rb, 0, sizeof(*rb));
+}
 
-#define RINGBUF_RIDX(rb)       (rb.ridx & CLI_UART_RECVBUF_MASK)
-#define RINGBUF_WIDX(rb)       (sizeof(rb.buf) - __HAL_DMA_GET_COUNTER(huart_mgmt.hdmarx))
-#define RINGBUF_COUNT(rb)      ((unsigned)(RINGBUF_WIDX(rb) - RINGBUF_RIDX(rb)))
-#define RINGBUF_READ(rb, dst)  {dst = rb.buf[RINGBUF_RIDX(rb)]; rb.buf[RINGBUF_RIDX(rb)] = '.'; rb.ridx++;}
+/* return number of characters read */
+inline int ringbuf_read_char(ringbuf_t *rb, uint8_t *c)
+{
+    if (rb->ridx != rb->widx) {
+        *c = rb->buf[rb->ridx];
+        if (++rb->ridx >= sizeof(rb->buf))
+            rb->ridx = 0;
+        return 1;
+    }
+    return 0;
+}
+
+inline void ringbuf_write_char(ringbuf_t *rb, uint8_t c)
+{
+    rb->buf[rb->widx] = c;
+    if (++rb->widx >= sizeof(rb->buf))
+        rb->widx = 0;
+}
+
+/* some possibly-useful functions */
+inline int ringbuf_empty(ringbuf_t *rb)
+{
+    return (rb->ridx == rb->widx);
+}
+
+inline int ringbuf_count(ringbuf_t *rb)
+{
+    int len = rb->widx - rb->ridx;
+    if (len < 0)
+        len += sizeof(rb->buf);
+    return len;
+}
+
+static ringbuf_t uart_ringbuf;
+
+/* current character received from UART */
+static uint8_t uart_rx;
+
+/* Semaphore to inform uart_cli_read that there's a new character.
+ */
+osSemaphoreId  uart_sem;
+osSemaphoreDef(uart_sem);
+
+/* Callback for HAL_UART_Receive_DMA().
+ */
+void HAL_UART1_RxCpltCallback(UART_HandleTypeDef *huart)
+{
+    ringbuf_write_char(&uart_ringbuf, uart_rx);
+    osSemaphoreRelease(uart_sem);
+    HAL_UART_Receive_DMA(huart, &uart_rx, 1);
+}
 
 static void uart_cli_print(struct cli_def *cli __attribute__ ((unused)), const char *buf)
 {
@@ -74,18 +124,11 @@ static void uart_cli_print(struct cli_def *cli __attribute__ ((unused)), const c
 
 static int uart_cli_read(struct cli_def *cli __attribute__ ((unused)), void *buf, size_t count)
 {
-    uint32_t timeout = 0xffffff;
-    while (count && timeout) {
-	if (RINGBUF_COUNT(uart_ringbuf)) {
-	    RINGBUF_READ(uart_ringbuf, *(uint8_t *) buf);
-	    buf++;
-	    count--;
-	}
-	timeout--;
+    for (int i = 0; i < count; ++i) {
+        while (ringbuf_read_char(&uart_ringbuf, (uint8_t *)(buf + i)) == 0)
+            osSemaphoreWait(uart_sem, osWaitForever);
     }
-    if (! timeout) return 0;
-
-    return 1;
+    return count;
 }
 
 static int uart_cli_write(struct cli_def *cli __attribute__ ((unused)), const void *buf, size_t count)
@@ -98,11 +141,8 @@ int control_mgmt_uart_dma_rx(mgmt_cli_dma_state_t state)
 {
     if (state == DMA_RX_START) {
 	if (uart_ringbuf.rx_state != DMA_RX_START) {
-	    memset((void *) uart_ringbuf.buf, 0, sizeof(uart_ringbuf.buf));
-
-	    /* Start receiving data from the UART using DMA */
-	    HAL_UART_Receive_DMA(&huart_mgmt, (uint8_t *) uart_ringbuf.buf, sizeof(uart_ringbuf.buf));
-	    uart_ringbuf.ridx = 0;
+            ringbuf_init(&uart_ringbuf);
+	    HAL_UART_Receive_DMA(&huart_mgmt, &uart_rx, 1);
 	    uart_ringbuf.rx_state = DMA_RX_START;
 	}
 	return 1;
@@ -195,6 +235,8 @@ int cli_main(void)
 {
     static struct cli_def cli;
 
+    uart_sem = osSemaphoreCreate(osSemaphore(uart_sem), 0);
+
     mgmt_cli_init(&cli);
     cli_set_auth_callback(&cli, check_auth);
 



More information about the Commits mailing list