[Cryptech-Commits] [sw/stm32] 02/03: Adapt uart_rx_thread to the post-thread tasking model, because we're still subject to the same forces that made it a good idea in the first place.

git at cryptech.is git at cryptech.is
Tue Aug 22 17:29:56 UTC 2017


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

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

commit e4302fb3f0f9c9b60d79a83a69d02ca23fb663ff
Author: Paul Selkirk <paul at psgd.org>
AuthorDate: Mon Jul 31 23:23:14 2017 -0400

    Adapt uart_rx_thread to the post-thread tasking model, because we're still
    subject to the same forces that made it a good idea in the first place.
    
        commit 2b6b9f8
        Change RPC UART to have a high-priority thread monitoring a large(ish) DMA
        buffer, because we've observed out-of-order receives under load.
---
 projects/hsm/hsm.c | 49 ++++++++++++++++++++++++++++++++-----------------
 1 file changed, 32 insertions(+), 17 deletions(-)

diff --git a/projects/hsm/hsm.c b/projects/hsm/hsm.c
index 8a8f441..28a1e68 100644
--- a/projects/hsm/hsm.c
+++ b/projects/hsm/hsm.c
@@ -244,25 +244,38 @@ static void RxCallback(uint8_t c)
     }
 }
 
-static uint8_t uart_rx[2];      /* current character received from UART */
-static uint32_t uart_rx_idx = 0;
-
-/* UART DMA half-complete and complete callbacks. With a 2-character DMA
- * buffer, one or the other of these will fire on each incoming character.
- * Under heavy load, these will sometimes fire in the wrong order, but the
- * data are in the right order in the DMA buffer, so we have a flip-flop
- * buffer index that doesn't depend on the order of the callbacks.
+/* A ring buffer for the UART DMA receiver. In theory, it should get at most
+ * 92 characters per 1ms tick, but we're going to up-size it for safety.
  */
-void HAL_UART2_RxHalfCpltCallback(UART_HandleTypeDef *huart)
-{
-    RxCallback(uart_rx[uart_rx_idx]);
-    uart_rx_idx ^= 1;
-}
+#ifndef RPC_UART_RECVBUF_SIZE
+#define RPC_UART_RECVBUF_SIZE  1024  /* must be a power of 2 */
+#endif
+#define RPC_UART_RECVBUF_MASK  (RPC_UART_RECVBUF_SIZE - 1)
+
+typedef struct {
+    uint32_t ridx;
+    uint8_t buf[RPC_UART_RECVBUF_SIZE];
+} uart_ringbuf_t;
 
-void HAL_UART2_RxCpltCallback(UART_HandleTypeDef *huart)
+volatile uart_ringbuf_t uart_ringbuf = {0, {0}};
+
+#define RINGBUF_RIDX(rb)       (rb.ridx & RPC_UART_RECVBUF_MASK)
+#define RINGBUF_WIDX(rb)       (sizeof(rb.buf) - __HAL_DMA_GET_COUNTER(huart_user.hdmarx))
+#define RINGBUF_COUNT(rb)      ((RINGBUF_WIDX(rb) - RINGBUF_RIDX(rb)) & RPC_UART_RECVBUF_MASK)
+#define RINGBUF_READ(rb, dst)  {dst = rb.buf[RINGBUF_RIDX(rb)]; rb.ridx++;}
+
+size_t uart_rx_max = 0;
+
+static void uart_rx_task(void)
 {
-    RxCallback(uart_rx[uart_rx_idx]);
-    uart_rx_idx ^= 1;
+    size_t count = RINGBUF_COUNT(uart_ringbuf);
+    if (uart_rx_max < count) uart_rx_max = count;
+
+    while (RINGBUF_COUNT(uart_ringbuf)) {
+        uint8_t c;
+        RINGBUF_READ(uart_ringbuf, c);
+        RxCallback(c);
+    }
 }
 
 /* Send one character over the UART. This is called from
@@ -425,7 +438,9 @@ int main(void)
         Error_Handler();
 
     /* Start the UART receiver. */
-    if (HAL_UART_Receive_DMA(&huart_user, uart_rx, 2) != CMSIS_HAL_OK)
+    extern void set_SysTick_hook(void (*hook)(void));
+    set_SysTick_hook(uart_rx_task);
+    if (HAL_UART_Receive_DMA(&huart_user, (uint8_t *) uart_ringbuf.buf, sizeof(uart_ringbuf.buf)) != CMSIS_HAL_OK)
         Error_Handler();
 
     /* Launch other tasks (csprng warm-up task?)



More information about the Commits mailing list