Skip to main content
Version: 5.0

Run the Example

Project Content

The FreeRTOS Demo example is spread over two separate projects: one for the destination, the other for the source.

ProjetFolderDescription
Acklio Open-Source ExampleCloudThe Python source files of the UDP client/server application running on the Cloud side
STM FullSDK Reference implementationMiddlewares / Third PartyThe source files to build the FreeRTOS/IP/UDP client/server application to run on the board. Acklio FullSDK project folder is also in this directory.

Dependencies

ResourceLink
STM32CubeIDEIDE to load ST projects. It can be downloaded from the official website
GitLab Repositoryhttps://gitlab.acklio.cloud/acklio-opensource/stm-fullsdk-reference-implementation/-/tree/release/STM32CubeExpansion_LRWAN_V2.1.0
Build & Flash DocumentationThe STM32Cube compilation page explains in detail how to build and flash the device for the FreeRTOS demo

The IP stack library used on device-side is uIP.

The Cloud application requires Python 3 to run.

Demo Application Workflow

The messaging between the client application and the server application follows the scenario illustrated below.

Client Server Messaging

During a session, four messages are transmitted between the client and the server applications. They contain the session identifier and a dummy payload.

  1. Message #1 Small uplink payload (less than 50 bytes) which is not fragmented.
  2. Message #2 Small downlink payload (less than 50 bytes) which is not fragmented.
  3. Message #3 Large uplink payload (more than 242 bytes) which is fragmented.
  4. Message #4 Large downlink payload (more than 242 bytes) which is fragmented.

The downlink message is always sent 5 seconds after the server application received the uplink message. Once it is received by the client application, it is printed in the logs.

The transmission delay between two consecutive uplinks is set to 600 seconds.

At the end of the session, a new session of transmission starts.

FreeRTOS Tasks

The device application is made of three layers, implemented as three FreeRTOS tasks as illustrated below.

Layers

The communication between the device application and the Cloud application is made by sending external messages.

The communication between layers uses queueing and internal messages. The internal message types are defined in common.h by the message_type_e enumeration.

Periodical Messages

External messages are transmitted periodically from one layer to the next.

External messages

FromToMessageDescription
task_apptask_appSENDSends an external message
task_apptask_uipSENDSends an external message
task_uiptask_uipSENDSends an external message
task_uiptask_sdkSENDSends an external message
task_sdktask_uipTX_RESULTResult of the previous transmission request
task_uiptask_appTX_RESULTResult of the previous transmission request
task_sdktask_uipDATA_RCVDData has been received
task_uiptask_appDATA_RCVDData has been received

The message that task_app sends to itself is generated by the timer handler function that allows the periodic transmission of the external message.

The message that task_uip sends to itself is due to the way the uIP stack works.

task_app

task_app is the application task. It periodically requests to send an external message to the remote Cloud application (see below).

Let's take the example of a long message that should be sent from the device application to the Cloud application. It contains the following string, terminated by a new line character.

Hello, Acklio!

On user action in the Cloud application, the application task requests to send the following external string, terminated by a new line character.

Hi, there!

When the application task receives an external message from the remote Cloud application, it displays the first 48 bytes of the message, in hexadecimal.

In the case of a short message containing the string getLocalTime, the application task of the Cloud application replies with a message structured as follows (where nnnnnnnnnn contains the current board time in ms, left padded with 0).

local time: nnnnnnnnnn

task_uip

task_uip contains the uIP stack. It forwards external messages from the application layer to Acklio FullSDK layer.

When the application layer wants to send an external message to the Cloud application, it forwards it to task_uip that wraps it in an IPv6/UDP datagram and requests task_sdk to send it.

Conversely, when a datagram is received from the Cloud application via task_sdk, task_uip extracts the payload and forwards it to the application layer.

task_sdk

task_sdk runs the FullSDK which performs IPv6/UDP compression/decompression and fragmentation when required.

Device Initialization

The main function, in main.c, initializes the system (peripherals, clock, etc.) then starts the tasks.

Device initialization

FromToMessageDescription
task_apptask_uipINITInternal message to initialize the uIP layer
task_uiptask_sdkINITInternal message to initialize Acklio FullSDK layer
task_sdktask_sdkPROCESSRun Acklio FullSDK processing
task_sdktask_sdkNETWORK_JOINEDConnectivity is up
task_sdktask_sdkNETWORK_CONFIGUREDDevice network interface is configured
task_sdktask_uipNETWORK_CONFIGUREDDevice network interface is configured
task_uiptask_appREADYInternal message informing on layer status
task_uiptask_appCAN_NOT_SENDInternal message: The layer is busy, the transmission request cannot be fulfilled

Cloud Application

The Cloud application can send downlink messages to the device on user action (See above, task_app).

Action for a Long Message

When the D key is pressed and then Enter, a long message is sent to the device that contains a timestamp, a sequence number and a text.

nnn - hh:mm:ss - text
  • nnn The sequence number, with three figures. It starts from 000 and is incremented with each new downlink message. When it reaches 999 it wraps around to 000.
  • hh:mm:ss The timestamp.
  • text The text contain enough characters to make a message of 300 bytes.

Action for a Short Message

When the T key is pressed and then Enter, a short message is sent to the device, requesting the local time of the device. The reply of the device is displayed.

More generally, every uplink message sent by the device is displayed.

Run the Demo Example

The Demo starts on Cloud-side.

Cloud Side

The Cloud application must run on the same machine as the VPN agent.

In the acklio-opensource-examples/examples/freertos/udp-client-server folder, run the following command:

python3 -m cloud -dev-ip <dev_ipv6_addr> -dev-port <dev_udp_port> -app-ip <app_ipv6_addr> -app-port <app_udp_port_>

Where:

  • <dev_ipv6_addr> is the IPv6 address of the device, as displayed in the device profile in Acklio IPCore.
  • <dev_udp_port> is the UDP port of the device, as defined in Acklio IPCore.
  • <app_ipv6_addr> is the IPv6 address of the application address, as defined in Acklio IPCore.
  • <app_udp_port> is the application UDP port, as defined in Acklio IPCore.

The server application requires an IPv6 address to start. To assign it to one of the network interfaces on your machine, run:

sudo ip -6 address add <app_ipv6_addr> dev <network_interface>

Client Side

Make sure that you flashed the board and that the board is connected to the development computer.

In the STM32 Cube IDE:

  1. Select the "Release" build configuration.
  2. Go to "Run > Run Configurations..." to create the "Run" configuration from it.
  3. Click the "Run" button.

View the Logs

To display trace messages generated by the device application, use one of the following commands depending on your terminal emulation application.

miniterm /dev/<usbPort> 9600
minicom -D /dev/<usbPort> -b 9600 -w