From 5ca7ab1db0b5d9646eb60d7d5f218c93921504a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Fri, 22 Dec 2017 23:10:14 +0100 Subject: [PATCH] implement a message processing queue that will hopefully aleviate the pain in working with tinyframe. this should make it possible to almost entirely get rid of async jobs for simple replies --- USB/usbd_cdc_if.c | 8 ++++++- cortex_handlers.c | 3 +++ freertos.c | 50 +++++++++++++++++++++++++++++++++--------- tasks/sched_queue.h | 10 +++++++++ tasks/task_main.c | 2 +- tasks/task_msg.c | 20 +++++++++++++++++ tasks/task_msg.h | 12 ++++++++++ units/test/unit_test.c | 6 ++++- 8 files changed, 98 insertions(+), 13 deletions(-) create mode 100644 tasks/task_msg.c create mode 100644 tasks/task_msg.h diff --git a/USB/usbd_cdc_if.c b/USB/usbd_cdc_if.c index 52d4ce1..736aa62 100644 --- a/USB/usbd_cdc_if.c +++ b/USB/usbd_cdc_if.c @@ -48,6 +48,7 @@ /* Includes ------------------------------------------------------------------*/ #include "platform.h" +#include "tasks/task_msg.h" #include "usbd_cdc_if.h" /* USER CODE BEGIN INCLUDE */ #include "task_main.h" @@ -265,6 +266,7 @@ static int8_t CDC_Control_FS (uint8_t cmd, uint8_t* pbuf, uint16_t length) */ static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len) { + static struct rx_que_item rxitem; /* USER CODE BEGIN 6 */ // this does nothing?! // the buffer was already assigned in the init function and we got it as argument here?! @@ -272,7 +274,11 @@ static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len) assert_param(*Len <= APP_RX_DATA_SIZE); USBD_CDC_ReceivePacket(&hUsbDeviceFS); - TF_Accept(comm, Buf, *Len); + + // Post the data chunk on the RX queue to be handled asynchronously. + rxitem.len = *Len; + memcpy(rxitem.data, Buf, rxitem.len); + assert_param(pdPASS == xQueueSend(queRxDataHandle, &rxitem, 100)); return (USBD_OK); /* USER CODE END 6 */ diff --git a/cortex_handlers.c b/cortex_handlers.c index a0d36e7..752dcb4 100644 --- a/cortex_handlers.c +++ b/cortex_handlers.c @@ -4,6 +4,7 @@ #include #include "platform/debug_uart.h" #include "platform/status_led.h" +#include "utils/stacksmon.h" /* External variables --------------------------------------------------------*/ @@ -29,6 +30,8 @@ void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName) called if a stack overflow is detected. */ PRINTF(tFAULT" RTOS stack overflow! tsk: %s\r\n", (char *) pcTaskName); StatusLed_On(STATUS_FAULT); + + stackmon_dump(); while (1); } diff --git a/freertos.c b/freertos.c index f4fc74b..d042d19 100644 --- a/freertos.c +++ b/freertos.c @@ -57,23 +57,43 @@ /* USER CODE END Includes */ /* Variables -----------------------------------------------------------------*/ + +#define STACK_MAIN 160 +#define STACK_MSG 170 +#define STACK_LP 128 +#define STACK_HP 128 + osThreadId tskMainHandle; -uint32_t mainTaskBuffer[ 160 ]; +uint32_t mainTaskBuffer[ STACK_MAIN ]; osStaticThreadDef_t mainTaskControlBlock; + +osThreadId tskMsgHandle; +uint32_t msgTaskBuffer[ STACK_MSG ]; +osStaticThreadDef_t msgTaskControlBlock; + osThreadId tskSchedLPHandle; -uint32_t schedLowBuffer[ 128 ]; +uint32_t schedLowBuffer[ STACK_LP ]; osStaticThreadDef_t schedLowControlBlock; + osThreadId tskSchedHPHandle; -uint32_t schedHighBuffer[ 128 ]; +uint32_t schedHighBuffer[ STACK_HP ]; osStaticThreadDef_t schedHighControlBlock; + osMessageQId queSchedLPHandle; -uint8_t myQueue01Buffer[ 5 * sizeof( struct sched_que_item ) ]; +uint8_t myQueue01Buffer[ LP_SCHED_CAPACITY * sizeof( struct sched_que_item ) ]; osStaticMessageQDef_t myQueue01ControlBlock; + osMessageQId queSchedHPHandle; -uint8_t myQueue02Buffer[ 5 * sizeof( struct sched_que_item ) ]; +uint8_t myQueue02Buffer[ HP_SCHED_CAPACITY * sizeof( struct sched_que_item ) ]; osStaticMessageQDef_t myQueue02ControlBlock; + +osMessageQId queRxDataHandle; +uint8_t myQueue03Buffer[ RX_QUE_CAPACITY * sizeof( struct rx_que_item ) ]; +osStaticMessageQDef_t myQueue03ControlBlock; + osMutexId mutTinyFrameTxHandle; osStaticMutexDef_t myMutex01ControlBlock; + osSemaphoreId semVcomTxReadyHandle; osStaticSemaphoreDef_t myBinarySem01ControlBlock; @@ -85,6 +105,7 @@ osStaticSemaphoreDef_t myBinarySem01ControlBlock; void TaskMain(void const * argument); extern void TaskSchedLP(void const * argument); extern void TaskSchedHP(void const * argument); +extern void TaskMessaging(void const * argument); void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ @@ -127,6 +148,7 @@ void MX_FREERTOS_Init(void) { stackmon_register("Main", mainTaskBuffer, sizeof(mainTaskBuffer)); stackmon_register("Job Queue Low", schedLowBuffer, sizeof(schedLowBuffer)); stackmon_register("Job Queue High", schedHighBuffer, sizeof(schedHighBuffer)); + stackmon_register("Messaging", msgTaskBuffer, sizeof(msgTaskBuffer)); /* USER CODE END Init */ /* Create the mutex(es) */ @@ -154,30 +176,38 @@ void MX_FREERTOS_Init(void) { /* Create the thread(s) */ /* definition and creation of tskMain */ - osThreadStaticDef(tskMain, TaskMain, osPriorityHigh, 0, 160, mainTaskBuffer, &mainTaskControlBlock); + osThreadStaticDef(tskMain, TaskMain, osPriorityHigh, 0, STACK_MAIN, mainTaskBuffer, &mainTaskControlBlock); tskMainHandle = osThreadCreate(osThread(tskMain), NULL); /* definition and creation of tskSchedLP */ - osThreadStaticDef(tskSchedLP, TaskSchedLP, osPriorityLow, 0, 128, schedLowBuffer, &schedLowControlBlock); + osThreadStaticDef(tskSchedLP, TaskSchedLP, osPriorityLow, 0, STACK_LP, schedLowBuffer, &schedLowControlBlock); tskSchedLPHandle = osThreadCreate(osThread(tskSchedLP), NULL); /* definition and creation of tskSchedHP */ - osThreadStaticDef(tskSchedHP, TaskSchedHP, osPriorityAboveNormal, 0, 128, schedHighBuffer, &schedHighControlBlock); + osThreadStaticDef(tskSchedHP, TaskSchedHP, osPriorityAboveNormal, 0, STACK_HP, schedHighBuffer, &schedHighControlBlock); tskSchedHPHandle = osThreadCreate(osThread(tskSchedHP), NULL); + /* definition and creation of TaskMessaging */ + osThreadStaticDef(tskMsg, TaskMessaging, osPriorityNormal, 0, STACK_MSG, msgTaskBuffer, &msgTaskControlBlock); + tskMsgHandle = osThreadCreate(osThread(tskMsg), NULL); + /* USER CODE BEGIN RTOS_THREADS */ /* add threads, ... */ /* USER CODE END RTOS_THREADS */ /* Create the queue(s) */ /* definition and creation of queSchedLP */ - osMessageQStaticDef(queSchedLP, 5, struct sched_que_item, myQueue01Buffer, &myQueue01ControlBlock); + osMessageQStaticDef(queSchedLP, LP_SCHED_CAPACITY, struct sched_que_item, myQueue01Buffer, &myQueue01ControlBlock); queSchedLPHandle = osMessageCreate(osMessageQ(queSchedLP), NULL); /* definition and creation of queSchedHP */ - osMessageQStaticDef(queSchedHP, 5, struct sched_que_item, myQueue02Buffer, &myQueue02ControlBlock); + osMessageQStaticDef(queSchedHP, HP_SCHED_CAPACITY, struct sched_que_item, myQueue02Buffer, &myQueue02ControlBlock); queSchedHPHandle = osMessageCreate(osMessageQ(queSchedHP), NULL); + /* definition and creation of queRxData */ + osMessageQStaticDef(queRxData, RX_QUE_CAPACITY, struct rx_que_item, myQueue03Buffer, &myQueue03ControlBlock); + queRxDataHandle = osMessageCreate(osMessageQ(queRxData), NULL); + /* USER CODE BEGIN RTOS_QUEUES */ /* add queues, ... */ /* USER CODE END RTOS_QUEUES */ diff --git a/tasks/sched_queue.h b/tasks/sched_queue.h index 4239ede..dcae182 100644 --- a/tasks/sched_queue.h +++ b/tasks/sched_queue.h @@ -29,4 +29,14 @@ struct sched_que_item { }; }; +// This que is used to stash frames received from TinyFrame for later evaluation on the application thread +struct rx_que_item { + uint32_t len; + uint8_t data[64]; +}; + +#define LP_SCHED_CAPACITY 5 +#define HP_SCHED_CAPACITY 5 +#define RX_QUE_CAPACITY 8 + #endif //GEX_SCHED_QUEUE_H diff --git a/tasks/task_main.c b/tasks/task_main.c index 60b9e1a..3c148da 100644 --- a/tasks/task_main.c +++ b/tasks/task_main.c @@ -48,7 +48,7 @@ void TaskMain(void const * argument) // Periodically check stacks for overrun stackmon_check_canaries(); // Periodically dump all stacks - for checking levels before critical (to reduce size if not needed) -// if ((cnt%50)==0) stackmon_dump(); + if ((cnt%75)==0) stackmon_dump(); continue; } diff --git a/tasks/task_msg.c b/tasks/task_msg.c new file mode 100644 index 0000000..8c2db78 --- /dev/null +++ b/tasks/task_msg.c @@ -0,0 +1,20 @@ +// +// Created by MightyPork on 2017/12/22. +// + +#include +#include "platform.h" +#include "task_msg.h" +#include "sched_queue.h" + +void TaskMessaging(const void * argument) +{ + dbg("> Message queue task started!"); + + struct rx_que_item slot; + while (1) { + xQueueReceive(queRxDataHandle, &slot, osWaitForever); + assert_param(slot.len>0 && slot.len<=64); // check the len is within bounds + TF_Accept(comm, slot.data, slot.len); + } +} \ No newline at end of file diff --git a/tasks/task_msg.h b/tasks/task_msg.h new file mode 100644 index 0000000..ef3ffa6 --- /dev/null +++ b/tasks/task_msg.h @@ -0,0 +1,12 @@ +// +// Created by MightyPork on 2017/12/22. +// + +#ifndef GEX_F072_TASK_MSG_H +#define GEX_F072_TASK_MSG_H + +extern osMessageQId queRxDataHandle; +extern osThreadId tskMsgHandle; +void TaskMessaging(const void * argument); + +#endif //GEX_F072_TASK_MSG_H diff --git a/units/test/unit_test.c b/units/test/unit_test.c index 66b9cfe..aa1b6ce 100644 --- a/units/test/unit_test.c +++ b/units/test/unit_test.c @@ -196,7 +196,11 @@ static bool Tst_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, Paylo .buf = cpy, .len = len, }; - dbg("Rx len %d, %.*s\r\n", (int)len, (int)len, cpy); + + PRINTF("Rx len %d: ", (int)len); + PUTSN((char *) cpy, len); + PUTS("\r\n"); + scheduleJob(&job, TSK_SCHED_HIGH); break;