Переглянути джерело

✨ feat: 添加串口接收线程

添加了串口接收线程,为了方便使用,目前该线程使用轮询读取串口数据,以后再考虑优化,并在实际硬件上进行了单元测试。
Jackistang 4 роки тому
батько
коміт
5979bb38c0

+ 1 - 0
CMakeLists.txt

@@ -7,6 +7,7 @@ set(CMAKE_BUILD_TYPE "Debug")
 set(SOURCES
     # src/hci_transport_uart_linux.c
     src/hci_transport_h4.c
+    src/receiver.c
 
 # porting os
     porting/os/linux/src/os_mutex.c

+ 27 - 1
include/hci_transport_h4.h

@@ -17,10 +17,36 @@ enum {
 };
 
 struct rt_hci_transport_h4_config {
+    /**
+     * @brief Receive package callback.
+     * 
+     * @param type      Controller to Host package type, ACL, SYNC, EVENT, or ISO.
+     * @param buf       Package buffer.
+     * @param length    Package length
+    */
     void (*package_callback)(int type, uint8_t *buf, size_t length);
 };
 
-extern int rt_hci_transport_h4_init(struct rt_hci_transport_h4_config *config);
+/**
+ * @brief Init hci transport h4 .
+ * 
+ * @param config    Init configure.
+ * 
+ * @return void
+*/
+extern void rt_hci_transport_h4_init(struct rt_hci_transport_h4_config *config);
+
+/**
+ * @brief HCI transport h4 send package.
+ * 
+ * @param type      HCI package type.
+ * @param buf       HCI package buffer.
+ * @param length    HCI package length.
+ * 
+ * @return int
+ * @retval  >=0     Sended data length.
+ * @retval  -1      Send fail.
+*/
 extern int rt_hci_transport_h4_send(int type, uint8_t *buf, size_t length);
 
 

+ 9 - 0
porting/os/include/os_port.h

@@ -43,6 +43,15 @@ extern int os_task_create(struct os_task *t, const char *name, os_task_func_t fu
 */
 extern int os_task_remove(struct os_task *t);
 
+/**
+ * @brief Sleep ms.
+ * 
+ * @param   ms  The sleep time with ms.
+ * 
+ * @return void
+*/
+extern void os_sleep(int ms);
+
 /*
  * Semaphores
  */

+ 1 - 1
porting/os/linux/include/os_type.h

@@ -13,7 +13,7 @@ extern "C" {
 #define OS_WAIT_FOREVER (-1)
 
 typedef uint32_t os_time_t;
-typedef int os_stack_t;
+typedef uint8_t os_stack_t;
 
 typedef void *(*os_task_func_t)(void *);
 

+ 8 - 0
porting/os/linux/src/os_task.c

@@ -1,6 +1,8 @@
 #include "os_type.h"
 #include <errno.h>
 #include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
 
 #define UNUSED(n)   ((void*)(sizeof(n)))
 
@@ -27,3 +29,9 @@ int os_task_remove(struct os_task *t)
 {
     return pthread_cancel(t->handle);
 }
+
+
+void os_sleep(int ms)
+{
+    sleep(ms);
+}

+ 1 - 1
porting/os/linux/src/os_uart.c

@@ -18,7 +18,7 @@ enum {
 static int set_baudrate(struct termios * toptions, void *args)
 {
     uint32_t baudrate = *(uint32_t *)args;
-    printf("h4_set_baudrate %u\n", baudrate);
+    // printf("h4_set_baudrate %u\n", baudrate);
 
     speed_t brate = baudrate; // let you override switch below if needed
     switch(baudrate) {

+ 2 - 2
src/h4_inner.h

@@ -7,9 +7,9 @@
 extern "C" {
 #endif
 
-extern int _hci_transport_h4_recv(uint8_t *buf, uint16_t size);
-
+extern int _hci_transport_h4_pack(uint8_t *buf, uint16_t size);
 
+extern int _receiver_init(void);
 
 #ifdef __cplusplus
 }

+ 5 - 6
src/hci_transport_h4.c

@@ -6,13 +6,11 @@
 
 static void (*g_package_cb)(int type, uint8_t *buf, size_t size);
 
-static struct rt_ringbuffer g_ringbuffer;
-static uint8_t g_ringbuffer_pool[512];
-
-int rt_hci_transport_h4_init(struct rt_hci_transport_h4_config *config)
+void rt_hci_transport_h4_init(struct rt_hci_transport_h4_config *config)
 {
     g_package_cb = config->package_callback;
-    rt_ringbuffer_init(&g_ringbuffer, g_ringbuffer_pool, ARRAY_SIZE(g_ringbuffer_pool));
+
+    return 0;
 }
 
 int rt_hci_transport_h4_send(int type, uint8_t *buf, size_t size)
@@ -41,7 +39,7 @@ static struct hci_pkg_format g_pkg_fmt[] = {
 
 static uint8_t recv_buffer[512];
 static uint16_t recv_index;
-int _hci_transport_h4_recv(uint8_t *buf, uint16_t buf_len)
+int _hci_transport_h4_pack(uint8_t *buf, uint16_t buf_len)
 {
     assert(buf);
     assert(buf_len > 0);
@@ -69,6 +67,7 @@ int _hci_transport_h4_recv(uint8_t *buf, uint16_t buf_len)
         if (recv_hci_size < expect_hci_size)
             return 0;
         
+        //TODO 目前无法处理一个包内含有两条消息的情况。
         g_package_cb(recv_buffer[0], recv_buffer+1, expect_hci_size);
 
         /* Reset receive buffer, copy data from end pointer to start pointer. */

+ 33 - 0
src/receiver.c

@@ -0,0 +1,33 @@
+#include "os_port.h"
+#include "h4_inner.h"
+#include "hci_transport_h4.h"
+#include <stdio.h>
+
+static struct os_task   recv_task;
+static os_stack_t recv_stack[1024] __attribute__ ((aligned (4))) ;
+
+
+static void _receiver_task(void)
+{
+    uint8_t buf[30];
+    int size;
+    int err;
+    while (1) {
+        size = os_uart_recv(buf, ARRAY_SIZE(buf));
+        if ((err = _hci_transport_h4_pack(buf, size))) {
+            printf("Pack h4 package fail: err(%d)\n", err);
+        }
+        // os_sleep(1);
+    }
+}
+
+int _receiver_init(void)
+{
+    int err;
+    err = os_task_create(&recv_task, "recv", _receiver_task, NULL, 10, 0, recv_stack, ARRAY_SIZE(recv_stack));
+    if (err)
+        return -1;
+    
+    return 0;
+}
+

+ 28 - 2
tests/test_hci_transport_h4.c

@@ -1,4 +1,5 @@
 #include "hci_transport_h4.h"
+#include "../src/h4_inner.h"
 #include "os_port.h"
 #include <stdio.h>
 #include <string.h>
@@ -11,11 +12,25 @@
 
 static struct os_sem sync_sem;
 
+static struct os_uart_config uart_config = {
+    .device_name = "/dev/ttyACM0",
+    .parity      = OS_UART_PARITY_NONE,
+    .stopbit     = OS_UART_STOPBIT_1_BIT,
+    .databit     = OS_UART_DATABIT_8_BIT,
+    .baudrate    = 1000000,
+    .flowcontrol = true,
+};
+
 static int init_suite(void)
 {
     if (os_sem_init(&sync_sem, 0))
         return -1;
     
+    os_uart_init(&uart_config);
+
+    if (_receiver_init())
+        return -1;
+
     return 0;
 }
 
@@ -48,14 +63,25 @@ static void test_hci_transport_h4(void)
 
     int n = rt_hci_transport_h4_send(HCI_TRANSPORT_H4_COMMAND, command1, ARRAY_SIZE(command1));
     CU_ASSERT_EQUAL(n, ARRAY_SIZE(command1));
+    /* Real hardware test. */
+    int err = os_sem_take(&sync_sem, 1000);
+    CU_ASSERT_EQUAL(err, 0);
 
     /* For mock test */
     uint8_t recv_buf[] = {0x04, 0x0E, 0x04, 0x01, 0x03, 0x0C, 0x00};
-    int err = _hci_transport_h4_recv(recv_buf, ARRAY_SIZE(recv_buf));
+    err = _hci_transport_h4_pack(recv_buf, ARRAY_SIZE(recv_buf));
     CU_ASSERT_EQUAL(err, 0);
-
     err = os_sem_take(&sync_sem, 1000);
     CU_ASSERT_EQUAL(err, 0);
+
+    //测试 _hci_transport_h4_recv 接口分两段接收一个包。
+    for (int i = 1; i < ARRAY_SIZE(recv_buf); i+=3) {
+        err = _hci_transport_h4_pack(recv_buf, i);
+        CU_ASSERT_EQUAL(err, 0);
+        err = _hci_transport_h4_pack(recv_buf+i, ARRAY_SIZE(recv_buf)-i);
+        err = os_sem_take(&sync_sem, 1000);
+        CU_ASSERT_EQUAL(err, 0);
+    }
 }
 
 int test_hci_transport_h4_init(void)