process rcmd via queue
This commit is contained in:
parent
2d2a8abd79
commit
61c7e4c12f
@ -364,7 +364,7 @@ Hereafter described is the default *plain* format, which uses MSB bit numbering.
|
|||||||
|
|
||||||
# Remote control
|
# 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.
|
Note: all settings are stored in NVRAM and will be reloaded when device starts.
|
||||||
|
|
||||||
|
@ -15,6 +15,11 @@
|
|||||||
#include "timesync.h"
|
#include "timesync.h"
|
||||||
#include "blescan.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
|
// table of remote commands and assigned functions
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const uint8_t opcode;
|
const uint8_t opcode;
|
||||||
@ -23,9 +28,16 @@ typedef struct {
|
|||||||
const bool store;
|
const bool store;
|
||||||
} cmd_t;
|
} 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 IRAM_ATTR rcommand(const uint8_t *cmd, const size_t cmdlength);
|
||||||
void do_reset(bool warmstart);
|
void rcmd_queuereset(void);
|
||||||
|
uint32_t rcmd_queuewaiting(void);
|
||||||
|
void rcmd_deinit(void);
|
||||||
|
esp_err_t rcmd_init(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -34,6 +34,8 @@ void doHousekeeping() {
|
|||||||
ESP_LOGD(TAG, "MACprocessor %d bytes left | Taskstate = %d",
|
ESP_LOGD(TAG, "MACprocessor %d bytes left | Taskstate = %d",
|
||||||
uxTaskGetStackHighWaterMark(macProcessTask),
|
uxTaskGetStackHighWaterMark(macProcessTask),
|
||||||
eTaskGetState(macProcessTask));
|
eTaskGetState(macProcessTask));
|
||||||
|
ESP_LOGD(TAG, "Rcommand interpreter %d bytes left | Taskstate = %d",
|
||||||
|
uxTaskGetStackHighWaterMark(rcmdTask), eTaskGetState(rcmdTask));
|
||||||
#if (HAS_LORA)
|
#if (HAS_LORA)
|
||||||
ESP_LOGD(TAG, "LMiCtask %d bytes left | Taskstate = %d",
|
ESP_LOGD(TAG, "LMiCtask %d bytes left | Taskstate = %d",
|
||||||
uxTaskGetStackHighWaterMark(lmicTask), eTaskGetState(lmicTask));
|
uxTaskGetStackHighWaterMark(lmicTask), eTaskGetState(lmicTask));
|
||||||
|
@ -38,7 +38,8 @@ timesync_proc 1 3 processes realtime time sync requests
|
|||||||
irqhandler 1 2 cyclic tasks (i.e. displayrefresh) triggered by timers
|
irqhandler 1 2 cyclic tasks (i.e. displayrefresh) triggered by timers
|
||||||
gpsloop 1 1 reads data from GPS via serial or i2c
|
gpsloop 1 1 reads data from GPS via serial or i2c
|
||||||
lorasendtask 1 1 feeds data from lora sendqueue to lmcic
|
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
|
IDLE 1 0 ESP32 arduino scheduler -> runs wifi channel rotator
|
||||||
|
|
||||||
Low priority numbers denote low priority tasks.
|
Low priority numbers denote low priority tasks.
|
||||||
@ -291,6 +292,10 @@ void setup() {
|
|||||||
ESP_LOGI(TAG, "Starting MAC processor...");
|
ESP_LOGI(TAG, "Starting MAC processor...");
|
||||||
macQueueInit();
|
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
|
// start BLE scan callback if BLE function is enabled in NVRAM configuration
|
||||||
// or remove bluetooth stack from RAM, if option bluetooth is not compiled
|
// or remove bluetooth stack from RAM, if option bluetooth is not compiled
|
||||||
#if (BLECOUNTER)
|
#if (BLECOUNTER)
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
// Local logging tag
|
// Local logging tag
|
||||||
static const char TAG[] = __FILE__;
|
static const char TAG[] = __FILE__;
|
||||||
|
|
||||||
// global variable indicating if rcommand() is executing
|
QueueHandle_t RcmdQueue;
|
||||||
bool rcmd_busy = false;
|
TaskHandle_t rcmdTask;
|
||||||
|
|
||||||
// set of functions that can be triggered by remote commands
|
// set of functions that can be triggered by remote commands
|
||||||
void set_reset(uint8_t val[]) {
|
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
|
sizeof(table) / sizeof(table[0]); // number of commands in command table
|
||||||
|
|
||||||
// check and execute remote command
|
// 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)
|
if (cmdlength == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint8_t foundcmd[cmdlength], cursor = 0;
|
uint8_t foundcmd[cmdlength], cursor = 0;
|
||||||
bool storeflag = false;
|
bool storeflag = false;
|
||||||
rcmd_busy = true;
|
|
||||||
|
|
||||||
while (cursor < cmdlength) {
|
while (cursor < cmdlength) {
|
||||||
|
|
||||||
@ -436,6 +435,64 @@ void rcommand(const uint8_t cmd[], const uint8_t cmdlength) {
|
|||||||
if (storeflag)
|
if (storeflag)
|
||||||
saveConfig();
|
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()
|
} // 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()
|
@ -143,15 +143,7 @@ void enter_deepsleep(const uint64_t wakeup_sec, gpio_num_t wakeup_gpio) {
|
|||||||
spi_deinit();
|
spi_deinit();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// wait until rcommands are all done
|
// save LMIC state to RTC RAM
|
||||||
for (i = 10; i > 0; i--) {
|
|
||||||
if (rcmd_busy)
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// save LMIC state to RTC RAM
|
|
||||||
#if (HAS_LORA)
|
#if (HAS_LORA)
|
||||||
SaveLMICToRTC(wakeup_sec);
|
SaveLMICToRTC(wakeup_sec);
|
||||||
#endif // (HAS_LORA)
|
#endif // (HAS_LORA)
|
||||||
|
@ -12,8 +12,7 @@ void SendPayload(uint8_t port) {
|
|||||||
|
|
||||||
ESP_LOGD(TAG, "sending Payload for Port %d", port);
|
ESP_LOGD(TAG, "sending Payload for Port %d", port);
|
||||||
|
|
||||||
MessageBuffer_t
|
MessageBuffer_t SendBuffer; // contains MessageSize, MessagePort, Message[]
|
||||||
SendBuffer; // contains MessageSize, MessagePort, Message[]
|
|
||||||
|
|
||||||
SendBuffer.MessageSize = payload.getSize();
|
SendBuffer.MessageSize = payload.getSize();
|
||||||
|
|
||||||
@ -190,6 +189,7 @@ void sendData() {
|
|||||||
} // sendData()
|
} // sendData()
|
||||||
|
|
||||||
void flushQueues(void) {
|
void flushQueues(void) {
|
||||||
|
rcmd_queuereset();
|
||||||
#if (HAS_LORA)
|
#if (HAS_LORA)
|
||||||
lora_queuereset();
|
lora_queuereset();
|
||||||
#endif
|
#endif
|
||||||
@ -202,7 +202,7 @@ void flushQueues(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool allQueuesEmtpy(void) {
|
bool allQueuesEmtpy(void) {
|
||||||
uint32_t rc = 0;
|
uint32_t rc = rcmd_queuewaiting();
|
||||||
#if (HAS_LORA)
|
#if (HAS_LORA)
|
||||||
rc += lora_queuewaiting();
|
rc += lora_queuewaiting();
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user