1. Introduction
X-CUBE-ST67W61.pack is made available in the STM32CubeMX ecosystem.
It can be installed from the “Software Packs” menu, more precisely from the "Manage Software packs” (Alt+U) and “Select Components” (Alt+O) panels.
The X-CUBE-ST67W61 projects provided in the classical X-CUBE-ST67W61_v1.0.0.zip are generated using the STM32CubeMX.
X-CUBE-ST67W61_v1.0.0.zip contains eleven projects for NUCLEO-U575ZI-Q board, and two projects for each of NUCLEO-H7S3L8, NUCLEO-H563ZI and NUCLEO-N657X0-Q boards.
All the projects have been created using the STM32CubeMX initialization code generator with ioc files.
The scope of X-CUBE-ST67W61.pack within STM32CubeMX is to help the users:
- create their own project
- port existing application examples on other devices
- perform the combination of the two points above
The prerequisites are:
- To have the latest STM32CubeMX version installed - version 6.14.1 was used to make this tutorial
- To have the latest X-CUBE-ST67W61 installed - version 1.0.0 was used for this
1.1. Hardware requirements
- 256 KB of flash memory
- 48 KB of RAM memory
- At least, SPI and DMA shall be present
Remember to flash the updated code in the ST67W611M, refer to How to flash the ST67W611M.
1.2. Known limitations and tips
The projects created with X-CUBE-ST67W61.pack are meant to be functional “almost” out of the box.
A few user actions are requested before generating the projects:
- Under the panel "Project Manager" and "Advanced Settings": select the checkbox “do not generate function call” for "Mx_App_xxx_Init()".
Not doing that can lead to a warning or an error depending on the IDE. - The default values of the parameters are not customized for each application variant.
Not adapting some of the parameters might lead an application to run incorrectly.
Check how the parameters are configured by looking to the ioc files of the corresponding applications (all applications are available on NUCLEO-U575ZI-Q).
Once the code is generated, the application will do nothing unless you add the call to the main_app() function within the FreeRTOSTM StartDefaultTask function.
#include "main_app.h" void StartDefaultTask(void *argument) { /* USER CODE BEGIN defaultTsk */ main_app(); for (;;) { osDelay(1000); } /* USER CODE END defaultTsk */ }
Depending on the family, some compilation errors may happen.
They are often due to FreeRTOS compatibility limitations or incorrect configuration of the ioc files.
More details about these topics are given in the next chapters.
1.3. FreeRTOS
All the applications available in the X-CUBE-ST67W61 expansion package are based on FreeRTOS.
- STM32N6 requires at least X-CUBE-FREERTOS V1.3.1 expansion package based on FreeRTOS 10.6.2 version
- CM33 core-based families need at least X-CUBE-FREERTOS V1.3.0
- Old devices use legacy FreeRTOS (i.e. FreeRTOS provided directly in the Middleware without need to select the X-CUBE-FREERTOS expansion package) and the version of such FreeRTOS depends on the families
- STM32L0, STM32F0, use FreeRTOS v10.2.1
- STM32H7, STM32L4, STM32G0 and STM32F4 use FreeRTOS v10.3.1
- STM32H7Rx/7Sx uses FreeRTOS V10.6.2
Required adjustments:
- For STM32 on CM0/CM0+ cores with FreeRTOS version older than 10.6 (e.g. STM32G0): xPortIsInsideInterrupt CM0 workaround.
- Setting the Heap size bigger than default size (by default STM32CubeMX put it xxx) (in the provided examples it is set to 30 kb). Refer to Heap Size adjustment.
- Setting the stack size of the default task to 512 kb (by default STM32CubeMX put it to 128 kb which will lead to stack overflow during initialization). Refer to Stack Size adjustment.
- For a few device families, the associated FreeRTOS version might be wrongly detected, in such case, it might be necessary to change the main_app.c to include the correct FreeRTOS API file (typically app_freertos.h vs FreeRTOS.h)
General limitation not related to the X-CUBE-ST67W61 pack:
- In case of STM32N6 devices, the generated IDE projects include FreeRTOS code for one domain at the time, either secure or nonsecure. X-CUBE-ST67W61 must be on the same domain.
1.4. User code sections limitations
The X-CUBE-ST67W61 applications implement some basic support of USER CODE SECTION to be compatible with STM32CubeMX methodology but not with the intention to cover all cases.
The STM32CubeMX GUI (within component selector) provides the User application which allows the user to write his own application code within USER CODE SECTION.
2. X-CUBE-ST67W61.pack configuration
2.1. Component Selector overview
The pack consists of various layers and components.
The Component Selector lets you choose which modules will be compiled and linked to the project. Some modules are always required, some depend on the chosen application, and others are optional (e.g., for enhanced logs, statistics, performance measures, trace dumping, low power, etc.).
2.1.1. Main components
These two components must always be selected to use applications delivered in the X-CUBE-ST67W61.
Component | Description |
---|---|
Service API | Wi-Fi®, Bluetooth® LE, Network, HTTP, MQTT, OTA and System APIs. Required to provide interfaces to the chosen application. |
Driver / W61_at_and_bus | Implementation of AT layer driver and SPI Bus Management. Required to exchange with the ST67W611M1 module. |
2.1.2. Applications component
Component | Description |
---|---|
Application | X-CUBE-ST67W61 contains ten “functional applications” and one User application. If the user wants to create its own application based on the ST67W6X_Network_Driver Middleware,
it is suggested to select the User application as a starting point. |
Some applications provided in the X-CUBE-ST67W61.zip are extended compared to what CubeMx generates starting from an empty directory.
In particular:
- FOTA application for STM32U5 implements also the host firmware to be updated. The related code strongly depends on the host device and on its flash memory. Refer to FOTA application for details.
- HTTP Server and Wi-Fi Commissioning applications embeds an HTML server. Refer to How to generate html_page.h for details.
- MQTT and HTTPS client applications are functional with the embedded (default) certificate. Refer to Security and certificates to generate your own certificates.
2.1.3. Utilities
These three elements are optional but may be required depending on the application chosen.
If a component is not selected, the associated files are not linked in the project structure.
Component | Description |
---|---|
Logging | Redirect all middleware and application traces to the selected HW output. By default, UART is chosen as the output solution. If the Logging component is not selected in the Component Selector, printf / putchar will be employed instead. Users have the option to implement their own module by adhering to the API, which can be achieved by overriding the function vLoggingPrintf(). When Logging is selected in the Component Selector, the default settings configure the OUTPUT_MODE to OUTPUT_MODE_USART and the LOG_LEVEL to DEBUG for all applications. Users can modify these settings through the GUI in the Parameter Settings panel. |
Service Shell | Shell functions to manage the API functions directly into the UART Terminal. The Shell utility is required to use the Service Shell features. |
Shell utility | Provides a command line interface solution for the user to interact with the program via a serial command. When the component is selected, the feature is disabled by default. The SHELL_ENABLE parameter can be modified in the Parameter Settings tab. |
Statistics | Provides some tools to evaluate the performances of the RTOS or Network. When the component is selected, the features are disabled by default. The TASK_PERF_ENABLE, MEM_PERF_ENABLED, IPERF_ENABLED parameters can be modified in the Parameter Settings tab. |
When using the Shell utility, all Service Shell functions must be placed in specific region of the Flash.
Depending on the IDE chosen, the following change must be applied to the project structure:
IDE | Shell utility specific region requirement |
---|---|
EWARM | in the linker script file (as example stm32u575xx_flash.icf):
keep { section FSymTab }; place in ROM_region { readonly, ro section FSymTab }; |
STM32CubeIDE | in the linker script file (as example STM32U575ZITXQ_FLASH.ld):
/* The program code and other data into "FLASH" Rom type memory */ .text : { *(.text) /* .text sections (code) */ ... . = ALIGN(4); __fsymtab_start = .; KEEP(*(FSymTab)) __fsymtab_end = .; _etext = .; /* define a global symbols at end of code */ } >FLASH |
MDK-ARM | In Misc controls field of the project Linker options (Project->Options->Linker->Misc controls) add the following options:
--keep *.o(FSymTab) --diag_suppress L6319W The diag suppress is needed to avoid the warning about the unused section. |
2.1.4. Third Party Middlewares
These three optional components provides specific features for some applications.
Component | Description |
---|---|
cJSON | Ultralightweight JSON parser used by several applications (CLI, MQTT, HTTPS client, FOTA). |
LittleFS | Minimal File System used by projects to export Certificates files to the ST67W611M1 module. These certificates are needed for the security methods (HTTPS, MQTTS, SSL). |
TraceRecorder | Percepio Trace tool used to analyze the Real-Time Operating System execution. More details: How to debug with Percepio Trace |
2.1.5. Low Power
The Tiny LPM provides a set of macros to enter and exit chosen Low Power mode (Sleep, Stop, Standby).
When selected, FreeRTOS tickless may be required to manage low power directly in the operating system sequencer.
The feature is disabled by default. The LOW_POWER_MODE parameter can be modified in the Parameter Settings tab.
The Low Power code is provided for the STM32U5 Family. For other platforms, a warning will be raised to inform the user to verify compatibility.
2.2. Configuration panel
The GUI panel "W6X Modules" helps to select the features to be initialized (Wi-Fi®, Bluetooth® LE, Network, etc.), the "Parameters Setting" panel is used to configure the W6X and the "Platform Settings" is used to map the IPs instances (e.g. SPI1, USART1, etc.).
2.2.1. W6X Modules tab
The ST67W61 service API and Driver components are composed by different "modules" (Wi-Fi®, Bluetooth® LE, Network, MQTT).
The user can choose which module to initialize:
- WIFI_STA_INIT
- WIFI_SAP_INIT
- NET_INIT
- MQTT_INIT
- BLE_INIT
The code for these modules is always generated, but it won't be linked if not initialized.
2.2.2. Parameter Settings tab
Parameters are spread across several configuration files:
Section | Description |
---|---|
App parameters | Setup the application features in the app_config.h file. |
W6X parameters | Setup the API default configurations (mainly used at initialization) in the "w6x_config.h" file. |
W61 driver parameters | Setup the AT drivers default configuration in the "w61_driver_config.h" file. |
Logging-Shell parameters | Setup the Logging and Shell components in the "logging_config.h" and "shell_config.h" files. |
Basic parameters | Setup the global common configuration used by the application and the middleware components. |
2.2.3. Platform Settings tab
Mapping between the IPs used by the ST67W61 applications versus the IPs that have been enabled on the device.
IP | Description |
---|---|
SPI | Communication to the modem uses SPI. |
USART | User can decide to not output log, use ITM or use its own system. However, when Shell component is enabled USART is mandatory. |
LPTIM | Required only in case FreeRTOS tickless component is selected (used for Low Power with STM32U5) |
3. How to generate projects
Three cases are covered:
- How to generate a project starting from an existing ioc
- How to export a project to a pinout compatible MCU
- How to generate a project starting from scratch
3.1. How to generate a project starting from an existing ioc
This can be done for one of the devices available in the pack (NUCLEO-U575ZI-Q, NUCLEO-H563ZI, NUCLEO-H7S3L8 and NUCLEO-N657X0-Q).
For other devices than NUCLEO-U575ZI-Q, the X-CUBE-ST67W61 only provide two projects (CLI and Echo),
this method allows to generate easily the other projects for the other mentioned devices.
Steps | Description | Graphical view |
---|---|---|
Step 1 | Copy an ioc file in a new directory. | |
Step 2 | Choose the application you want to generate (e.g. User_v). | |
Step 3 | Adapt the parameters values if needed (W6X Modules, Parameter Settings, Platform Settings). | |
Step4 | Disable the call to Mx_App_User_Init (do not call function check box). | |
Step5 | Select the IDE and Press Generate code button. | |
Step6 (Optional) | Skip the step5, enable the Flat directory structure, select the IDE and Press Generate code button. To use flat directory structure (i.e. Driver and MW directories copied into your project directory) |
Once the code is generated, the application will do nothing unless adding the call to main_app() function within the FreeRTOS StartDefaultTask.
#include "main_app.h" void StartDefaultTask(void *argument) { /* USER CODE BEGIN defaultTsk */ main_app(); for (;;) { osDelay(1000); } /* USER CODE END defaultTsk */ }
Fill the user code section with your code.
If the component Shell is used, the linker file has to be customized, see Utilities.
The examples above demonstrate how to generate the User_v application, but this method can be applied to any application not provided for a specific target (e.g., for NUCLEO-H7S3L8, NUCLEO-H563ZI, and NUCLEO-N657X0-Q).
Keep in mind that USER CODE SECTIONS for applications other than User_v may not meet all requirements.
3.2. How to export a project to a pinout compatible MCU
This is done starting from an existing ioc and using the “Pinout compatible MCU” feature. The feature is deeply described in the chapter 15 of the following STM32CubeMX tutorial:
https://www.st.com/resource/en/user_manual/um1718-stm32cubemx-for-stm32-configuration-and-initialization-c-code-generation-stmicroelectronics.pdf:
Within the ioc provided in the pack (NUCLEO-U575ZI-Q, NUCLEO-H563ZI, NUCLEO-H7S3L8 or NUCLEO-N657X0-Q), choose the one with package, board, pinout as much as similar to the device you need to port the application.
For example, to generate for STM32L552ZCTxQ, the ioc provided for NUCLEOS U575ZI-Q are a good starting point, because STM32L552ZCTxQ is full pin compatible.
- If the device to which user wishes to port the code is available and if it is Pinout Fully compatible, the expected exporting time is rather quick.
- If the device to which user wishes to port the code is available, but it needs HW changes, some additional work (and time) is required, depending on the incompatibilities.
- If the device to which user wishes to port the code is not available, porting becomes more complex, go to next chapter: Generate from scratch.
Double-clicking on the wished device will create a new ioc, based on that device.
Notice that all IPs (SPI, UART) and GPIO labels and setting are automatically ported.
Sometimes the user might need to apply some minor adaptations, as for example the Interrupt priority if they are not in the same range.
When passing from a device Using X-CUBE_FreeRTOS to a device family using Legacy FreeRTOS, the FreeROS shall be reenabled and reconfigured.
Refer to FreeRTOS.
The ST67W61 might also need to be reconfigured, in particular the Platform Settings. Refer to X-CUBE-ST67W61-pack_configuration.
In Clock Configuration panel, check the SPI clock is still 40MHz maximum.
Under the panel "Project Manager" and "Advanced Settings": select the checkbox “do not generate function call” for "Mx_App_xxx_Init()".Not doing that can lead to a warning or an error depending on the IDE.
Once everything is configured, press "Generate code" button.
Next image shows that code is generated for the selected family, in this example notice STM32L5xx_HAL_Driver
Once the code is generated, the application will do nothing unless adding the call to main_app() function within the FreeRTOS StartDefaultTask.
#include "main_app.h" void StartDefaultTask(void *argument) { /* USER CODE BEGIN defaultTsk */ main_app(); for (;;) { osDelay(1000); } /* USER CODE END defaultTsk */ }
Fill the user code section with your code.
If the component Shell is used, the linker file has to be customized, see Shell.
3.3. How to generate a project starting from scratch
This is necessary to generate a project from scratch when the device family, the type of package or the shield, are not pin compatible with the ioc delivered as examples.
A step by step description based on a NUCLEO-G0B1RE board, is shown below. The following flow can be applied to other Nucleo family boards (STM32U5, STM32H7Rx/7Sx, STM32H5, ...).
3.3.1. Step 1: Project creation
Open STM32CubeMX and create the new project
Note: Nucleo-64 is selected since STM32G0 is chosen as a target example, but Nucleo-144 could be chosen for other STM32.
3.3.2. Step 2: Pinout & Configuration
Provides all the different steps to configure the hardware pinouts and the relevant Middleware
3.3.2.1. Pinout
When generating an application from scratch and if X-Nucleo-67W61M1 is used, the pinout must be set in accordance with the ST67W61M1 Arduino interfaces.
The table below summarizes them:
Pin function | NUCLEO pin name | GPIO mode | GPIO pull mode | GPIO speed |
---|---|---|---|---|
SPI_CLK | D13 | AF PP | No pull | Very high |
SPI_MISO | D12 | AF PP | No pull | Very high |
SPI_MOSI | D11 | AF PP | No pull | Very high |
SPI_CS | D10 | Output PP | No pull | High |
USER_BUTTON | D8 | EXTI Falling | Pull-up | N/A |
CHIP_EN | D5 | Output PP | No pull | High |
BOOT | D6 | Output PP | No pull | Low |
SPI_RDY | D3 | EXTI Falling/Rising | No pull | N/A |
As an help, the X-Nucleo-67W61M Arduino view is shown below:
Setting | Description |
---|---|
UART GPIO | |
SPI GPIO | |
Channels DMA |
3.3.2.2. Configuration
Setting | Description |
---|---|
Low Power Timer | The following LPTIM1 setting is just given as a "how to do" in case of Low Power application requirements. This Low Power and FreeRTOS tickless requirement is only available on STM32U5 platform see Low Power requirements. |
GPIO | |
Timer |
3.3.3. Step 3: Clock configuration
In the ''Clock Configuration'' panel, set the SPI clock to 40MHz maximum.
3.3.4. Step 4: Middleware & Software Packs
After having configured the hardware pinouts, the real time kernel and software package must be selected and configured.
3.3.4.1. FreeRTOS parameters adjustments
FreeRTOS component can be either be selected from Middleware (FREERTOS) or from the Software Pack (X-CUBE-FREERTOS) depending on the chosen STM32.
By default, the stack size of the default task defined by STM32CubeMx tool is equal to 128 words. The application default task required 512 words.
Adjust heap size and stack size:
The size heap value should be set at least to 40Kbytes. In order to optimize the memory, this value could be adjusted during integration and validation tests of the application.
THe definition of xPortIsInsideInterrupt() must be added in macroport.h.
portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) { uint32_t ulCurrentInterrupt; BaseType_t xReturn; /* Obtain the number of the currently executing interrupt. */ __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); if( ulCurrentInterrupt == 0 ) { xReturn = pdFALSE; } else { xReturn = pdTRUE; } return xReturn; }
3.3.4.2. X-CUBE-ST67W61 Software package
By selecting the X-CUBE-ST67W61 pack, up to 11 different applications (Echo, Ping, WiFi_Commissioning, CLI, BLE_Commissioning, BLE_p2p_Client, BLE_p2p_Server, FOTA, HTTP_Server, HTTPS_Client, MQTT) and one User project can be selected.
See Component Selector overview for more details.
Having selected an application (here "Echo_v" is selected), components of the software pack must be enabled thanks to the associated checkboxes.
You must also set the platform setting tab.
See Configuration panel for more details.
3.3.5. Step 5: Project Manager
User should select the checkbox “do not generate function call” for Mx_App_xxx_Init. Not doing that can lead to a warning or an error depending on the IDE.
3.3.6. Step 6: Generate and build the project
After completing the "Project Manager" setting, press "Generate Code" button
After doing a project generation, the user will have to implement some additional modifications:
- The main_app() function which is defined in the app_freertos.c file has to be called in the task named "StartDefaultTask". This "StartDefaultTask" is definied in the main.c file. In order to declare the prototype of the called function, do inclusion of the main_app.h file in a user code section of the main.c (in private includes user code section).
/* USER CODE BEGIN Header_StartDefaultTask */ /** * @brief Function implementing the defaultTsk thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_StartDefaultTask */ #include "main_app.h" void StartDefaultTask(void *argument) { /* USER CODE BEGIN defaultTsk */ main_app(); /* Infinite loop */ for (;;) { osDelay(1000); } /* USER CODE END defaultTsk */ }
- For STM32 on CM0/CM0+ cores with FreeRTOS version older than 10.6, add the definition of xPortIsInsideInterrupt() as defined in macroport.h cf legacy freertos
Do "Open Project". At this point you have two options:
- Launch directly a "Rebuilt all" IAR command to generate a new executable. You will be faced to "compilation issues" which can be solved thanks to "Manual user modifications" described above,
- Do "Manual user modifications" before launching the "Rebuilt all" IAR command to generate a new executable.
Whatever the options chosen, the final build should be OK
Now, binary is ready to download and to run the application on the target and to debug it if something goes wrong from a functional point of view.