Merge pull request #699 from cyberman54/development

Development
This commit is contained in:
Verkehrsrot 2021-01-03 00:17:36 +01:00 committed by GitHub
commit b9584a2fdf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 104 additions and 32 deletions

View File

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

View File

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

View File

@ -277,12 +277,11 @@ void start_BLEscan(void) {
// Register callback function for capturing bluetooth packets // Register callback function for capturing bluetooth packets
register_ble_callback(false); register_ble_callback(false);
ESP_LOGI(TAG, "Bluetooth scanner started"); ESP_LOGI(TAG, "Bluetooth scanner started");
#endif // BLECOUNTER
} else { } else {
ESP_LOGE(TAG, "Bluetooth controller start failed. Resetting device"); ESP_LOGE(TAG, "Bluetooth controller start failed. Resetting device");
do_reset(true); do_reset(true);
} }
#endif // BLECOUNTER
} // start_BLEscan } // start_BLEscan
void stop_BLEscan(void) { void stop_BLEscan(void) {

View File

@ -14,7 +14,7 @@ extern boolean isSDS011Active;
#endif #endif
void setCyclicIRQ() { void setCyclicIRQ() {
xTaskNotifyFromISR(irqHandlerTask, CYCLIC_IRQ, eSetBits, NULL); xTaskNotify(irqHandlerTask, CYCLIC_IRQ, eSetBits);
} }
// do all housekeeping // do all housekeeping
@ -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));

View File

@ -19,7 +19,7 @@ RTC_DATA_ATTR lmic_t RTC_LMIC;
#endif #endif
#endif #endif
QueueHandle_t LoraSendQueue; static QueueHandle_t LoraSendQueue;
TaskHandle_t lmicTask = NULL, lorasendTask = NULL; TaskHandle_t lmicTask = NULL, lorasendTask = NULL;
class MyHalConfig_t : public Arduino_LMIC::HalConfiguration_t { class MyHalConfig_t : public Arduino_LMIC::HalConfiguration_t {

View File

@ -6,7 +6,7 @@
// Local logging tag // Local logging tag
static const char TAG[] = __FILE__; static const char TAG[] = __FILE__;
QueueHandle_t MacQueue; static QueueHandle_t MacQueue;
TaskHandle_t macProcessTask; TaskHandle_t macProcessTask;
static uint32_t salt = renew_salt(); static uint32_t salt = renew_salt();

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 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.
@ -60,8 +61,10 @@ irqHandlerTask (Core 1), see irqhandler.cpp
fired by hardware fired by hardware
DisplayIRQ -> esp32 timer 0 DisplayIRQ -> esp32 timer 0
ButtonIRQ -> external gpio CLOCKIRQ -> esp32 timer 1 or external GPIO (RTC_INT or GPS_INT)
PMUIRQ -> PMU chip gpio MatrixDisplayIRQ-> esp32 timer 3
ButtonIRQ -> external GPIO
PMUIRQ -> PMU chip GPIO
fired by software (Ticker.h) fired by software (Ticker.h)
TIMESYNC_IRQ -> setTimeSyncIRQ() TIMESYNC_IRQ -> setTimeSyncIRQ()
@ -291,6 +294,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)

View File

@ -4,7 +4,7 @@
static const char TAG[] = __FILE__; static const char TAG[] = __FILE__;
QueueHandle_t MQTTSendQueue; static QueueHandle_t MQTTSendQueue;
TaskHandle_t mqttTask; TaskHandle_t mqttTask;
Ticker mqttTimer; Ticker mqttTimer;
@ -12,6 +12,7 @@ WiFiClient netClient;
MQTTClient mqttClient; MQTTClient mqttClient;
void mqtt_deinit(void) { void mqtt_deinit(void) {
mqttClient.unsubscribe(MQTT_INTOPIC);
mqttClient.onMessageAdvanced(NULL); mqttClient.onMessageAdvanced(NULL);
mqttClient.disconnect(); mqttClient.disconnect();
vTaskDelete(mqttTask); vTaskDelete(mqttTask);
@ -22,6 +23,7 @@ esp_err_t mqtt_init(void) {
// setup network connection and MQTT client // setup network connection and MQTT client
ETH.begin(); ETH.begin();
mqttClient.begin(MQTT_SERVER, MQTT_PORT, netClient); mqttClient.begin(MQTT_SERVER, MQTT_PORT, netClient);
mqttClient.setKeepAlive(MQTT_KEEPALIVE);
mqttClient.onMessageAdvanced(mqtt_callback); mqttClient.onMessageAdvanced(mqtt_callback);
_ASSERT(SEND_QUEUE_SIZE > 0); _ASSERT(SEND_QUEUE_SIZE > 0);

View File

@ -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 static 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,65 @@ 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 * sizeof(RcmdBuffer_t));
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(); 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)

View File

@ -4,7 +4,7 @@
Ticker sendTimer; Ticker sendTimer;
void setSendIRQ() { void setSendIRQ() {
xTaskNotifyFromISR(irqHandlerTask, SENDCYCLE_IRQ, eSetBits, NULL); xTaskNotify(irqHandlerTask, SENDCYCLE_IRQ, eSetBits);
} }
// put data to send in RTos Queues used for transmit over channels Lora and SPI // put data to send in RTos Queues used for transmit over channels Lora and SPI
@ -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

View File

@ -43,7 +43,7 @@ static const char TAG[] = __FILE__;
DMA_ATTR uint8_t txbuf[BUFFER_SIZE]; DMA_ATTR uint8_t txbuf[BUFFER_SIZE];
DMA_ATTR uint8_t rxbuf[BUFFER_SIZE]; DMA_ATTR uint8_t rxbuf[BUFFER_SIZE];
QueueHandle_t SPISendQueue; static QueueHandle_t SPISendQueue;
TaskHandle_t spiTask; TaskHandle_t spiTask;