Updated to new startup & esp event handling.

Modules can now subscribe to ESP system events via the new
NODEMCU_ESP_EVENT() macro. See nodemcu_esp_event.h for details.
This commit is contained in:
Johny Mattsson 2016-09-27 18:42:08 +10:00
parent 6349fc8622
commit 33eb1bc790
4 changed files with 159 additions and 21 deletions

View File

@ -0,0 +1,75 @@
/*
* Copyright 2016 Dius Computing Pty Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the copyright holders nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @author Johny Mattsson <jmattsson@dius.com.au>
*/
#ifndef _NODEMCU_ESP_EVENT_H_
#define _NODEMCU_ESP_EVENT_H_
#include "esp_event.h"
#include "module.h"
/**
* Similarly to how a NodeMCU module is registered, a module can register
* to receive copies of ESP system events (e.g. WiFi stack notifications).
* These notifications will come in the form of callbacks within the main
* Lua thread context, making it possible to directly relay information
* through to Lua callbacks/globals.
*
* Registering is as simple as including this header file, then adding a
* line for each event the module wishes to be notified about, e.g.:
*
* NODEMCU_ESP_EVENT(SYSTEM_EVENT_STA_GOT_IP, do_stuff_when_got_ip);
* NODEMCU_ESP_EVENT(SYSTEM_EVENT_STA_DISCONNECTED, do_stuff_when_discon);
*
* These registrations are done at link-time, and consume no additional RAM.
* The event IDs are located in esp_event.h in the IDF.
*/
// Event callback prototype
typedef void (*nodemcu_esp_event_cb) (const system_event_t *event);
// System event queue getter (matching esp_event_loop.h's declaration)
QueueHandle_t esp_event_loop_get_queue (void);
// Internal definitions
typedef struct {
system_event_id_t event_id;
nodemcu_esp_event_cb callback;
} nodemcu_esp_event_reg_t;
extern nodemcu_esp_event_reg_t *esp_event_cb_table;
#define NODEMCU_ESP_EVENT(evcode, func) \
static const LOCK_IN_SECTION(".esp_event_cb_table") \
nodemcu_esp_event_reg_t MODULE_PASTE_(func,evcode) = { evcode, func };
#endif

View File

@ -9,6 +9,9 @@ SECTIONS {
lua_rotable = ABSOLUTE(.); lua_rotable = ABSOLUTE(.);
KEEP(*(.lua_rotable)) KEEP(*(.lua_rotable))
LONG(0) LONG(0) /* Null-terminate the array */ LONG(0) LONG(0) /* Null-terminate the array */
esp_event_cb_table = ABSOLUTE(.);
KEEP(*(.esp_event_cb_table))
LONG(0) LONG(0) /* Null-terminate the array */
} }
} }
INSERT AFTER .flash.text INSERT AFTER .flash.text

View File

@ -15,19 +15,79 @@
#include "vfs.h" #include "vfs.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#include "esp_system.h" #include "esp_system.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include "flash_api.h" #include "flash_api.h"
#include "driver/console.h" #include "driver/console.h"
#include "task/task.h" #include "task/task.h"
#include "sections.h" #include "sections.h"
#include "nodemcu_esp_event.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "freertos/queue.h"
#define SIG_LUA 0 #define SIG_LUA 0
#define SIG_UARTINPUT 1 #define SIG_UARTINPUT 1
static task_handle_t esp_event_task;
static QueueHandle_t esp_event_queue;
// We provide our own esp_event_send which hooks into the NodeMCU task
// task framework, and ensures all events are handled in the same context
// as the LVM, making life as easy as possible for us.
esp_err_t esp_event_send (system_event_t *event)
{
if (!event)
return ESP_ERR_INVALID_ARG;
if (!esp_event_task || !esp_event_queue)
return ESP_ERR_INVALID_STATE; // too early!
portBASE_TYPE ret = xQueueSendToBack (esp_event_queue, event, 0);
if (ret != pdPASS)
{
NODE_ERR("failed to queue esp event %d", event->event_id);
return ESP_FAIL;
}
// If the task_post() fails, it only means the event gets delayed, hence
// we claim OK regardless.
task_post_medium (esp_event_task, 0);
return ESP_OK;
}
QueueHandle_t esp_event_loop_get_queue (void)
{
return esp_event_queue;
}
static void handle_esp_event (task_param_t param, task_prio_t prio)
{
(void)param;
(void)prio;
system_event_t evt;
while (xQueueReceive (esp_event_queue, &evt, 0) == pdPASS)
{
esp_err_t ret = esp_event_process_default (&evt);
if (ret != ESP_OK)
NODE_ERR("default event handler failed for %d", evt.event_id);
nodemcu_esp_event_reg_t *evregs;
for (evregs = esp_event_cb_table; evregs->callback; ++evregs)
{
if (evregs->event_id == evt.event_id)
evregs->callback (&evt);
}
}
}
// +================== New task interface ==================+ // +================== New task interface ==================+
static void start_lua(task_param_t param, task_prio_t prio) { static void start_lua(task_param_t param, task_prio_t prio) {
(void)param; (void)param;
@ -93,29 +153,29 @@ void nodemcu_init(void)
} }
static void nodemcu_main (void *param) void app_main (void)
{ {
(void)param; esp_event_queue =
xQueueCreate (CONFIG_SYSTEM_EVENT_QUEUE_SIZE, sizeof (system_event_t));
esp_event_task = task_get_id (handle_esp_event);
input_task = task_get_id (handle_input);
ConsoleSetup_t cfg;
cfg.bit_rate = CONFIG_CONSOLE_BIT_RATE;
cfg.data_bits = CONSOLE_NUM_BITS_8;
cfg.parity = CONSOLE_PARITY_NONE;
cfg.stop_bits = CONSOLE_STOP_BITS_1;
cfg.auto_baud = CONFIG_CONSOLE_BIT_RATE_AUTO;
console_init (&cfg, input_task);
nodemcu_init (); nodemcu_init ();
nvs_flash_init (6, 3);
system_init ();
tcpip_adapter_init ();
task_pump_messages (); task_pump_messages ();
__builtin_unreachable (); __builtin_unreachable ();
} }
void app_main (void)
{
input_task = task_get_id (handle_input);
ConsoleSetup_t cfg;
cfg.bit_rate = CONFIG_CONSOLE_BIT_RATE;
cfg.data_bits = CONSOLE_NUM_BITS_8;
cfg.parity = CONSOLE_PARITY_NONE;
cfg.stop_bits = CONSOLE_STOP_BITS_1;
cfg.auto_baud = CONFIG_CONSOLE_BIT_RATE_AUTO;
console_init (&cfg, input_task);
xTaskCreate (
nodemcu_main, "nodemcu", 3072, 0, tskIDLE_PRIORITY +1, NULL);
}

@ -1 +1 @@
Subproject commit 4480ab6c8ce70778df4948e587e712540de237eb Subproject commit e3ffcd22d533f30550c53023c2c680a1f234f014