merged job queue with message queue
This commit is contained in:
+10
-1
@@ -5,6 +5,7 @@
|
||||
#ifndef GEX_SCHED_QUEUE_H
|
||||
#define GEX_SCHED_QUEUE_H
|
||||
|
||||
#include "platform.h"
|
||||
#include <TinyFrame.h>
|
||||
|
||||
typedef struct sched_que_item Job;
|
||||
@@ -32,7 +33,15 @@ 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];
|
||||
uint8_t data[MSG_QUE_SLOT_SIZE];
|
||||
};
|
||||
|
||||
struct rx_sched_combined_que_item {
|
||||
bool is_job;
|
||||
union {
|
||||
struct rx_que_item msg;
|
||||
struct sched_que_item job;
|
||||
};
|
||||
};
|
||||
|
||||
#endif //GEX_SCHED_QUEUE_H
|
||||
|
||||
+77
-8
@@ -2,12 +2,56 @@
|
||||
// Created by MightyPork on 2017/12/22.
|
||||
//
|
||||
|
||||
#include <utils/hexdump.h>
|
||||
#include "platform.h"
|
||||
#include "comm/messages.h"
|
||||
#include "task_msg.h"
|
||||
|
||||
volatile uint32_t msgQueHighWaterMark = 0;
|
||||
|
||||
static void que_safe_post(struct rx_sched_combined_que_item *slot)
|
||||
{
|
||||
uint32_t count = 0;
|
||||
assert_param(slot != NULL);
|
||||
|
||||
if (inIRQ()) {
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
assert_param(pdPASS == xQueueSendFromISR(queMsgJobHandle, slot, &xHigherPriorityTaskWoken));
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
|
||||
#if USE_STACK_MONITOR
|
||||
count = (uint32_t) uxQueueMessagesWaitingFromISR(queMsgJobHandle);
|
||||
#endif
|
||||
} else {
|
||||
assert_param(pdPASS == xQueueSend(queMsgJobHandle, slot, MSG_QUE_POST_TIMEOUT));
|
||||
|
||||
#if USE_STACK_MONITOR
|
||||
count = (uint32_t) uxQueueMessagesWaiting(queMsgJobHandle);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if USE_STACK_MONITOR
|
||||
msgQueHighWaterMark = MAX(msgQueHighWaterMark, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a function for later execution in the jobs thread
|
||||
*
|
||||
* @param callback - the callback function
|
||||
*/
|
||||
void scheduleJob(Job *job)
|
||||
{
|
||||
assert_param(job->cb != NULL);
|
||||
|
||||
struct rx_sched_combined_que_item slot = {
|
||||
.is_job = true,
|
||||
.job = *job, // copy content of the struct
|
||||
};
|
||||
|
||||
que_safe_post(&slot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process data received from TinyFrame.
|
||||
* The queue holds received messages or parts of messages,
|
||||
@@ -17,22 +61,47 @@ volatile uint32_t msgQueHighWaterMark = 0;
|
||||
* TF functions (send, respond) can be called immediately without the need for an
|
||||
* intermediate queued job.
|
||||
*/
|
||||
void TaskMessaging(const void * argument)
|
||||
void TaskMsgJob(const void *argument)
|
||||
{
|
||||
dbg("> Message queue task started!");
|
||||
dbg("> Job+Msg queue task started!");
|
||||
|
||||
struct rx_que_item slot;
|
||||
struct rx_sched_combined_que_item slot;
|
||||
while (1) {
|
||||
xQueueReceive(queRxDataHandle, &slot, osWaitForever);
|
||||
assert_param(slot.len>0 && slot.len<=64); // check the len is within bounds
|
||||
xQueueReceive(queMsgJobHandle, &slot, osWaitForever);
|
||||
|
||||
// We need thr scratch buffer for many unit command handlers
|
||||
TF_Accept(comm, slot.data, slot.len);
|
||||
if (slot.is_job) {
|
||||
assert_param(slot.job.cb != NULL);
|
||||
slot.job.cb(&slot.job);
|
||||
}
|
||||
else {
|
||||
assert_param(slot.msg.len > 0 && slot.msg.len <= MSG_QUE_SLOT_SIZE); // check the len is within bounds
|
||||
TF_Accept(comm, slot.msg.data, slot.msg.len);
|
||||
}
|
||||
|
||||
#if USE_STACK_MONITOR
|
||||
uint32_t count;
|
||||
count = (uint32_t) uxQueueMessagesWaiting(queRxDataHandle); // this seems to return N+1, hence we don't add the +1 for the one just removed.
|
||||
count = (uint32_t) uxQueueMessagesWaiting(queMsgJobHandle); // this seems to return N+1, hence we don't add the +1 for the one just removed.
|
||||
msgQueHighWaterMark = MAX(msgQueHighWaterMark, count);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void rxQuePostMsg(uint8_t *buf, uint32_t len)
|
||||
{
|
||||
assert_param(buf != NULL);
|
||||
assert_param(len != 0);
|
||||
|
||||
static struct rx_sched_combined_que_item slot;
|
||||
|
||||
do {
|
||||
// Post the data chunk on the RX queue to be handled asynchronously.
|
||||
slot.is_job = false;
|
||||
slot.msg.len = len > MSG_QUE_SLOT_SIZE ? MSG_QUE_SLOT_SIZE : len;
|
||||
memcpy(slot.msg.data, buf, slot.msg.len);
|
||||
|
||||
que_safe_post(&slot);
|
||||
|
||||
len -= slot.msg.len;
|
||||
buf += slot.msg.len;
|
||||
} while (len > 0);
|
||||
}
|
||||
|
||||
+13
-3
@@ -5,8 +5,18 @@
|
||||
#ifndef GEX_F072_TASK_MSG_H
|
||||
#define GEX_F072_TASK_MSG_H
|
||||
|
||||
extern osMessageQId queRxDataHandle;
|
||||
extern osThreadId tskMsgHandle;
|
||||
void TaskMessaging(const void * argument);
|
||||
#include "platform.h"
|
||||
#include "sched_queue.h"
|
||||
|
||||
extern osMessageQId queMsgJobHandle;
|
||||
extern osThreadId tskMsgJobHandle;
|
||||
void TaskMsgJob(const void *argument);
|
||||
void scheduleJob(Job *job);
|
||||
|
||||
#if USE_STACK_MONITOR
|
||||
extern volatile uint32_t msgQueHighWaterMark;
|
||||
#endif
|
||||
|
||||
void rxQuePostMsg(uint8_t *buf, uint32_t len);
|
||||
|
||||
#endif //GEX_F072_TASK_MSG_H
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
//
|
||||
// Created by MightyPork on 2017/11/21.
|
||||
//
|
||||
|
||||
#include "platform.h"
|
||||
#include "task_sched.h"
|
||||
|
||||
extern osMessageQId queSchedHandle;
|
||||
|
||||
volatile uint32_t jobQueHighWaterMark = 0;
|
||||
|
||||
/**
|
||||
* Schedule a function for later execution in the jobs thread
|
||||
*
|
||||
* @param callback - the callback function
|
||||
*/
|
||||
void scheduleJob(Job *job)
|
||||
{
|
||||
QueueHandle_t que = queSchedHandle;
|
||||
|
||||
assert_param(que != NULL);
|
||||
assert_param(job->cb != NULL);
|
||||
|
||||
uint32_t count;
|
||||
if (inIRQ()) {
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
assert_param(pdPASS == xQueueSendFromISR(que, job, &xHigherPriorityTaskWoken));
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
|
||||
#if USE_STACK_MONITOR
|
||||
count = (uint32_t) uxQueueMessagesWaitingFromISR(que);
|
||||
#endif
|
||||
} else {
|
||||
assert_param(pdPASS == xQueueSend(que, job, 100));
|
||||
|
||||
#if USE_STACK_MONITOR
|
||||
count = (uint32_t) uxQueueMessagesWaiting(que);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if USE_STACK_MONITOR
|
||||
jobQueHighWaterMark = MAX(jobQueHighWaterMark, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* job queue handler (for use in interrupts to do longer stuff on a thread)
|
||||
*
|
||||
* @param argument
|
||||
*/
|
||||
void TaskJobQueue(const void *argument)
|
||||
{
|
||||
dbg("> High priority queue task started!");
|
||||
|
||||
struct sched_que_item job;
|
||||
while (1) {
|
||||
xQueueReceive(queSchedHandle, &job, osWaitForever);
|
||||
|
||||
assert_param(job.cb != NULL);
|
||||
job.cb(&job);
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
//
|
||||
// Created by MightyPork on 2017/11/21.
|
||||
//
|
||||
|
||||
#ifndef GEX_TASK_SCHED_H
|
||||
#define GEX_TASK_SCHED_H
|
||||
|
||||
#include "platform.h"
|
||||
#include "sched_queue.h"
|
||||
|
||||
#if USE_STACK_MONITOR
|
||||
extern volatile uint32_t jobQueHighWaterMark;
|
||||
extern volatile uint32_t msgQueHighWaterMark;
|
||||
#endif
|
||||
|
||||
extern osThreadId tskJobRunnerHandle;
|
||||
void TaskJobQueue(const void *argument);
|
||||
|
||||
void scheduleJob(Job *job);
|
||||
|
||||
#endif //GEX_TASK_SCHED_H
|
||||
Reference in New Issue
Block a user