Technical topic: TASTE on MSP430 with FreeRTOS

From TASTE
Revision as of 08:33, 26 May 2020 by Rbabski (talk | contribs)
Jump to: navigation, search

This page describes how FreeRTOS support was added to TASTE.

Hardware Description

This article describes steps of adding support for MSP-430 platform using MSP43FR5969 processor as example. The MSP430FR5969 LaunchPad Development Kit was used for testing purposes.

Microcontroller's parameters:

  • 16-bit RISC architecture;
  • 16‑MHz Clock;
  • 64KB FRAM / 2KB SRAM.

On this very limited platform using PolyORB-HI-Ada or PolyORB-HI-C is impossible, due to memory requirements. In the next sections the different approach of code generation is described.

Memory models in MSP430FR5969

The MSP430FR5969 can operate in two memory models:

  • small memory model;
  • large memory model.

In small memory model only 48 KB of FRAM are available for programmer with additional 2 KB for stack and global or static variables. This limitation is caused by the fact, that in small memory model, only 16 bits for addressing are avaiable. The 16 bit should allow to address 64 KB of memory, but some memory areas are used by bootlader or perpherals.

In large memory model, the programmer can use additional 16 KB of FRAM, which gives 64 KB of memory + additional 2 KB for stack and bss. In this model all 20 bits of address line are used and also the size of pointers are bigger - 4 bytes instead of 2 and the different instruction set is used. It means that simple change from small memory model to large memory model increases size of generated code.

In small memory model the static and global variables are allocated in 2KB of RAM, which may be too small memory segment of are variables. The variables may be allocated outside the RAM segment by adding the special attribute, bellow is the example but it can be changed by additing special attribute. For an example:

__attribute__ ((persistent)) int global_variable = 0;

The programmes should reintialize value of this variable after reset of the MCU.

In large memory model the variables may be allocated outside the RAM memory segment, which allows the programmer to declare large number of variables. There's also an compiler option -mdata-region=upper to use only memory segment from higher memory, the almost whole RAM segment may be used by stack.

The problem with 2 KB of RAM segment is that the stack may overwrite the other variables allocated in this segment during runtime. This may happen before start of FreeRTOS scheduler, during initialization. Currently about 200 bytes of stack are required. The programmer should make sure that, there's enaugh space for stack in the RAM segment after building the partition image.

TBD Script which checks this constraint since the msp430-elf-ld does not allow to set the stack size (The TI compiler allows to do this).

FreeRTOS port for MSP430FR5969

The FreeRTOS port for MSP430FR5969 supports both small memory model and large memory model. When large memory model is used the following options should be passed to the compiler:

  • -D__LARGE_DATA_MODEL__=1
  • -mlarge

There are options to specify in which memory segment the code and data should be placed:

  • -mcode-region=[either,lower,upper]
  • -mdata-region=[either,lower,upper]

The options -mcode-region=either,lower,upper -mdata-region=upper are recommended for TASTE.

For small memory model, the only required compiler option is -msmall.

Memory allocation in FreeRTOS

FreeRTOS may be configured to use dynamic memory allocation or static memory allocation or both. When the dynamic memory allocation is used the programmer shoud provide memory region for special FreeRTOS heap. When static memory allocation is used the programmer shoud allocate required structures before creating FreeRTOS objects. For TASTE the dynamic memory allocation is disabled, the generated code uses only static memory allocation.

More information at Static Vs Dynamic Memory Allocation

New execution platform

Add new platform Platform_MSP430_FreeRTOS to TASTE. Follow instructions from Technical topic: Add a new target platform to TASTE.

TBC

Kazoo templates for MSP430

Kazoo generates multiplatform skeletons and glue source code for function blocks. The asn1scc generates code responsible for encoding/decoding data, which is also platform agnostic.

The rest of the code, which should be generated to create image of the partition, comes from Concurrency View. This code is responsible for device initialization, the initialization of drivers and function blocks from Interface View, and communication between these objects. To cope with this the following entities should be used:

  • Threads;
  • Queues;
  • Timers;
  • Mutexes/Semaphores.

Before support for MSP430 this was achived by using code generated by Ocarina which uses PolyORB-HI-Ada or PolyORB-HI-C as middleware.

Support for MSP430 is based on FreeRTOS constructs:

This set of constructs is enaugh to create code which ensures cooperation of function blocks and communication with remote partitions.

For every function block from Interface View the generated code should create mutex or semaphore, which is used for synchronization. For every interface of the function block, the set of funnction for passing messages should be generated, and in additional:

  • if the interface is cyclic, the generated code shoud create timer and message queue, and
  • if the interface is sporadic, the generated code should creater message queue;
  • if the interface is protected, the code should acquire and release lock before calling the function;
  • if the interface is unprotected there's no additional constrains.

For every thead the Stack_Size and Priority properties should be included.

For every queue the property Queue_Length should be taken into account.

If the node from Deployment View contains devices, then the genrated code should include drived implementation code.

The templates should also generate the Makefile and GNAT Project Manager configuration file, which are responsible for building process of the partition image.

Following sections describes the kazoo templates.

msp430_freertos_gpr

The sole purpose of this template is to create following files:

  • build/node/Makefile.node;
  • build/node/partition_partition.gpr.

The only purpose of Makefile is to run grpbuild to build whore partition binary and to run script which copies required FreeRTOS source files into partition source directory.


The generated gpr file contains configuration for GNAT project manager. In this file following sections are generated:

  • List of directories of source files, relative to the location of gpr file , see Source_Dirs
  • Directory for object files, relative to the location of gpr file, see Object_Dir
  • Directory for outpt file, relative to the location of gpr file, see Exec_Dir
  • Configuration of the compilers see package Compiler, which includes:
    • paths to the compiler executables
    • flags for the compilers
  • Configuration of the linker, see package Linker,
    • path to the linker executable
    • flags for the linker

See other templates like c_pohi_gpr.

msp430_freertos_files

This template generates file build/node/gather_freertos_files.sh, which is executed by Makefile.node. The sole purpose of this file is to copy required FreeRTOS source files to the partition directory. The location of FreeRTOS directory is expressed by FREERTOS_PATH environment variable.

If the files cannot be copied, the script prints an error message, and the process of building is terminated.

msp430_freertos_config

The sole purpose of this template is to produce file build/node/partition/FreeRTOSCOnfig.h. This file is required by FreeRTOS. this file determines minimal set of FreeRTOS construct, which are required to build partition. Almost all options are disabled.

msp430_freertos_main

This template generates file build/node/partition/main.c, which is entry point for the partition.

This file contains following functions:

  • function prvSetupHardware, which configures MSP430FR5969 MCU and calls device drivers initialization routines.
  • function vApplicationStackOverflowHook, which may be used to check stack overflow during debugging (see [1]).
  • function vApplicationSetupTimerInterrupt, which configures Timer A for FreeRTOS system ticks.
  • function vApplicationGetIdleTaskMemory and vApplicationGetTimerTaskMemory, which provides memory for Ilde task and Timer task. Before these function there's allocated TCB and actuall stacks (see [2])
  • declaration of semaphores for all function blocks from interface view
  • functions which initializes all the threads (see thread.tmplt) with their stacks and queues.
  • the function main, which is actual entry point of the partition. The main function:
    • calls function prvSetupHardware
    • initializes all previously declared samaphores (see xCreateMutexStatic).
    • After hardware initialization the subroutine main calls initialization subroutines for every function block from the Interface View
    • calls previously defined functions which initializes all the tasks
    • calls vTaskStartScheduler.

The subroutine prvSetupHardware initializes oscillators and clocks:

  • oscillator DCO frequency is set to 8 MHz;
  • oscillator LFXTCLK frequency is set to 32768 Hz;
  • clock MCLK uses DCO with divider 1;
  • clock SMCLK uses DCO with divider 1;
  • clock ACLK uses LFXTCLK with divider 1.

msp430_freertos_thread_header and msp430_freertos_thread_body

In few words, these templates generates main subroutines for every thread.

For every thread the following subroutine is created:

void prv_@_Thread_Name_@Task(void* prParameters);

The generated function contains a loop which waits for incomming tasks and calls subroutine to execute the task. If the corespondend function from InterfaceView is cyclic interface then a timer is created. The timer callback function creates a new Task and puts it into the Thread Queue.

msp430_freertos_wrappers_header and msp430_freertos_wrappers_body

These templtes creates following files:

  • build/node/partition/partition_interface.h
  • build/node/partition/partition_interface.h

These files contains: Functions pro_, which are generted for protected interfaces.

void pro_@_Parent_Function_@_@_Name_@

This function is responsible for acquiring and releasing lock on function mutex. See pi.tmplt

Functions vm_

void vm_@_LOWER:Parent_Function_@_@_LOWER:Name_@

Which are responsible for calling required interfaces. For required sporadic interfaces, the task structure is created and then function deliver_to_ is called which is responsible for putting the task into conrespondent queue or passing the task to the device driver.


The functions call_

 void call_@_LOWER:Thread_Name_@ (const char* buf, size_t len)

Which is responsible for acquiring and releasing lock on functions sporadic or cyclic interfaces.


msp430_freertos_transport_body msp430_transport_header

These templates generates following files:

  • build/node/partition/transpor.h
  • build/node/partition/tranport.c

The transport.h contains generated structure MSPAllParameters. This structure is used only to calculate the size of the filed m_data in the structures Request and Message

The structure Request is used to pass task to the task queues in local partition. The structure Message is used to pass task to the sporadic interfaces on remote partition. This structure contains additional field m_port which denotes number of the port.

The file transport.h contains function process_incomming_message which is used by communication device driver to proceed incoming message. Also the device driver should use function register_remote_transport_func which is used to pass the structure Message outside the partition.

For the moment, only one device driver on the msp430 node is supported and only one device driver for MSP430 is created.

In file transport.c the subroutines deliver_to_ are defined. These functions are used to transport the Request to corresponding queue or to the device driver.

The file generated for PolORB deployment.h is used to obtain a port number for remote port.

Also the function process_incoming_message uses enum from deployment.h to decide which thread shoud be used to proceed Message.

msp430_freertos_eusci_a_serial_minimal_header and msp430_freertos_eusci_a_serial_minimal_header

These templates generates following files:

  • build/node/partition/drivers/msp430_eusci_a_serial_minimal/msp430_eusci_a_serial_minimal.c
  • build/node/partition/drivers/msp430_eusci_a_serial_minimal/msp430_eusci_a_serial_minimal.h

These files contains a source code of the communication driver Which uses MSP430 e_USCI_A to provide UART communication with other partitions.

Following functions are defined:

void msp430_eusci_a_serial_minimal_init(void);
void msp430_eusci_a_serial_minimal_poller(void* param);
void msp430_eusci_a_serial_minimal_sender(uint8_t* data, uint32_t length, uint32_t port);

More about device driver in section.

Device drivers

The devices and their drivers are described in file ocarina_components.aadl. This file describes subprograms required by device drivers. The device drivers for MSP430 and FreeRTOS will be implemented independly using driver library for MSP430FR5969.

ocarina_components.aadl

The file ocarina_components.aadl is part of the taste-setup project. On the Taste VM the location of this file is /home/taste/tool-src/install/misc/aadl-library/ocarina_components.aadl.

Adding new bus

To add new bus or implementation of bus add entry to the package ocarina_buses. For the MSP430 the new bus implementation serial.minimal was added.

Ocarina components adding bus.png

Adding new drivers

To add new device add entry to the package ocarina_drivers Fot MSP430 two devices was added.


Ocarina components adding device.png

UART

TBC