From ab2d35274032b2a60d9975a32de63b071c6da625 Mon Sep 17 00:00:00 2001 From: 1998-felix Date: Thu, 24 Aug 2023 12:38:42 +0300 Subject: [PATCH 1/2] Add stm32 capability Signed-off-by: 1998-felix --- targets/stm32/mqtt/.gitignore | 2 + targets/stm32/mqtt/Makefile | 17 ++++ targets/stm32/mqtt/README.md | 24 +++++ targets/stm32/mqtt/include/MQTTClientapp.h | 27 +++++ targets/stm32/mqtt/include/MQTTInterface.h | 36 +++++++ targets/stm32/mqtt/include/config.h | 11 ++ targets/stm32/mqtt/platformio.ini | 28 ++++++ targets/stm32/mqtt/src/MQTTClientapp.c | 104 +++++++++++++++++++ targets/stm32/mqtt/src/MQTTInterface.c | 111 +++++++++++++++++++++ 9 files changed, 360 insertions(+) create mode 100644 targets/stm32/mqtt/.gitignore create mode 100644 targets/stm32/mqtt/Makefile create mode 100644 targets/stm32/mqtt/README.md create mode 100644 targets/stm32/mqtt/include/MQTTClientapp.h create mode 100644 targets/stm32/mqtt/include/MQTTInterface.h create mode 100644 targets/stm32/mqtt/include/config.h create mode 100644 targets/stm32/mqtt/platformio.ini create mode 100644 targets/stm32/mqtt/src/MQTTClientapp.c create mode 100644 targets/stm32/mqtt/src/MQTTInterface.c diff --git a/targets/stm32/mqtt/.gitignore b/targets/stm32/mqtt/.gitignore new file mode 100644 index 0000000..b9f3806 --- /dev/null +++ b/targets/stm32/mqtt/.gitignore @@ -0,0 +1,2 @@ +.pio +.vscode diff --git a/targets/stm32/mqtt/Makefile b/targets/stm32/mqtt/Makefile new file mode 100644 index 0000000..a911c7c --- /dev/null +++ b/targets/stm32/mqtt/Makefile @@ -0,0 +1,17 @@ +all: + platformio -f run + +upload: + platformio -f run --target upload + +clean: + platformio -f run --target clean + +program: + platformio -f run --target program + +uploadfs: + platformio -f run --target uploadfs + +update: + platformio -f update \ No newline at end of file diff --git a/targets/stm32/mqtt/README.md b/targets/stm32/mqtt/README.md new file mode 100644 index 0000000..b507e69 --- /dev/null +++ b/targets/stm32/mqtt/README.md @@ -0,0 +1,24 @@ +# MQTTS- stm32 target +## Requirements +1. Mainflux broker details including: hostname, ThingID, Thing Credentials and Channel ID +2. [PlatformIO](https://platformio.org/) +3. [dfu-util](https://dfu-util.sourceforge.net/) +4. [STM32CubeIDE](https://www.st.com/en/development-tools/stm32cubeide.html) + +## Configure +1. Use the STM32CUbeIDE to generate the specific files for your target. Please ensure to add the [Lwip]() and [Paho embedded c]()libraries as third party libraries. Then copy the files to this section +Edit the platform.ini file for the specific target. +2. Edit the [config file](include/config.h) with your broker and network details. + +## Build +The project can be built by utilising the make file within the target directory + +```bash +make +``` +## Flash +Platform io generate a build directory with the fimware.bin within it. Use the make command to flash to board +```bash +make upload +``` + diff --git a/targets/stm32/mqtt/include/MQTTClientapp.h b/targets/stm32/mqtt/include/MQTTClientapp.h new file mode 100644 index 0000000..71945c9 --- /dev/null +++ b/targets/stm32/mqtt/include/MQTTClientapp.h @@ -0,0 +1,27 @@ + +#ifndef MQTT_CLIENT_APP_H_ +#define MQTT_CLIENT_APP_H_ + +#include "MQTTClient.h" +#include "MQTTInterface.h" +#include "cmsis_os.h" +#include "config.h" + +#include + +#define MQTT_PORT 1883 +#define MQTT_BUFSIZE 1024 + +Network net; +MQTTClient mqttClient; + +uint8_t sndBuffer[MQTT_BUFSIZE]; +uint8_t rcvBuffer[MQTT_BUFSIZE]; +uint8_t msgBuffer[MQTT_BUFSIZE]; + +void mqttClientSubTask(void const *argument); +void mqttClientPubTask(void const *argument); +int mqttConnectBroker(void); +void mqttMessageArrived(MessageData* msg); + +#endif diff --git a/targets/stm32/mqtt/include/MQTTInterface.h b/targets/stm32/mqtt/include/MQTTInterface.h new file mode 100644 index 0000000..887117e --- /dev/null +++ b/targets/stm32/mqtt/include/MQTTInterface.h @@ -0,0 +1,36 @@ +#ifndef _MQTTInterface_H +#define _MQTTInterface_H + +typedef struct Timer Timer; + +struct Timer +{ + unsigned long systick_period; + unsigned long end_time; +}; + +typedef struct Network Network; + +struct Network +{ + struct netconn *conn; + struct netbuf *buf; + int offset; + int (*mqttread)(Network *, unsigned char *, int, int); + int (*mqttwrite)(Network *, unsigned char *, int, int); + void (*disconnect)(Network *); +}; + +void initTimer(Timer *); +char timerIsExpired(Timer *); +void timerCountDownMS(Timer *, unsigned int); +void timerCountDown(Timer *, unsigned int); +int timerLeftMS(Timer *); + +int netRead(Network *, unsigned char *, int, int); +int netWrite(Network *, unsigned char *, int, int); +void netDisconnect(Network *); +void newNetwork(Network *); +int connectNetwork(Network *, char *, int); + +#endif diff --git a/targets/stm32/mqtt/include/config.h b/targets/stm32/mqtt/include/config.h new file mode 100644 index 0000000..3437fce --- /dev/null +++ b/targets/stm32/mqtt/include/config.h @@ -0,0 +1,11 @@ +#ifndef CONFIG_H +#define CONFIG_H + +const char *mfThingId = " "; +const char *mfThingPass = " "; +const char *mfChannelId = " "; +char mfTopic[150]; + +const char *server = " "; + +#endif diff --git a/targets/stm32/mqtt/platformio.ini b/targets/stm32/mqtt/platformio.ini new file mode 100644 index 0000000..a4aa44d --- /dev/null +++ b/targets/stm32/mqtt/platformio.ini @@ -0,0 +1,28 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nucleo_f429zi] +platform = ststm32 +board = nucleo_f429zi +framework = stm32cube +monitor_speed=115200 +lib_deps= + https://git.savannah.nongnu.org/git/lwip.git + https://github.com/eclipse/paho.mqtt.embedded-c.git + +upload_protocol = dfu +build_flags = + -D ENABLE_USB_SERIAL + -D USBCON + -D USBD_VID=0x0483 + -D USBD_PID=0x5740 + -D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC + + -D HAL_PCD_MODULE_ENABLED \ No newline at end of file diff --git a/targets/stm32/mqtt/src/MQTTClientapp.c b/targets/stm32/mqtt/src/MQTTClientapp.c new file mode 100644 index 0000000..a1e84b8 --- /dev/null +++ b/targets/stm32/mqtt/src/MQTTClientapp.c @@ -0,0 +1,104 @@ +#include "main.h" +#include "MQTTClientapp.h" + +void createMainfluxChannel(void) +{ + const char *_preId = "channels/"; + const char *_postId = "/messages"; + strcpy(mfTopic, _preId); + strcat(mfTopic, mfChannelId); + strcat(mfTopic, _postId); +} + +void mqttClientSubTask(void const *argument) +{ + while (1) + { + if (!mqttClient.isconnected) + { + MQTTDisconnect(&mqttClient); + mqttConnectBroker(); + osDelay(1000); + } + else + { + MQTTYield(&mqttClient, 1000); + osDelay(100); + } + } +} + +void mqttClientPubTask(void const *argument) +{ + const char *str = "{'message':'hello'}"; + MQTTMessage message; + + while (1) + { + if (mqttClient.isconnected) + { + message.payload = (void *)str; + message.payloadlen = strlen(str); + + MQTTPublish(&mqttClient, mfTopic, &message); + } + osDelay(1000); + } +} + +int mqttConnectBroker() +{ + int ret; + + net_clear(); + ret = net_init(&net); + if (ret != MQTT_SUCCESS) + { + printf("net_init failed.\n"); + return -1; + } + + ret = net_connect(&net, server, MQTT_PORT); + if (ret != MQTT_SUCCESS) + { + printf("net_connect failed.\n"); + return -1; + } + + MQTTClientInit(&mqttClient, &net, 1000, sndBuffer, sizeof(sndBuffer), rcvBuffer, sizeof(rcvBuffer)); + createMainfluxChannel(); + + MQTTPacket_connectData data = MQTTPacket_connectData_initializer; + data.willFlag = 0; + data.MQTTVersion = 3; + data.clientID.cstring = "STM32F4"; + data.username.cstring = mfThingId; + data.password.cstring = mfThingPass; + data.keepAliveInterval = 60; + data.cleansession = 1; + + ret = MQTTConnect(&mqttClient, &data); + if (ret != MQTT_SUCCESS) + { + printf("MQTTConnect failed.\n"); + return ret; + } + + ret = MQTTSubscribe(&mqttClient, mfChannelId, QOS0, mqttMessageArrived); + if (ret != MQTT_SUCCESS) + { + printf("MQTT Subscribe failed.\n"); + return ret; + } + + return MQTT_SUCCESS; +} + +void mqttMessageArrived(MessageData *msg) +{ + MQTTMessage *message = msg->message; + memset(msgBuffer, 0, sizeof(msgBuffer)); + memcpy(msgBuffer, message->payload, message->payloadlen); + + printf("MQTT MSG[%d]:%s\n", (int)message->payloadlen, msgBuffer); +} \ No newline at end of file diff --git a/targets/stm32/mqtt/src/MQTTInterface.c b/targets/stm32/mqtt/src/MQTTInterface.c new file mode 100644 index 0000000..2ff714a --- /dev/null +++ b/targets/stm32/mqtt/src/MQTTInterface.c @@ -0,0 +1,111 @@ +#include + +#include "lwip.h" +#include "lwip/api.h" +#include "lwip/sockets.h" +#include "stm32f4xx_hal.h" +#include "MQTTInterface.h" + + +#define MQTT_PORT 1883 + +uint32_t MilliTimer; + +char timerIsExpired(Timer *timer) { + long left = timer->end_time - MilliTimer; + return (left < 0); +} + +void timerCountDownMS(Timer *timer, unsigned int timeout) { + timer->end_time = MilliTimer + timeout; +} + +void timerCountDown(Timer *timer, unsigned int timeout) { + timer->end_time = MilliTimer + (timeout * 1000); +} + +int timerLeftMS(Timer *timer) { + long left = timer->end_time - MilliTimer; + return (left < 0) ? 0 : left; +} + +void initTimer(Timer *timer) { + timer->end_time = 0; +} + +void newNetwork(Network *n) { + n->conn = NULL; + n->buf = NULL; + n->offset = 0; + n->mqttread = netRead; + n->mqttwrite = netWrite; + n->disconnect = netDisconnect; +} + +int connectNetwork(Network *n, char *ip, int port) { + err_t err; + + n->conn = netconn_new(NETCONN_TCP); + if (n->conn != NULL) { + err = netconn_connect(n->conn, &ip, port); + + if (err != ERR_OK) { + netconn_delete(n->conn); + return -1; + } + } + + return 0; +} + +int netRead(Network *n, unsigned char *buffer, int len, int timeout_ms) { + int rc; + struct netbuf *inbuf; + int offset = 0; + int bytes = 0; + + while(bytes < len) { + if(n->buf != NULL) { + inbuf = n->buf; + offset = n->offset; + rc = ERR_OK; + } else { + rc = netconn_recv(n->conn, &inbuf); + offset = 0; + } + + if(rc != ERR_OK) { + if(rc != ERR_TIMEOUT) { + bytes = -1; + } + break; + } else { + int nblen = netbuf_len(inbuf) - offset; + if((bytes+nblen) > len) { + netbuf_copy_partial(inbuf, buffer+bytes, len-bytes,offset); + n->buf = inbuf; + n->offset = offset + len - bytes; + bytes = len; + } else { + netbuf_copy_partial(inbuf, buffer+bytes, nblen, offset); + bytes += nblen; + netbuf_delete(inbuf); + n->buf = NULL; + n->offset = 0; + } + } + } + return bytes; +} + +int netWrite(Network *n, unsigned char *buffer, int len, int timeout_ms) { + int rc = netconn_write(n->conn, buffer, len, NETCONN_NOCOPY); + if(rc != ERR_OK) return -1; + return len; +} + +void netDisconnect(Network *n) { + netconn_close(n->conn); + netconn_delete(n->conn); + n->conn = NULL; +} \ No newline at end of file From 69076011ae63b7292744c99dc9a6f103d588cd13 Mon Sep 17 00:00:00 2001 From: 1998-felix Date: Mon, 28 Aug 2023 07:31:03 +0300 Subject: [PATCH 2/2] Format code Signed-off-by: 1998-felix --- targets/stm32/mqtt/include/MQTTClientapp.h | 19 +++--- targets/stm32/mqtt/src/MQTTClientapp.c | 16 +++-- targets/stm32/mqtt/src/MQTTInterface.c | 75 ++++++++++++++-------- 3 files changed, 68 insertions(+), 42 deletions(-) diff --git a/targets/stm32/mqtt/include/MQTTClientapp.h b/targets/stm32/mqtt/include/MQTTClientapp.h index 71945c9..5d71636 100644 --- a/targets/stm32/mqtt/include/MQTTClientapp.h +++ b/targets/stm32/mqtt/include/MQTTClientapp.h @@ -1,27 +1,26 @@ - #ifndef MQTT_CLIENT_APP_H_ #define MQTT_CLIENT_APP_H_ +#include + #include "MQTTClient.h" #include "MQTTInterface.h" #include "cmsis_os.h" #include "config.h" -#include - -#define MQTT_PORT 1883 -#define MQTT_BUFSIZE 1024 +#define MQTT_PORT 1883 +#define MQTT_BUFSIZE 1024 -Network net; -MQTTClient mqttClient; +Network net; +MQTTClient mqttClient; -uint8_t sndBuffer[MQTT_BUFSIZE]; +uint8_t sndBuffer[MQTT_BUFSIZE]; uint8_t rcvBuffer[MQTT_BUFSIZE]; uint8_t msgBuffer[MQTT_BUFSIZE]; void mqttClientSubTask(void const *argument); void mqttClientPubTask(void const *argument); -int mqttConnectBroker(void); -void mqttMessageArrived(MessageData* msg); +int mqttConnectBroker(void); +void mqttMessageArrived(MessageData *msg); #endif diff --git a/targets/stm32/mqtt/src/MQTTClientapp.c b/targets/stm32/mqtt/src/MQTTClientapp.c index a1e84b8..616562e 100644 --- a/targets/stm32/mqtt/src/MQTTClientapp.c +++ b/targets/stm32/mqtt/src/MQTTClientapp.c @@ -1,6 +1,10 @@ #include "main.h" #include "MQTTClientapp.h" +#define MESSAGE_DELAY 1000 +#define OS_DELAY 100 +#define KEEP_ALIVE_INT 60 + void createMainfluxChannel(void) { const char *_preId = "channels/"; @@ -18,12 +22,12 @@ void mqttClientSubTask(void const *argument) { MQTTDisconnect(&mqttClient); mqttConnectBroker(); - osDelay(1000); + osDelay(MESSAGE_DELAY); } else { - MQTTYield(&mqttClient, 1000); - osDelay(100); + MQTTYield(&mqttClient, MESSAGE_DELAY); + osDelay(OS_DELAY); } } } @@ -42,7 +46,7 @@ void mqttClientPubTask(void const *argument) MQTTPublish(&mqttClient, mfTopic, &message); } - osDelay(1000); + osDelay(MESSAGE_DELAY); } } @@ -65,7 +69,7 @@ int mqttConnectBroker() return -1; } - MQTTClientInit(&mqttClient, &net, 1000, sndBuffer, sizeof(sndBuffer), rcvBuffer, sizeof(rcvBuffer)); + MQTTClientInit(&mqttClient, &net, MESSAGE_DELAY, sndBuffer, sizeof(sndBuffer), rcvBuffer, sizeof(rcvBuffer)); createMainfluxChannel(); MQTTPacket_connectData data = MQTTPacket_connectData_initializer; @@ -74,7 +78,7 @@ int mqttConnectBroker() data.clientID.cstring = "STM32F4"; data.username.cstring = mfThingId; data.password.cstring = mfThingPass; - data.keepAliveInterval = 60; + data.keepAliveInterval = KEEP_ALIVE_INT; data.cleansession = 1; ret = MQTTConnect(&mqttClient, &data); diff --git a/targets/stm32/mqtt/src/MQTTInterface.c b/targets/stm32/mqtt/src/MQTTInterface.c index 2ff714a..d1f2613 100644 --- a/targets/stm32/mqtt/src/MQTTInterface.c +++ b/targets/stm32/mqtt/src/MQTTInterface.c @@ -6,34 +6,39 @@ #include "stm32f4xx_hal.h" #include "MQTTInterface.h" - -#define MQTT_PORT 1883 +#define MQTT_PORT 1883 uint32_t MilliTimer; -char timerIsExpired(Timer *timer) { +char timerIsExpired(Timer *timer) +{ long left = timer->end_time - MilliTimer; return (left < 0); } -void timerCountDownMS(Timer *timer, unsigned int timeout) { +void timerCountDownMS(Timer *timer, unsigned int timeout) +{ timer->end_time = MilliTimer + timeout; } -void timerCountDown(Timer *timer, unsigned int timeout) { +void timerCountDown(Timer *timer, unsigned int timeout) +{ timer->end_time = MilliTimer + (timeout * 1000); } -int timerLeftMS(Timer *timer) { +int timerLeftMS(Timer *timer) +{ long left = timer->end_time - MilliTimer; return (left < 0) ? 0 : left; } -void initTimer(Timer *timer) { +void initTimer(Timer *timer) +{ timer->end_time = 0; } -void newNetwork(Network *n) { +void newNetwork(Network *n) +{ n->conn = NULL; n->buf = NULL; n->offset = 0; @@ -42,14 +47,17 @@ void newNetwork(Network *n) { n->disconnect = netDisconnect; } -int connectNetwork(Network *n, char *ip, int port) { +int connectNetwork(Network *n, char *ip, int port) +{ err_t err; n->conn = netconn_new(NETCONN_TCP); - if (n->conn != NULL) { + if (n->conn != NULL) + { err = netconn_connect(n->conn, &ip, port); - if (err != ERR_OK) { + if (err != ERR_OK) + { netconn_delete(n->conn); return -1; } @@ -58,36 +66,48 @@ int connectNetwork(Network *n, char *ip, int port) { return 0; } -int netRead(Network *n, unsigned char *buffer, int len, int timeout_ms) { +int netRead(Network *n, unsigned char *buffer, int len, int timeout_ms) +{ int rc; struct netbuf *inbuf; int offset = 0; int bytes = 0; - while(bytes < len) { - if(n->buf != NULL) { + while (bytes < len) + { + if (n->buf != NULL) + { inbuf = n->buf; offset = n->offset; rc = ERR_OK; - } else { + } + else + { rc = netconn_recv(n->conn, &inbuf); offset = 0; } - if(rc != ERR_OK) { - if(rc != ERR_TIMEOUT) { + if (rc != ERR_OK) + { + if (rc != ERR_TIMEOUT) + { bytes = -1; } break; - } else { + } + else + { int nblen = netbuf_len(inbuf) - offset; - if((bytes+nblen) > len) { - netbuf_copy_partial(inbuf, buffer+bytes, len-bytes,offset); + if ((bytes + nblen) > len) + { + netbuf_copy_partial(inbuf, buffer + bytes, len - bytes, offset); n->buf = inbuf; n->offset = offset + len - bytes; bytes = len; - } else { - netbuf_copy_partial(inbuf, buffer+bytes, nblen, offset); + } + else + { + netbuf_copy_partial(inbuf, buffer + bytes, nblen, offset); bytes += nblen; netbuf_delete(inbuf); n->buf = NULL; @@ -98,14 +118,17 @@ int netRead(Network *n, unsigned char *buffer, int len, int timeout_ms) { return bytes; } -int netWrite(Network *n, unsigned char *buffer, int len, int timeout_ms) { +int netWrite(Network *n, unsigned char *buffer, int len, int timeout_ms) +{ int rc = netconn_write(n->conn, buffer, len, NETCONN_NOCOPY); - if(rc != ERR_OK) return -1; + if (rc != ERR_OK) + return -1; return len; } -void netDisconnect(Network *n) { +void netDisconnect(Network *n) +{ netconn_close(n->conn); - netconn_delete(n->conn); + netconn_delete(n->conn); n->conn = NULL; } \ No newline at end of file