merged job queue with message queue

This commit is contained in:
2018-01-12 09:30:02 +01:00
parent c58787c95d
commit 7816d75563
12 changed files with 123 additions and 148 deletions
+10 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
-62
View File
@@ -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);
}
}
-21
View File
@@ -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