process rcmd via queue

This commit is contained in:
cyberman54 2021-01-01 15:25:56 +01:00
parent 2d2a8abd79
commit 61c7e4c12f
7 changed files with 90 additions and 22 deletions

View File

@ -364,7 +364,7 @@ Hereafter described is the default *plain* format, which uses MSB bit numbering.
# Remote control
The device listenes for remote control commands on LoRaWAN Port 2. Multiple commands per downlink are possible by concatenating them.
The device listenes for remote control commands on LoRaWAN Port 2. Multiple commands per downlink are possible by concatenating them, but must not exceed a maximum of 10 bytes per downlink.
Note: all settings are stored in NVRAM and will be reloaded when device starts.

View File

@ -15,6 +15,11 @@
#include "timesync.h"
#include "blescan.h"
// maximum number of elements in rcommand interpreter queue
#define RCMD_QUEUE_SIZE 5
extern TaskHandle_t rcmdTask;
// table of remote commands and assigned functions
typedef struct {
const uint8_t opcode;
@ -23,9 +28,16 @@ typedef struct {
const bool store;
} cmd_t;
extern bool rcmd_busy;
// Struct for remote command processing queue
typedef struct {
uint8_t cmd[10];
uint8_t cmdLen;
} RcmdBuffer_t;
void rcommand(const uint8_t cmd[], const uint8_t cmdlength);
void do_reset(bool warmstart);
void IRAM_ATTR rcommand(const uint8_t *cmd, const size_t cmdlength);
void rcmd_queuereset(void);
uint32_t rcmd_queuewaiting(void);
void rcmd_deinit(void);
esp_err_t rcmd_init(void);
#endif

View File

@ -34,6 +34,8 @@ void doHousekeeping() {
ESP_LOGD(TAG, "MACprocessor %d bytes left | Taskstate = %d",
uxTaskGetStackHighWaterMark(macProcessTask),
eTaskGetState(macProcessTask));
ESP_LOGD(TAG, "Rcommand interpreter %d bytes left | Taskstate = %d",
uxTaskGetStackHighWaterMark(rcmdTask), eTaskGetState(rcmdTask));
#if (HAS_LORA)
ESP_LOGD(TAG, "LMiCtask %d bytes left | Taskstate = %d",
uxTaskGetStackHighWaterMark(lmicTask), eTaskGetState(lmicTask));

View File

@ -38,7 +38,8 @@ timesync_proc 1 3 processes realtime time sync requests
irqhandler 1 2 cyclic tasks (i.e. displayrefresh) triggered by timers
gpsloop 1 1 reads data from GPS via serial or i2c
lorasendtask 1 1 feeds data from lora sendqueue to lmcic
macprocess 1 1 analyzes sniffed MACs
macprocess 1 1 MAC analyzer loop
rmcd_process 1 1 Remote command interpreter loop
IDLE 1 0 ESP32 arduino scheduler -> runs wifi channel rotator
Low priority numbers denote low priority tasks.
@ -291,6 +292,10 @@ void setup() {
ESP_LOGI(TAG, "Starting MAC processor...");
macQueueInit();
// start rcommand processing task
ESP_LOGI(TAG, "Starting rcommand interpreter...");
rcmd_init();
// start BLE scan callback if BLE function is enabled in NVRAM configuration
// or remove bluetooth stack from RAM, if option bluetooth is not compiled
#if (BLECOUNTER)

View File

@ -5,8 +5,8 @@
// Local logging tag
static const char TAG[] = __FILE__;
// global variable indicating if rcommand() is executing
bool rcmd_busy = false;
QueueHandle_t RcmdQueue;
TaskHandle_t rcmdTask;
// set of functions that can be triggered by remote commands
void set_reset(uint8_t val[]) {
@ -396,14 +396,13 @@ static const uint8_t cmdtablesize =
sizeof(table) / sizeof(table[0]); // number of commands in command table
// check and execute remote command
void rcommand(const uint8_t cmd[], const uint8_t cmdlength) {
void rcmd_execute(const uint8_t cmd[], const uint8_t cmdlength) {
if (cmdlength == 0)
return;
uint8_t foundcmd[cmdlength], cursor = 0;
bool storeflag = false;
rcmd_busy = true;
while (cursor < cmdlength) {
@ -436,6 +435,64 @@ void rcommand(const uint8_t cmd[], const uint8_t cmdlength) {
if (storeflag)
saveConfig();
rcmd_busy = false;
} // rcmd_execute()
// remote command processing task
void rcmd_process(void *pvParameters) {
_ASSERT((uint32_t)pvParameters == 1); // FreeRTOS check
RcmdBuffer_t RcmdBuffer;
while (1) {
// fetch next or wait for incoming rcommand from queue
if (xQueueReceive(RcmdQueue, &RcmdBuffer, portMAX_DELAY) != pdTRUE) {
ESP_LOGE(TAG, "Premature return from xQueueReceive() with no data!");
continue;
}
rcmd_execute(RcmdBuffer.cmd, RcmdBuffer.cmdLen);
}
delay(2); // yield to CPU
} // rcmd_process()
// enqueue remote command
void IRAM_ATTR rcommand(const uint8_t *cmd, const size_t cmdlength) {
RcmdBuffer_t rcmd = {0};
rcmd.cmdLen = cmdlength;
memcpy(rcmd.cmd, cmd, cmdlength);
if (xQueueSendToBack(RcmdQueue, (void *)&rcmd, (TickType_t)0) != pdTRUE)
ESP_LOGW(TAG, "Remote command queue is full");
} // rcommand()
void rcmd_queuereset(void) { xQueueReset(RcmdQueue); }
uint32_t rcmd_queuewaiting(void) { return uxQueueMessagesWaiting(RcmdQueue); }
void rcmd_deinit(void) {
rcmd_queuereset();
vTaskDelete(rcmdTask);
}
esp_err_t rcmd_init(void) {
_ASSERT(RCMD_QUEUE_SIZE > 0);
RcmdQueue = xQueueCreate(RCMD_QUEUE_SIZE, sizeof(RcmdBuffer_t));
if (RcmdQueue == 0) {
ESP_LOGE(TAG, "Could not create rcommand send queue. Aborting.");
return ESP_FAIL;
}
ESP_LOGI(TAG, "Rcommand send queue created, size %d Bytes", RCMD_QUEUE_SIZE);
xTaskCreatePinnedToCore(rcmd_process, // task function
"rcmdloop", // name of task
3072, // stack size of task
(void *)1, // parameter of the task
1, // priority of the task
&rcmdTask, // task handle
1); // CPU core
return ESP_OK;
} // rcmd_init()

View File

@ -143,15 +143,7 @@ void enter_deepsleep(const uint64_t wakeup_sec, gpio_num_t wakeup_gpio) {
spi_deinit();
#endif
// wait until rcommands are all done
for (i = 10; i > 0; i--) {
if (rcmd_busy)
vTaskDelay(pdMS_TO_TICKS(1000));
else
break;
}
// save LMIC state to RTC RAM
// save LMIC state to RTC RAM
#if (HAS_LORA)
SaveLMICToRTC(wakeup_sec);
#endif // (HAS_LORA)

View File

@ -12,8 +12,7 @@ void SendPayload(uint8_t port) {
ESP_LOGD(TAG, "sending Payload for Port %d", port);
MessageBuffer_t
SendBuffer; // contains MessageSize, MessagePort, Message[]
MessageBuffer_t SendBuffer; // contains MessageSize, MessagePort, Message[]
SendBuffer.MessageSize = payload.getSize();
@ -190,6 +189,7 @@ void sendData() {
} // sendData()
void flushQueues(void) {
rcmd_queuereset();
#if (HAS_LORA)
lora_queuereset();
#endif
@ -202,7 +202,7 @@ void flushQueues(void) {
}
bool allQueuesEmtpy(void) {
uint32_t rc = 0;
uint32_t rc = rcmd_queuewaiting();
#if (HAS_LORA)
rc += lora_queuewaiting();
#endif