diff --git a/mongoose.h b/mongoose.h index f6e80774..a4f2c285 100644 --- a/mongoose.h +++ b/mongoose.h @@ -3412,8 +3412,9 @@ static inline void mg_dash_ev_handler(struct mg_connection *c, int ev, } } -extern void mongoose_init(void); -extern void mongoose_poll(void); +extern struct mg_mgr g_mgr; +extern void mg_dash_init(struct mg_mgr *); +extern void mg_dash_poll(struct mg_mgr *); // Copyright (c) 2023 Cesanta Software Limited // All rights reserved diff --git a/resources/I-CUBE-Mongoose/Cesanta.I-CUBE-Mongoose.pdsc b/resources/I-CUBE-Mongoose/Cesanta.I-CUBE-Mongoose.pdsc index 8425db95..76847867 100644 --- a/resources/I-CUBE-Mongoose/Cesanta.I-CUBE-Mongoose.pdsc +++ b/resources/I-CUBE-Mongoose/Cesanta.I-CUBE-Mongoose.pdsc @@ -7,7 +7,7 @@ License.txt https://mongoose.ws/contact/ - See https://github.com/cesanta/mongoose/releases/tag/7.21 + See https://github.com/cesanta/mongoose/releases/tag/7.21 See https://github.com/cesanta/mongoose/releases/tag/7.21 See https://github.com/cesanta/mongoose/releases/tag/7.13 @@ -15,20 +15,25 @@ CUBE_RULES_COMPLIANT IMPLEMENTED_WITH_STM32CUBEMX - - - Mongoose - TCP/IP stack + TLS + HTTP + WebSocket + MQTT + Firmware OTA - - + + + + + - - Mongoose - TCP/IP stack + TLS + HTTP + WebSocket + MQTT + Firmware OTA + + Networking Core - - - - - + + + + + + + Web Device Dashboard + + + diff --git a/resources/I-CUBE-Mongoose/Makefile b/resources/I-CUBE-Mongoose/Makefile index e4549b22..b402ec01 100644 --- a/resources/I-CUBE-Mongoose/Makefile +++ b/resources/I-CUBE-Mongoose/Makefile @@ -1,10 +1,15 @@ -VERSION = 7.21.2 +VERSION = 7.21.3 REPO_ROOT = ../.. -FILES = Mongoose App Cesanta.I-CUBE-Mongoose.pdsc License.txt Release_Notes.html +FILES = Cesanta.I-CUBE-Mongoose.pdsc Release_Notes.html mongoose_config.h README.md +GENERATED = License.txt \ + mongoose.h mongoose.c \ + mongoose_dashboard.c dashboard.html.c + # STM32CubeMX/Cesanta.I-CUBE-Mongoose.$(VERSION)_Configs.xml \ + # STM32CubeMX/Cesanta.I-CUBE-Mongoose.$(VERSION)_Modes.xml all: Cesanta.I-CUBE-Mongoose.$(VERSION).pack -Cesanta.I-CUBE-Mongoose.$(VERSION).pack: $(FILES) Mongoose/mongoose.h Mongoose/mongoose.c App/mongoose_app.c App/dashboard.html.c +Cesanta.I-CUBE-Mongoose.$(VERSION).pack: $(FILES) $(GENERATED) zip -r $@ $^ cp $@ Cesanta.I-CUBE-Mongoose.pack @@ -15,17 +20,28 @@ check: Cesanta.I-CUBE-Mongoose.$(VERSION).pack License.txt: cp $(REPO_ROOT)/LICENSE $@ + Mongoose: mkdir -p Mongoose -App/mongoose_app.c: - cp $(REPO_ROOT)/tutorials/device-dashboard/mongoose_app.c $@ -App/dashboard.html.c: + +mongoose_dashboard.c: + cp $(REPO_ROOT)/tutorials/device-dashboard/mongoose_dashboard.c $@ + +dashboard.html.c: make -C $(REPO_ROOT)/tutorials/device-dashboard dashboard.html.c cp $(REPO_ROOT)/tutorials/device-dashboard/dashboard.html.c $@ -Mongoose/mongoose.h: Mongoose + +mongoose.h: Mongoose cp $(REPO_ROOT)/mongoose.h $@ -Mongoose/mongoose.c: Mongoose + +mongoose.c: Mongoose cp $(REPO_ROOT)/mongoose.c $@ +STM32CubeMX/Cesanta.I-CUBE-Mongoose.${VERSION}_Modes.xml: STM32CubeMX/m.xml + sed s,__VERSION__,$(VERSION),g $^ > $@ + +STM32CubeMX/Cesanta.I-CUBE-Mongoose.${VERSION}_Configs.xml: STM32CubeMX/c.xml + sed s,__VERSION__,$(VERSION),g $^ > $@ + clean: - rm -rf *.pack License.txt Mongoose App/*.{html,js,c} + rm -rf *.pack STM32CubeMX/*.$(VERSION)_*.xml $(GENERATED) diff --git a/resources/I-CUBE-Mongoose/README.md b/resources/I-CUBE-Mongoose/README.md new file mode 100644 index 00000000..9cdb9797 --- /dev/null +++ b/resources/I-CUBE-Mongoose/README.md @@ -0,0 +1,121 @@ +# Mongoose CubeMX pack + +This pack provides an easy to use CubeMX integration. + +## Mongoose Networking Core + +This module installs Mongoose Library itself: `mogoose.c`, `mongoose.h` and +`mongoose_config.h`. It is required for any other module to work. Below are +the steps to make it work with you CubeMX application: + +## Configure peripherals + +In CubeMX, configure USART (for debug), RNG (for TLS), ETH. + +## Enable debug logs + +Open `Core/Src/main.c` and add this snippet: + +```c +/* USER CODE BEGIN 0 */ +int _write(int fd, unsigned char *buf, int len) { + HAL_UART_Transmit(&huart3, buf, len, HAL_MAX_DELAY); + return len; +} +/* USER CODE END 0 */ +``` + +## Call Mongoose + +Open `Core/Src/main.c`. Add at the top of the file: + +```c +/* USER CODE BEGIN Includes */ +#include "mongoose.h" +/* USER CODE END Includes */ +``` + +Inside main() function: + +```c +Inside the `main()` function: + +```c +/* USER CODE BEGIN WHILE */ +struct mg_mgr mgr; +mg_mgr_init(&mgr); + +while (1) +{ + mg_mgr_poll(&mgr, 1); +/* USER CODE END WHILE */ +``` + +This starts the TCP/IP stack. In the serial console logs, you should +see something like this: + +```text +0 2 mongoose.c:26153:mg_phy_init PHY ID: 0x07 0xc131 (LAN87x) +6 2 mongoose.c:5834:mg_mgr_init Driver: stm32h, MAC: 2a:37:94:03:d5:74 +d 3 mongoose.c:5841:mg_mgr_init MG_IO_SIZE: 512, TLS: builtin +13 3 mongoose.c:5758:mg_listen 1 0 http://0.0.0.0:80 +19 1 mongoose.c:6260:onstatechange Link down +7d6 3 mongoose.c:28424:mg_tcpip_driv Link is 100M full-duplex +7db 3 mongoose.c:6404:tx_dhcp_discov DHCP discover sent. Our MAC: 2a:37:94:03:d5:74 +831 3 mongoose.c:6382:tx_dhcp_reques DHCP req sent +836 2 mongoose.c:6559:rx_dhcp_client Lease: 3600 sec (3602) +83c 2 mongoose.c:6249:onstatechange READY, IP: 192.168.2.31 +842 2 mongoose.c:6250:onstatechange GW: 192.168.2.1 +847 2 mongoose.c:6253:onstatechange MAC: 2a:37:94:03:d5:74 +``` + +Now, you should be able to ping your device. +However, it runs no network services. + +## Add hello world HTTP server + +Let's add the simplest web server possible. After the `mg_mgr_init()` +call, add one more line to start the HTTP listener: + +```c +mg_mgr_init(&mgr); +mg_http_listen(&mgr, "http://0.0.0.0:80", http_ev_handler, NULL); +``` + +And after the `_write()` override, add this HTTP event handler function: + +```c +static void http_ev_handler(struct mg_connection *c, int ev, void *ev_data) { + if (ev == MG_EV_HTTP_MSG) { + mg_http_reply(c, 200, "", "Hi from Mongoose! Tick %lu\r\n", HAL_GetTick()); + } +} +``` + +Rebuild, reflash your board, open the device's IP address in the browser, +and see the message displayed, something like: + +```text +Hi from Mongoose! Tick 38187 +``` + +## Add full device dashboard + +Remove the hello world server if you added it. Modify your while loop +to look like this: + +```c +/* USER CODE BEGIN WHILE */ +struct mg_mgr mgr; +mg_mgr_init(&mgr); +mg_dash_init(&mgr); + +while (1) +{ + mg_mgr_poll(&mgr, 1); + mg_dash_poll(&mgr); +/* USER CODE END WHILE */ +``` + +Rebuild, reflash your board and enjoy the fully functional device dashboard +that you can tailor to your firmware. diff --git a/resources/I-CUBE-Mongoose/App/mongoose_config.h b/resources/I-CUBE-Mongoose/mongoose_config.h similarity index 100% rename from resources/I-CUBE-Mongoose/App/mongoose_config.h rename to resources/I-CUBE-Mongoose/mongoose_config.h diff --git a/src/dash.h b/src/dash.h index 8871e586..85fdee46 100644 --- a/src/dash.h +++ b/src/dash.h @@ -267,5 +267,6 @@ static inline void mg_dash_ev_handler(struct mg_connection *c, int ev, } } -extern void mongoose_init(void); -extern void mongoose_poll(void); +extern struct mg_mgr g_mgr; +extern void mg_dash_init(struct mg_mgr *); +extern void mg_dash_poll(struct mg_mgr *); diff --git a/tutorials/device-dashboard/Makefile b/tutorials/device-dashboard/Makefile index dcd58798..ff3bc858 100644 --- a/tutorials/device-dashboard/Makefile +++ b/tutorials/device-dashboard/Makefile @@ -2,7 +2,7 @@ PROG ?= example MONGOOSE_DIR ?= ../.. -SOURCES = main.c mongoose_app.c dashboard.html.c $(MONGOOSE_DIR)/mongoose.c +SOURCES = main.c mongoose_dashboard.c dashboard.html.c $(MONGOOSE_DIR)/mongoose.c CFLAGS ?= -W -Wall -Wextra -Werror -Wundef -Wshadow -g3 -O0 PFLAGS = -I$(MONGOOSE_DIR) -DMG_DATA_SIZE=64 -DMG_TLS=MG_TLS_BUILTIN AFLAGS ?= -fsanitize=signed-integer-overflow,address,undefined,alignment @@ -25,7 +25,7 @@ dashboard.html.c: dashboard.html # For development: rebuild and restart if any of the sources change watch: - watchexec -r -w main.c -w mongoose_app.c -w $(MONGOOSE_DIR)/mongoose.h -w web_root -e c,h,html,css,js -- make + watchexec -r -w main.c -w mongoose_dashboard.c -w $(MONGOOSE_DIR)/mongoose.h -w web_root -e c,h,html,css,js -- make clean: rm -rf $(PROG) *.exe *.obj *.dSYM mongoose dashboard.* diff --git a/tutorials/device-dashboard/main.c b/tutorials/device-dashboard/main.c index 5cc27ba0..13db0c87 100644 --- a/tutorials/device-dashboard/main.c +++ b/tutorials/device-dashboard/main.c @@ -1,13 +1,18 @@ // SPDX-FileCopyrightText: 2026 Cesanta Software Limited // SPDX-License-Identifier: GPL-2.0-only or commercial -extern void mongoose_init(void); -extern void mongoose_poll(void); +#include "mongoose.h" int main(void) { - mongoose_init(); + struct mg_mgr mgr; + + mg_mgr_init(&mgr); + mg_dash_init(&mgr); + for (;;) { - mongoose_poll(); + mg_mgr_poll(&mgr, 10); + mg_dash_poll(&mgr); } + return 0; } diff --git a/tutorials/device-dashboard/mongoose_app.c b/tutorials/device-dashboard/mongoose_dashboard.c similarity index 90% rename from tutorials/device-dashboard/mongoose_app.c rename to tutorials/device-dashboard/mongoose_dashboard.c index 308905fc..a715ece4 100644 --- a/tutorials/device-dashboard/mongoose_app.c +++ b/tutorials/device-dashboard/mongoose_dashboard.c @@ -114,22 +114,16 @@ static struct mg_field_set field_sets[] = { {"chart1", fields_chart1, sync_chart1, 0, 0}, {0, 0, 0, 0, 0}, }; -static struct mg_mgr s_mgr; static struct mg_dash s_dashboard = {field_sets}; -void mongoose_init(void) { - mg_mgr_init(&s_mgr); - mg_http_listen(&s_mgr, HTTP_ADDR, mg_dash_ev_handler, &s_dashboard); +void mg_dash_init(struct mg_mgr *mgr) { + mg_http_listen(mgr, HTTP_ADDR, mg_dash_ev_handler, &s_dashboard); } -void mongoose_poll(void) { - mg_mgr_poll(&s_mgr, 1); - - { - // Send metrics change periodically - static uint64_t timer = 0; - if (mg_timer_expired(&timer, 300, mg_now())) { - mg_dash_send_change(&s_mgr, &s_dashboard, "metrics"); - } +void mg_dash_poll(struct mg_mgr *mgr) { + // Send metrics change periodically + static uint64_t timer = 0; + if (mg_timer_expired(&timer, 30000, mg_now())) { + mg_dash_send_change(mgr, &s_dashboard, "metrics"); } }