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

sipo
Ondřej Hruška 6 years ago
parent fa5261b65a
commit 5ca7ab1db0
  1. 8
      USB/usbd_cdc_if.c
  2. 3
      cortex_handlers.c
  3. 50
      freertos.c
  4. 10
      tasks/sched_queue.h
  5. 2
      tasks/task_main.c
  6. 20
      tasks/task_msg.c
  7. 12
      tasks/task_msg.h
  8. 6
      units/test/unit_test.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 */

@ -4,6 +4,7 @@
#include <TinyFrame.h>
#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);
}

@ -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 */

@ -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

@ -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;
}

@ -0,0 +1,20 @@
//
// Created by MightyPork on 2017/12/22.
//
#include <comm/messages.h>
#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);
}
}

@ -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

@ -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;

Loading…
Cancel
Save