back to main page

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.

STM32CubeMX Packages Manager

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.).

STM32CubeMX Packages Manager
Warning white.png Warning
After selecting components in the Component Selector, they must also be activated in the Mode panel.
Enabling components

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.
Applications menu

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.
Refer to Application projects page.

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.).

ST67W6X User application

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:

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.
copy and rename the ioc in a new directory
Step 2 Choose the application you want to generate (e.g. User_v).
Application list
Step 3 Adapt the parameters values if needed (W6X Modules, Parameter Settings, Platform Settings).
Update Module Initialization generation
Step4 Disable the call to Mx_App_User_Init (do not call function check box).
Disable Mx_App_User_Init
Step5 Select the IDE and Press Generate code button.
User application generated from X-CUBE-ST67W61 directory structure
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)
select Use Default Firmware Location and Copy only the necessary library files in the menu Project Manager > Code Generator.

Self content project creation

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.
Pinout Compatible MCU results

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.

Pinout Compatible MCU STM32L5 : ioc created

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

STM32L5 code generated

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

Open STM32CubeMX and do access to the board selector
Select the STM32 Nucleo-64 development board

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:

X-Nucleo-67W61M1 top view
Setting Description
UART GPIO
UART GPIOs setting - In accordance with X-Nucleo-67W61M1
SPI GPIO
SPI GPIOs setting - In accordance with X-Nucleo-67W61M1
Channels DMA
Channels DMA setting - association with SPI
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.
LPTIM1 setting
GPIO
GPIO mode configuration
Warning white.png Warning
During pinout setting with CubeMx "Pinout & Configuration" tool, special attention has to be done with GPIO mode Pinout

Each GPIO pin has to respect the exact GPIO mode.
As example, SPI_RDY GPIO mode has to be set to "External Interrupt Mode with Rising/Falling edge trigger detection"

Timer
Sys mode configuration: TIM1 in place of systick

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.

Connectivity Snipping taskSize stack2025-05-20 163347.png

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.

Heap size adjusted to a value equal to 40000 bytes


Warning white.png Warning
Legacy FreeRTOS: If the used device embeds an Arm® Cortex®M0+ (e.g. STM32G0) and its FreeRTOS version is older than of V10.6, definition below must be added manually after project has been generated.

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.

X-Cube-ST67W61 pack - mode and configuration

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.

X-Cube-ST67W61 pack - configuration and platform setting

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.

Connectivity Snipping advancedsetting 2025-05-20 160741.png

3.3.6. Step 6: Generate and build the project

After completing the "Project Manager" setting, press "Generate Code" button

CubeMx has generated a new project (in our case in EWARM eco-system)

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:

  1. 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,
  2. 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

IAR Embedded IDE

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.