Skip to content

Commit

Permalink
Merge pull request #5 from 1998-felix/stm32_mqtt
Browse files Browse the repository at this point in the history
NOISSUE-Add stm32 mqtt capability
  • Loading branch information
drasko authored Sep 15, 2023
2 parents 9a7ba11 + 6907601 commit 3f6c8f9
Show file tree
Hide file tree
Showing 9 changed files with 386 additions and 0 deletions.
2 changes: 2 additions & 0 deletions targets/stm32/mqtt/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.pio
.vscode
17 changes: 17 additions & 0 deletions targets/stm32/mqtt/Makefile
Original file line number Diff line number Diff line change
@@ -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
24 changes: 24 additions & 0 deletions targets/stm32/mqtt/README.md
Original file line number Diff line number Diff line change
@@ -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
```

26 changes: 26 additions & 0 deletions targets/stm32/mqtt/include/MQTTClientapp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef MQTT_CLIENT_APP_H_
#define MQTT_CLIENT_APP_H_

#include <string.h>

#include "MQTTClient.h"
#include "MQTTInterface.h"
#include "cmsis_os.h"
#include "config.h"

#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
36 changes: 36 additions & 0 deletions targets/stm32/mqtt/include/MQTTInterface.h
Original file line number Diff line number Diff line change
@@ -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
11 changes: 11 additions & 0 deletions targets/stm32/mqtt/include/config.h
Original file line number Diff line number Diff line change
@@ -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
28 changes: 28 additions & 0 deletions targets/stm32/mqtt/platformio.ini
Original file line number Diff line number Diff line change
@@ -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
108 changes: 108 additions & 0 deletions targets/stm32/mqtt/src/MQTTClientapp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#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/";
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(MESSAGE_DELAY);
}
else
{
MQTTYield(&mqttClient, MESSAGE_DELAY);
osDelay(OS_DELAY);
}
}
}

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(MESSAGE_DELAY);
}
}

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, MESSAGE_DELAY, 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 = KEEP_ALIVE_INT;
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);
}
134 changes: 134 additions & 0 deletions targets/stm32/mqtt/src/MQTTInterface.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#include <string.h>

#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;
}

0 comments on commit 3f6c8f9

Please sign in to comment.