1. MQTT presentation
This application aims to demonstrate an example of MQTT client over Wi-Fi which connects to an MQTT broker in order to publish telemetry data and receive parameter updates or commands from the cloud.
This application publishes periodically data to an MQTT broker (this example uses EMQX, but it can be changed to a preferred MQTT broker). The application also subscribes to the same topic to be able to monitor the published data.
In this example, the subscribed topic can be used to receive additional 'control' fields. Two actions are predefined:
- Change the LED state on the host board
- Reboot the host
To monitor the data sent and received, to/from the topics, a MQTT client can be installed on a PC, smartphone or tablet. Subscribing to the configured topics, allows the client to be notified every time the device publishes data to this topic.
2. Requirements
2.1. Software and system requirements
The required software is as follows (minimum IDEs version):
- STM32CubeIDE toolchain V1.18.1 [1].
- IAR Embedded Workbench for ARM (EWARM) toolchain V9.30.1
- RealView Microcontroller Development Kit (MDK-ARM) toolchain V5.39
Programmer:
- STM32CubeProgrammer [2] : To flash the board with an already generated binary
HyperTerminal:
- Use the application through the serial link
- Open a HyperTerminal client connected to the host ST-LINK COM port
The serial COM port must be configured as below:
Baudrate | 921600 |
Data | 8b |
Stopbit | 1b |
Parity | None |
Flow control | None |
Rx | LF |
Tx | LF |
Local Echo | Off |
For more details see HyperTerminal setup page.
2.2. Hardware requirements
This example runs on the NUCLEO-U575ZI-Q [3] board combined with the X-NUCLEO-67W61M1 board.
The X-NUCLEO-67W61M1 board is plugged into the NUCLEO-U575ZI-Q board through the Arduino connectors:
- The 5V, 3V3, GND through the CN6
- The SPI (CLK, MOSI, MISO), SPI_CS and USER_BUTTON signals through the CN5
- The BOOT, CHIP_EN, SPI_RDY and UART TX/RX signals through the CN9
3. ST67W6X_MQTT demonstration description
3.1. Project directory
The "ST67W6X_MQTT" demonstration is available by downloading the X-CUBE-ST67W61 Expansion Package.
Refer to Project directory wiki page for project directory information.
3.2. Project description
3.2.1. Topology structure
The application on the host uses the network coprocessor as a Wi-Fi station modem. It connects to a Wi-Fi local access point (hotspot/gateway/etc.) which needs a connection to the internet. Once the connection is established, the Host application connects to an MQTT broker to publish and subscribe to topics.
The host application uses the MEMS sensor board to generate telemetry data to be sent to the MQTT broker. It uses also an SNTP request to get the current time and date, added to the telemetry data.
Additionally, the host application can receive commands from the MQTT broker to change the LED state or to reboot the device.
3.2.2. Project execution
The different steps of the application Initialization are described below:
Description | Function | File |
---|---|---|
Initialize the system (HAL, Clocks, SPI, I2C, UART, RTC, GPIO) | main() | Core/Src/mainc.c |
Create the default FreeRTOS task containing the main application execution | MX_FREERTOS_Init() | Core/Src/app_feertos.c |
Start all configurated tasks | osKernelStart() | cmsis_os2.c |
Run the main_app() enter application function | StartDefaultTask() | Core/Src/app_freertos.c |
Initialize the logging utility to forward all traces on UART peripheral | W6X_Util_Init() | ST67W6X_Network_Driver/Core/w6x_sys.c |
Initialize the application callbacks to receive events from ST67W6X_Network_Driver | W6X_RegisterAppCb() | ST67W6X_Network_Driver/Core/w6x_sys.c |
Initialize the ST67W6X_Network_Driver Power up the Network Coprocessor Display global identification |
W6X_Init() | ST67W6X_Network_Driver/Core/w6x_sys.c |
Initialize the ST67W6X_Network_Driver Wi-Fi module Set the STA mode Enable the DHCP Client Configure the Country Code Set the Hostname |
W6X_WiFi_Init() | ST67W6X_Network_Driver/Core/w6x_wifi.c |
Initialize the ST67W6X_Network_DriverNetwork module | W6X_Net_Init() | ST67W6X_Network_Driver/Core/w6x_net.c |
Initialize the ST67W6X_Network_Driver MQTT module Register pre-allocated buffer to receive subscription messages |
W6X_MQTT_Init() | ST67W6X_Network_Driver/Core/w6x_mqtt.c |
The different steps of the application Process are described below:
Description | Function | File |
---|---|---|
Connect the Wi-Fi station device to an available Access Point | W6X_WiFi_Connect() | ST67W6X_Network_Driver/Core/w6x_wifi.c |
Enable the time synchronization through a remote SNTP server | W6X_Net_SetSNTPConfiguration() | ST67W6X_Network_Driver/Core/w6x_net.c |
Retrieve the SNTP time to update the RTC time configuration | W6X_Net_GetTime() | ST67W6X_Network_Driver/Core/w6x_net.c |
Initialize the sensor expansion board | Sys_Sensors_Init() | X-CUBE-MEMS1/App/sys_sensors.c |
Configure the device to a MQTT broker | W6X_MQTT_Configure() | ST67W6X_Network_Driver/Core/w6x_mqtt.c |
Connect the device to a MQTT broker | W6X_MQTT_Connect() | ST67W6X_Network_Driver/Core/w6x_mqtt.c |
Start a topic subscription. When a new message is received, a callback catches and parses the frame. |
W6X_MQTT_Subscribe() | ST67W6X_Network_Driver/Core/w6x_mqtt.c |
Publish a new message on the selected topic. The RTC time is always set by calling HAL_RTC_GetTime() and HAL_RTC_GetDate(). If a sensor board is available, the environmental measures are added in the frame by calling Sys_Sensors_Read() |
W6X_MQTT_Publish() | ST67W6X_Network_Driver/Core/w6x_mqtt.c |
Two topics subscription are started:
- /devices/<MQClientID>/control
- /sensors/<MQClientID>
One topic is used to publish periodically (every 2s): /sensors/<MQClientID> The device receives and displays the subscribed messages on the logging trace.
The publication message format is defined as below:
{ "state": { "reported": { "time": "%y-%m-%d %H:%M:%S", "rssi": %d, ... } } }
The "state.reported" object hierarchy is used to help with interoperability with first tier cloud providers.
When a message from the subscribed topic is received through the APP_mqtt_cb() callback defined by W6X_RegisterAppCb(), the MQTT frame is pushed into a subscription queue.
An application task Subscription_process_task() pulls and parses each frame stored in the subscription queue using the cJSON middleware to extract all fields and values from the JSON format message.
Some fields are predefined as described below:
Field | Value type | Description |
---|---|---|
time | String | Current date and time. Format: "%y-%m-%d %H:%M:%S" |
mac | String | MAC address of device. Format: "00:00:00:00:00:00" |
rssi | Integer | Current RSSI level of the Access Point (in db) |
temperature | Float | Temperature from sensor board (in degC) |
humidity | Float | Relative humidity from sensor board (in percent) |
pressure | Float | Pressure from sensor board (in mbar) |
LedOn | Bool | Set the Green Led state available on the Host board |
Reboot | Bool | Reboot the Host board |
3.3. Build and install
Refer to build and install chapter to details on how to build and download on the device.
3.4. User setup
3.4.1. ST67W6X default configuration
The default System configuration can be modified in "ST67W6X/Target/w6x_config.h":
/** NCP will go by default in low power mode when NCP is in idle mode */ #define W6X_POWER_SAVE_AUTO 1 /** NCP clock mode : 1: Internal RC oscillator, 2: External passive crystal, 3: External active crystal */ #define W6X_CLOCK_MODE 1
The default Wi-Fi configuration can be modified in the "ST67W6X/Target/w6x_config.h" file:
/** Define the DHCP configuration : 0: NO DHCP, 1: DHCP CLIENT STA, 2:DHCP SERVER AP, 3: DHCP STA+AP */ #define W6X_WIFI_DHCP 1 /** Define if the DNS addresses are set manually or automatically */ #define W6X_WIFI_DNS_MANUAL 0 /** String defining DNS IP 1 address to use * @note: This address will be used only if W6X_WIFI_DNS_MANUAL equals 1 */ #define W6X_WIFI_DNS_IP_1 {208, 67, 222, 222} /** String defining DNS IP 2 address to use * @note: This address will be used only if W6X_WIFI_DNS_MANUAL equals 1 */ #define W6X_WIFI_DNS_IP_2 {8, 8, 8, 8} /** String defining DNS IP 3 address to use * @note: This address will be used only if W6X_WIFI_DNS_MANUAL equals 1 */ #define W6X_WIFI_DNS_IP_3 {0, 0, 0, 0} /** Define the region code, supported values : [CN, JP, US, EU, 00] */ #define W6X_WIFI_COUNTRY_CODE "00" /** Define if the country code will match AP's one. * 0: match AP's country code, * 1: static country code */ #define W6X_WIFI_ADAPTIVE_COUNTRY_CODE 0 /** String defining Wi-Fi hostname */ #define W6X_WIFI_HOSTNAME "ST67W61_WiFi"
The default Net configuration can be modified in the "ST67W6X/Target/w6x_config.h" file:
/** Timeout in ticks when calling W6X_Net_Recv() */ #define W6X_NET_RECV_TIMEOUT 10000 /** Timeout in ticks when calling W6X_Net_Send() */ #define W6X_NET_SEND_TIMEOUT 10000
The default Utilities configuration can be modified in the "ST67W6X/Target/w6x_config.h" file:
/** Enable LittleFS */ #define LFS_ENABLE 1
The AT driver can be configured in "ST67W6X\Target\w61_driver_config.h":
/** Maximum number of detected AP during the scan. Cannot be greater than 50 */ #define W61_WIFI_MAX_DETECTED_AP 50 /** Debugging only: Enable AT log, i.e. logs the AT commands incoming/outcoming from/to the NCP */ #define W61_AT_LOG_ENABLE 0
Additionally, some other options can be modified in the "ST67W6X/Target" directory with different configuration files as below:
- logging_config.h: This file provides configuration for the logging component to set the log level.
- shell_config.h: This file provides configuration for shell component.
- w6x_config.h: This file provides configuration for the W6X APIs (used during init).
- w61_driver_config.h: This file provides configuration for the W61 configuration module.
All available defines are available in template directory "Middlewares/ST/ST67W6X_Network_Driver/Conf"
3.4.2. Application configuration
The Wi-Fi configuration used in this application is defined in "App_MQTT/App/app_config.h":
#define WIFI_SSID "YOUR_SSID" #define WIFI_PASSWORD "YOUR_PASSWORD"
The SNTP (Simple Network Time Protocol) can be modified in "App_MQTT/App/app_config.h":
/** SNTP timezone configuration */ #define WIFI_SNTP_TIMEZONE 1
The logging output mode can be modified in "App_MQTT/App/app_config.h":
/** Select output log mode [0: printf / 1: UART / 2: ITM] */ #define LOG_OUTPUT_MODE 1
The host low power mode can be modified in "App_MQTT/App/app_config.h":
/** Low power configuration [0: disable / 1: sleep / 2: stop / 3: standby] */ #define LOW_POWER_MODE 1
The host debugger pins can be modified in "App_MQTT/App/app_config.h":
/** * Enable/Disable MCU Debugger pins (dbg serial wires) * @note by HW serial wires are ON by default, need to put them OFF to save power */ #define DEBUGGER_ENABLED 1
The MQTT client configuration can be modified in "App_MQTT/App/app_config.h":
/** Subscribed topic max buffer size */ #define MQTT_TOPIC_BUFFER_SIZE 100 /** Subscribed message max buffer size */ #define MQTT_MSG_BUFFER_SIZE 600 /** Host name of remote MQTT Broker */ #define MQTT_HOST_NAME "broker.emqx.io" /** Port of remote MQTT Broker */ #define MQTT_HOST_PORT 1883 /** Security level */ #define MQTT_SECURITY_LEVEL 0 /** MQTT Client ID to be identified on MQTT Broker */ #define MQTT_CLIENT_ID "mySTM32_772" /** MQTT Username to be identified on MQTT Broker. Not used in non-secure */ #define MQTT_USERNAME "" /** MQTT Password to be identified on MQTT Broker. Not used in non-secure */ #define MQTT_USER_PASSWORD ""
3.4.3. MEMS configuration
The demonstration project is configured to use the sensors values from the X-NUCLEO-IKS4A1 or X-NUCLEO-IKS01A3 expansion boards with the X-CUBE-MEMS1 expansion software package.
The sensor usage can be enabled in "X-CUBE-MEMS1\App\sys_sensors.h":
#define SENSOR_ENABLED 1
The expansion board can be selected in the STM32CubeMX > Software Packs Component Selector > STMicroelectronics.X-CUBE-MEMS. The IKS4A1 is enabled by default.
This optional configuration is used to append the current measured temperature, humidity, and pressure values into the MQTT messages published. More details in X-CUBE-MEMS1.
3.5. Server setup
The MQTT client is a device that connects to an MQTT broker over a network.
The MQTT broker is a server that receives all messages from the clients and then routes the messages to the appropriate destination clients. It can be a service installed on a local computer in a private network or hosted by a third party in the cloud. The MQTT uses the TCP protocol for data transmission and can be encrypted using TLS.
3.5.1. Security and certificates
The NCP utilizes littlefs to read certificates and keys from the host processor that are then store internally.
This guide outlines the process for loading certificates and keys onto the NCP using the MQTT demonstration.
The guide will also show the process for configuring the host processor and NCP for using the different security schemes for MQTT over TLS.
The X-Cube-ST67W61 expansion package provides multiple certificates and keys to test with.
These can be found in the directory:
Projects\ST67W6X_Utilities\LittleFS\Certificates\lfs
The client-server certificate and key pairs are shown are named with a numerical identifier to signify their relationship. (i.e. ca_1.crt, client_1.crt, client_1.key, server_1.crt, server_1.key).
To load the CA, client certificates and keys onto the NCP the files must be placed within the lfs folder in the MQTT demonstration folder located here: Projects\NUCLEO-U575ZI-Q\Demonstrations\ST67W6X\ST67W6X_MQTT\littlefs\lfs
The certificates and keys are loaded onto the device as a littlefs.bin binary using linker input specified in the project settings.
To build this binary from the desired certificates and keys, once they are placed in the lfs folder specified above the build.bat (Windows) or build.sh (Linux) must be run to update the binary. This batch script is located in the directory above lfs:
Projects\NUCLEO-U575ZI-Q\Demonstrations\ST67W6X\ST67W6X_MQTT\littlefs
it may be necessary to modify the script if you wish to add more files than those already present:
mklfs.exe -c lfs -b 2048 -p 256 -r 256 -s 0x4000 -i littlefs.bin
- The -b 2048 parameter is used to define the size of a block in the binary. This size must be equal to or greater than the size of each certificate.
- The -s 0x4000 parameter is used to define the binary file size (16kb). It is suitable for storing 6 certificates. If you wish to add more, you need to increase the size in block steps (0x500 by default).
The size parameter must be aligned to the define in Projects\NUCLEO-U575ZI-Q\Demonstrations\ST67W6X\ST67W6X_MQTT\littlefs\Target\lfs_flash.c:
/** This value must be aligned with prebuild script argument */ #define LITTLEFS_SECTION_SIZE 0x4000
Once run, the binary will be updated.
3.5.2. Windows MQTT broker setup
The Eclipse Mosquitto is an open-source message broker that can be installed on a local computer:
- Download and install the executable: https://mosquitto.org/files/binary/win64/mosquitto-2.0.21a-install-windows-x64.exe
- Open a command prompt (cmd.exe) and navigate to the installation folder
cd "C:\Program Files\mosquitto"
- Create/Update the broker user configuration.
Create of edit the user_mosquitto.conf file, and copy following lines:
listener 1883 allow_anonymous true
- Start the broker
mosquitto.exe -v -c user_mosquitto.conf
- Define a username/password
mosquitto_passwd.exe -c passwd st67w6x
- Then, enter a password, and provide it a second time to confirm it. For example:
12345678
- Configure the certificate files
Open the "Projects\ST67W6X_Utilities\LittleFS\Certificates\lfs" directory and copy following files in "C:\Program Files\mosquitto":
server_1.crt server_1.key ca_1.crt
3.5.3. Linux MQTT broker setup
- Install the Mosquitto broker and a client:
$ sudo apt install mosquitto mosquitto-clients
Command | Description |
---|---|
systemctl status mosquitto | Check that the service is running. |
systemctl stop mosquitto | Stop the mosquitto service. |
systemctl start mosquitto | Start the mosquitto service. |
systemctl restart mosquitto | Restart the mosquitto service. |
- Create/Update the broker user configuration.
Create of edit the "/etc/mosquitto/conf.d/mosquitto.conf" file, and copy following lines:
listener 1883 allow_anonymous true persistence true persistence_location /var/lib/mosquitto/ log_dest file /var/log/mosquitto/mosquitto.log include_dir /etc/mosquitto/conf.d
- Start the broker
sudo systemctl restart mosquitto
- Define a username/password
mosquitto_passwd -c /etc/mosquitto/passwd st67w6x
- Then, enter a password, and provide it a second time to confirm it. For example:
12345678
- Configure the certificate files
Open the "Projects\ST67W6X_Utilities\LittleFS\Certificates\lfs" directory and copy following files in "/etc/mosquitto":
cp Projects/ST67W6X_Utilities/LittleFS/Certificates/lfs/server_1.crt /etc/mosquitto/server_1.crt cp Projects/ST67W6X_Utilities/LittleFS/Certificates/lfs/server_1.key /etc/mosquitto/server_1.key cp Projects/ST67W6X_Utilities/LittleFS/Certificates/lfs/ca_1.crt /etc/mosquitto/ca_1.crt
3.5.4. Local MQTT broker security setup
The following configurations are built for a local mosquitto server.
3.5.4.1. MQTT over TCP with no authentication and no encryption
- MQTT broker user configuration
listener 1883 allow_anonymous true
- MQTT client user configuration
/* MQTT Broker connection */ static W6X_MQTT_Connect_t mqtt_connect = { .HostName = "<IP Address of Broker PC>", .HostPort = 1883, .Scheme = 0, .MQClientId = "mySTM32_772", .MQUserName = "", .MQUserPwd = "", .Certificate = "", .PrivateKey = "", .CACertificate = "", .SNI_enabled = 0 };
3.5.4.2. MQTT over TLS with username authentication
- MQTT broker user configuration
listener 8883 cafile /etc/mosquitto/ca_1.crt certfile /etc/mosquitto/server_1.crt keyfile /etc/mosquitto/server_1.key use_identity_as_username false require_certificate false allow_anonymous false password_file /etc/mosquitto/passwd tls_version tlsv1.2
- MQTT client user configuration
/* MQTT Broker connection */ static W6X_MQTT_Connect_t mqtt_connect = { .HostName = "<IP Address of Broker PC>", .HostPort = 8883, .Scheme = 1, .MQClientId = "mySTM32_772", .MQUserName = "st67w6x", .MQUserPwd = "12345678", .Certificate = "", .PrivateKey = "", .CACertificate = "", .SNI_enabled = 0 };
3.5.4.3. MQTT over TLS with server certificate
- MQTT broker user configuration
listener 8883 cafile /etc/mosquitto/ca_1.crt certfile /etc/mosquitto/server_1.crt keyfile /etc/mosquitto/server_1.key require_certificate false use_identity_as_username false allow_anonymous false password_file /etc/mosquitto/passwd tls_version tlsv1.2
- MQTT client user configuration
/* MQTT Broker connection */ static W6X_MQTT_Connect_t mqtt_connect = { .HostName = "<IP Address of Broker PC>", .HostPort = 8883, .Scheme = 2, .MQClientId = "mySTM32_772", .MQUserName = "st67w6x", .MQUserPwd = "12345678", .Certificate = "", .PrivateKey = "", .CACertificate = "ca_1.crt", .SNI_enabled = 0 };
3.5.4.4. MQTT over TLS with client certificate
- MQTT broker user configuration
listener 8883 cafile /etc/mosquitto/ca_1.crt certfile /etc/mosquitto/server_1.crt keyfile /etc/mosquitto/server_1.key require_certificate true use_identity_as_username false allow_anonymous false password_file /etc/mosquitto/passwd tls_version tlsv1.2
- MQTT client user configuration
/* MQTT Broker connection */ static W6X_MQTT_Connect_t mqtt_connect = { .HostName = "<IP Address of Broker PC>", .HostPort = 8883, .Scheme = 3, .MQClientId = "mySTM32_772", .MQUserName = "st67w6x", .MQUserPwd = "12345678", .Certificate = "client_1.crt", .PrivateKey = "client_1.key", .CACertificate = "", .SNI_enabled = 0 };
3.5.4.5. MQTT over TLS with both certificate
- MQTT broker user configuration
listener 8883 cafile /etc/mosquitto/ca_1.crt certfile /etc/mosquitto/server_1.crt keyfile /etc/mosquitto/server_1.key require_certificate true use_identity_as_username false allow_anonymous false password_file /etc/mosquitto/passwd tls_version tlsv1.2
- MQTT client user configuration
/* MQTT Broker connection */ static W6X_MQTT_Connect_t mqtt_connect = { .HostName = "<IP Address of Broker PC>", .HostPort = 8883, .Scheme = 4, .MQClientId = "mySTM32_772", .MQUserName = "st67w6x", .MQUserPwd = "12345678", .Certificate = "client_1.crt", .PrivateKey = "client_1.key", .CACertificate = "ca_1.crt", .SNI_enabled = 0 };
3.5.5. Remote MQTT broker security setup
The following configurations are designed for a remote MQTT Broker, using HiveMQ as an example.
3.5.5.1. MQTT over TCP with no authentication and no encryption
This configuration uses the public MQTT broker as TCP connection.
- MQTT client user configuration
/* MQTT Broker connection */ static W6X_MQTT_Connect_t mqtt_connect = { .HostName = "broker.hivemq.com", .HostPort = 1883, .Scheme = 0, .MQClientId = "mySTM32_772", .MQUserName = "", .MQUserPwd = "", .Certificate = "", .PrivateKey = "", .CACertificate = "", .SNI_enabled = 0 };
3.5.5.2. MQTT over TLS with serverless version
This configuration uses the private MQTT Serverless broker version. This is a free version deployed on a remote cluster with limited usage (a limited subset of features is available, such as the number of devices to notify, but it is sufficient for this demonstration).
- Download the broker Root CA certificate from HiveMQ (isrgrootx1.pem) and place it in the folder:
"ST67W6X_MQTT/littlefs/lfs/isrgrootx1.pem"
- Generate the littlefs.bin using the build script (.bat for Windows, .sh for Linux):
ST67W6X_MQTT/littlefs/build.bat
- In the HiveMQ web console, create a broker under a serverless plan and set up the corresponding credentials (for example, username = st67w6x, password = 12345678, with permission set to "publish & subscribe"). Refer to the official HiveMQ documentation for this step.
- MQTT client user configuration
/* MQTT Broker connection */ static W6X_MQTT_Connect_t mqtt_connect = { .HostName = "xxxxxxxxxxx.s1.eu.hivemq.cloud", .HostPort = 8883, .Scheme = 2, .MQClientId = "mySTM32_772", .MQUserName = "st67w6x", .MQUserPwd = "12345678", .Certificate = "", .PrivateKey = "", .CACertificate = "isrgrootx1.pem", .SNI_enabled = 1 };
3.6. Creation of CSR, certificates and keys
If you use a local broker, you may need to regenerate your own certificates.
Here's an example code in python to generate a certificate, key and CSR (Certificate Signing Request) for the client and the server side:
# Variables
CA_KEY = "ca_example.key"
CA_CERT = "ca_example.crt"
CLIENT_KEY = "client_example.key"
CLIENT_CSR = "client_example.csr"
CLIENT_CERT = "client_example.crt"
CLIENT_NAME = "mqtt_client"
SERVER_KEY = "server_example.key"
SERVER_CSR = "server_example.csr"
SERVER_CERT = "server_example.crt"
SERVER_NAME = "mqtt_server"
# Function to run openssl commands
def run_openssl(command):
try:
subprocess.run(command, check=True, shell=True)
except subprocess.CalledProcessError as e:
print(f"An error occurred: {e}")
# Generate a random CA RSA key
run_openssl(f"openssl genrsa -out {CA_KEY} 2048")
# Generate CA certificate
run_openssl(f"openssl req -x509 -new -nodes -key {CA_KEY} -sha256 -days 1024 -out {CA_CERT} -subj \"/CN=MQTT CA\"")
# Generate client private key
run_openssl(f"openssl genrsa -out {CLIENT_KEY} 2048")
# Generate client certificate request
run_openssl(f"openssl req -new -key {CLIENT_KEY} -out {CLIENT_CSR} -subj \"/CN={CLIENT_NAME}\"")
# Generate client certificate signed by CA
run_openssl(f"openssl x509 -req -in {CLIENT_CSR} -CA {CA_CERT} -CAkey {CA_KEY} -CAcreateserial -out {CLIENT_CERT} -days 500 -sha256")
# Generate server private key
run_openssl(f"openssl genrsa -out {SERVER_KEY} 2048")
# Generate server certificate request
run_openssl(f"openssl req -new -key {SERVER_KEY} -out {SERVER_CSR} -subj \"/CN={SERVER_NAME}\"")
# Generate server certificate signed by CA
run_openssl(f"openssl x509 -req -in {SERVER_CSR} -CA {CA_CERT} -CAkey {CA_KEY} -CAcreateserial -out {SERVER_CERT} -days 500 -sha256")
# Display generated files
print("Generated files:")
print(f"CA Key: {CA_KEY}")
print(f"CA Certificate: {CA_CERT}")
print(f"Client Key: {CLIENT_KEY}")
print(f"Client CSR: {CLIENT_CSR}")
print(f"Client Certificate: {CLIENT_CERT}")
print(f"Server Key: {SERVER_KEY}")
print(f"Server CSR: {SERVER_CSR}")
print(f"Server Certificate: {SERVER_CERT}")
3.7. How it works
Initialization of the ST67W6X MQTT demonstration:
#### Welcome to ST67W6X MQTT Application ##### # build: 16:23:38 May 14 2025 --------------- Host info --------------- Host FW Version: 1.0.0 --------------- ST67W6X info ------------ ST67W6X MW Version: 1.0.0 AT Version: 1.0.0.1 SDK Version: 2.0.75 MAC Version: 1.6.38 Build Date: May 10 2025 10:15:04 Module ID: BOM ID: 0 Manufacturing Year: 2000 Manufacturing Week: 00 Battery Voltage: 3.306 V Trim Wi-Fi hp: 5,5,5,5,5,5,4,4,4,4,5,5,5,5 Trim Wi-Fi lp: 4,5,5,6,6,7,7,7,7,7,7,7,7,7 Trim BLE: 3,3,3,3,4 Trim XTAL: 35 MAC Address: 40:82:7b:00:0e:6d Anti-rollback Bootloader: 0 Anti-rollback App: 0 ----------------------------------------- mount success Wi-Fi init is done Net init is done MQTT init is done
Wi-Fi scan and connection to the nearby pre-defined access point:
SCAN DONE Cb informed APP that WIFI SCAN DONE. MAC : [94:83:c4:46:c0:b3] | Channel: 9 | WPA2 | RSSI: -43 | SSID: GL-A1300-0b1 MAC : [50:91:e3:73:bc:03] | Channel: 2 | WPA2 | RSSI: -48 | SSID: TP-Link_BC03 Connecting to Local Access Point NCP is treating the connection request DHCP client start, this may take few seconds Connected to following Access Point : [50:91:e3:73:bc:03] Channel: 2 | RSSI: -46 | SSID: TP-Link_BC03 App connected
Configuration of the SNTP Client, initialization of the MEMS board sensors, connection to the MQTT broker and subscription of two topics:
SNTP Time: Wed May 14 15:29:16 2025 MEMS Sensors init successful MQTT Configure successful MQTT Connect successful Subscribing to topic /devices/mySTM32_772/control. Subscribing to topic /sensors/mySTM32_772.
Create and publish the MQTT message. As the topic is also subscribed, the message is received and displayed:
MQTT Publish OK MQTT Subscription Received on topic "/sensors/mySTM32_775" time: 25-05-14 15:54:58 rssi: -42 mac: 40:82:7b:00:0e:6d temperature: 26.84 pressure: 1001.62 humidity: 41.53 MQTT Publish OK MQTT Subscription Received on topic "/sensors/mySTM32_775" time: 25-05-14 15:55:00 rssi: -42 mac: 40:82:7b:00:0e:6d temperature: 26.82 pressure: 1001.58 humidity: 41.51 MQTT Publish OK MQTT Subscription Received on topic "/sensors/mySTM32_775" time: 25-05-14 15:55:02 rssi: -42 mac: 40:82:7b:00:0e:6d temperature: 26.79 pressure: 1001.61 humidity: 41.54
3.8. Memory footprint
Module | Description |
---|---|
[Driver] HAL/CMSIS/BSP | STM32 CMSIS Cortex, HAL and LL, Board Specific Package drivers |
[Project] Core | Native STM32 core components |
[Project] App | Main part of the application |
[Project] Target | Configuration files for ST67W6X_Network_Driver and MEMS1 components |
[MW] ST67W6X_Network_Driver | Core and API System, Wi-Fi®, Network and MQTT components Util/Logging: Utility to process shell and trace messages onto the UART interface (can be changed by ITM) |
[MW] FreeRTOS | FreeRTOS kernel source |
[MW] JSON | JSON parser library |
[MW] LittleFS | LittleFS file system |
[Utility] lpm | Tiny Low-Power Management |
[Toolchain] Startup | Int_vect, init routines, init table, CSTACK and HEAP |
[Toolchain] EWARM Libraries | Native compiler libraries |
These values depend on the chosen toolset and they can change in next releases.
3.8.1. ROM/flash memory footprint
The picture below shows the sum of the read only memory (flash) of the MQTT demonstration.
The picture below shows the middleware ST67W6X_Network_Driver read-only memory (flash) used by MQTT demonstration.
3.8.2. Read-Write (RW) memory footprint
The picture below shows only the sum of the static read/write memory (static RAM) of the MQTT demonstration.
4. References