Real time embedded FreeRTOS RSS feed 
Homepage FreeRTOS+ Products FreeRTOS Labs Integration Services Contact / Enquiries

Porting FreeRTOS+UDP to a New Embedded C Compiler


Summary Bullet Points

  • A FreeRTOS+UDP project has two compiler dependencies, as follows:

    1. The syntax used by the compiler to pack structures. This relates directly to the core FreeRTOS+UDP code, and how FreeRTOS+UDP manages this dependency is described below.

    2. The syntax used by the compiler to define an interrupt service routine (ISR). This only relates to ISRs used in Ethernet drivers, not the core core FreeRTOS+UDP code, and is therefore not covered on this page.

  • The syntax required to pack structures is placed in compiler dependent header files to keep it out of the core FreeRTOS+UDP code.

  • Two header files are required for each compiler.

    1. pack_struct_start.h contains any keywords that are required to appear before the definition of a packed structure.

    2. pack_struct_end.h contains any keywords that are required to appear at the end of the definition of packed structure. pack_struct_end.h must also contain the semicolon ( ; ) used to end the structure definition.

  • Existing compiler specific header files are located in sub-directories of FreeRTOS-Plus/FreeRTOS-Plus-UDP/portable/Compiler


Detailed Explanation and Example

The FreeRTOS+UDP implementation uses C structures to map onto the UDP, IP, ARP, DNS and DHCP protocol headers. C compilers normally lay out the memory used to hold a C structure in a way that allows optimal access to the structure's members, and that often results in the internal representation of the structure being padded to achieve optimal byte alignment. For example, consider the following structure defined on a 32-bit microcontroller architecture:



    struct a_struct
    {
        uint8_t Member1;
        uint8_t Member2;
        uint8_t Member3;
        uint32_t Member4;
    }
						
Example C structure definition


The first three members are 8 bits each, and will most likely appear in three consecutive bytes of the same 32-bit word. The forth member is 32-bits, and will probably be most efficiently accessed if it is placed on a 32-bit (four byte) aligned memory address. Therefore the compiler can add a 'padding' byte between Member3 and Member4 to move the start address of Member4 onto a 32-bit boundary. The structure will then map into memory as below:



    struct a_struct
    {
        uint8_t Member1;  At address 0 (first byte of first 32-bit word)
        uint8_t Member2;  At address 1 (second byte of first 32-bit word)
        uint8_t Member3;  At address 2 (third byte of first 32-bit word)
        Padding byte      At address 4 (forth byte of the first 32-bit word)
        uint32_t Member4; Now at address 4, the first byte of the second 32-bit word
    }
						
Example of how the C structure will appear in the microcontroller memory


However, the UDP/IP protocol headers do not have padding bytes, so the compiler must be told not to add them into structures that map onto the protocol headers. Structures that do not contain padding bytes are said to be 'packed'. The syntax required to ensure structures are packed depends on the embedded C compiler. The FreeRTOS+UDP implementation avoids using any compiler specific syntax in the core files, and instead allows users to define their own packing directives in two very simple header files.

Structures that must be packed appear in the FreeRTOS+UDP code as follows:



    #include "pack_struct_start.h"
    struct a_struct
    {
        uint8_t Member1;
        uint8_t Member2;
        uint8_t Member3;
        uint32_t Member4;
    }
    #include "pack_struct_end.h"
						
A structure wrapped in pack_struct_start and pack_struct_end header file inclusions


A version of pack_struct_start.h and pack_struct_end.h that contains compiler specific syntax can then be provided for each compiler.

For example, the directory FreeRTOS-Plus/FreeRTOS-Plus-UDP/portable/Compiler/GCC contains definitions suitable for use with the GCC compiler. pack_struct_start.h is empty because GCC does not require any special syntax at the start of the structure. pack_struct_end.h contains the following single line of code:

    __attribute__( (packed) );
Therefore, after the pre-processor has included the header files, the C compiler sees the code as follows, which is valid GCC syntax for structure packing:


    struct a_struct
    {
        uint8_t Member1;
        uint8_t Member2;
        uint8_t Member3;
        uint32_t Member4;
    }
    __attribute__( (packed) );
						
How GCC sees a packed structure after pack_struct_start.h and pack_struct_end.h have been included

FreeRTOS-Plus/FreeRTOS-Plus-UDP/portable/Compiler/GCC already contains implementations for other compilers that can be used directly, or as a reference when adding new compiler ports.

pack_struct_end.h must, as a minimum, contain at least a semicolon ( ; ) to mark the end of the structure definition. It is sometimes valid for pack_struct_start.h to be empty, but it is never valid for pack_struct_end.h to be completely empty.


[ Back to the top ]    [ About FreeRTOS ]    [ FreeRTOS+ Sitemap ]    [ Main FreeRTOS Sitemap ]    [ ]


Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.