element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Personal Blogs
  • Community Hub
  • More
Personal Blogs
Legacy Personal Blogs Switch from TI-RTOS to SimpleLink POSIX: Threads and Semaphores
  • Blog
  • Documents
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Jan Cumps
  • Date Created: 5 May 2018 3:46 PM Date Created
  • Views 3253 views
  • Likes 7 likes
  • Comments 11 comments
  • firmware
  • msp432
  • ti-rtos
  • launchpad
  • code_composer_studio
  • posix
Related
Recommended

Switch from TI-RTOS to SimpleLink POSIX: Threads and Semaphores

Jan Cumps
Jan Cumps
5 May 2018

A real world migration from TI-RTOS to the POSIX API of TI SimpleLink.

Texas Instruments migrated from the proprietary TI-RTOS to the open POSIX API.

I'm migrating a project that extensively used the TI paradigms to that POSIX API. You're my witness.

image

The blog assumes that you are a TI-RTOS user and want to adapt to the new ways of working.

 

POSIX is an open API that defines how threads can be used. It also deals with common multi-thread topics like sharing (or reserving) resources, scheduling, priorities, and what have you.

I'm using the POSIX API to program the firmware of a Programmable Electronic Load. In fact, I'm porting the firmware from TI-RTOS to POSIX. You can follow along.

 

Side note: TI's move to SimpleLink from TI-RTOS

If you've never used TI-RTOS and its APIs, this blog is not for you. Just dive into SimpleLink and learn it.

If you've been using TI-RTOS, you can learn how the concepts of its API are handled now in SimpleLink.

 

When TI switched to SimpleLink, their RTOS approach underwent a significant overhaul.

Before SimpleLink, the RTOS was TI-RTOS centric. All examples used that APIs, it was an integral part of CCS and there was a GUI to configure tasks, semaphores, mailboxes and events.

In the new approach, SimpleLink uses the POSIX API. Under the hood, TI-RTOS or FreeRTOS can do the work. Your code doesn't need to know.

You win some, you loose some. For POSIX savvy people, this is a win. No need to learn a new RTOS. And POSIX is a standard. Adapting to standards is great.

I do have some gripes with it: the integration with CCS, where a separate project is created for the RTOS, feels hacky. And we lost the great GUI where you can declare tasks, mailboxes, semaphores, events.

Both things could be addressed if TI would put some effort into this. But I'm over that. I'm now porting the Programmable Electronic Load that we're designing here to SimpleLink image.

 

disclaimer: I'm human. Any change to a trusted and known approach results in resistance at first. The main reason why I waited to adapt the DC Load is because the pre-production LaunchPad that I used for the DC Load didn't support the latest SimpleLink releases. Not the things above. I tried to switch before but ran into (documented!) incompatibility issues with that pre-production LaunchPad.

 

Exercice 1: Threads

 

A TI-RTOS task turns into a POSIX thread. In the original firmware for the electronic load, I used the RTOS GUI to configure them.

In the POSIX paradigm, you declare and create them in code.

 

The heartbeat thread described here is a low priority job that will blink a LED on the LaunchPad. It helps to visually check the health of the RTOS while developing.

Any activity that impacts the bandwidth to run jobs regularly is easy spotted because the LED's rhythm gets disrupted. That's something that can be spotted by just looking at the board.

 

At the startup of the firmware, before the RTOS is started, The tasks are created.

note: BIOS_start() is TI-RTOS specific.

 

    /* Set priority and stack size attributes */
    pthread_attr_init(&attrs);
    priParam.sched_priority = 1;


    detachState = PTHREAD_CREATE_DETACHED;
    retc = pthread_attr_setdetachstate(&attrs, detachState);
    if (retc != 0) {
        /* pthread_attr_setdetachstate() failed */
        while (1);
    }


    pthread_attr_setschedparam(&attrs, &priParam);


    retc |= pthread_attr_setstacksize(&attrs, THREADSTACKSIZE);
    if (retc != 0) {
        /* pthread_attr_setstacksize() failed */
        while (1);
    }

    retc = pthread_create(&thread, &attrs, threadHeartBeat, NULL);
    if (retc != 0) {
        /* pthread_create() failed */
        while (1);
    }
// initiate shared hardware modules only. The ones dedicated to a task are initiated in that task
    GPIO_init();




    BIOS_start();

 

The thread has the same look and feel as the TI-RTOS task. You initialise the work to be done, then loop and sleep.

I still have to turn that sleep time into something that is centrally gouverned (together with priority), so that I don't loose view on what's running when.

I could pass it in arg0, but for the moment I'm planning to use just a header file where each thread's signature, sleep time and priority is defined (discuss if you think this can be done better).

 

 

/*
 *  ======== threadHeartBeat ========
 */
void *threadHeartBeat(void *arg0)
{
    /* 1 second delay */
    uint32_t time = 1;


    /* Call driver init functions */


    /* Configure the LED pin */
    GPIO_setConfig(Board_GPIO_LED0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);


    /* Turn on user LED */
    GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);


    while (1) {
        sleep(time);
        GPIO_toggle(Board_GPIO_LED0);
    }
}

 

This is an easy migration. I didn't expect complexities here because I've done this before in both FreeRTOS and TI-RTOS, both without the POSIX API.

Also, it's the main chunk of the SimpleLink RTOS "empty" example.

 

Exercice 2: UART , Triggers and Semaphores

 

I'm starting with the UART interface because it uses some interesting RTOS structures: interrupt driven IO and semaphores.

 

image

 

The task to read the UART is interrupt driven. Our task always sleeps and only wakes up when a character arrives at the USB Rx line.

We use a binary semaphore for that - one that always blocks unless a process (in our case, serial in interrupt) posts to that semaphore.

 

sem_t SEM_uart_rx; // this binary semaphore handles uart receiving interrupts

 

The semaphore gets initialised at the start of the UART task:

 

    iError = sem_init(&SEM_uart_rx, 0, 0);

 

Then, in that task's while loop, the process blocks on that binary semaphore and goes to sleep. Check the sem_wait() call.

 

   /* Loop forever echoing */
    while (1) {
        UART_read(uart, &input, 1);
        iError = sem_wait(&SEM_uart_rx); // when a character is received via UART, the interrupt handler will release the binary semaphore
        while (iError) {
            // POSIX reported error with semaphore. Can't recover.
        }
        // in my case: I get an interrupt for a single character, no need to loop.
        scpi_instrument_input((const char *)&input, 1);
    }

 

The task will sleep until someone wakes up the semaphore. The UART data receive interrupt will do that:

 

void UART00_IRQHandler(UART_Handle handle, void *buffer, size_t num)
{
    sem_post(&SEM_uart_rx);
}

 

This task does not have a sleep() call, because it isn't scheduled. The semaphore construct makes it reactive (and very cheap on resources while waiting).

The whole construct (including the registration of the read interrupt handler) looks like this:

 

void *threadUART(void *arg0)
{
    char        input;
    UART_Params uartParams;
    int iError;


    /* Call driver init functions */
//    GPIO_init();
    UART_init();


    /* Configure the LED pin */
    GPIO_setConfig(Board_GPIO_LED0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);


    /* Create a UART with data processing off. */
    UART_Params_init(&uartParams);
    uartParams.writeDataMode = UART_DATA_BINARY;
    uartParams.readDataMode = UART_DATA_BINARY;
    uartParams.readReturnMode = UART_RETURN_FULL;
    uartParams.readEcho = UART_ECHO_OFF;
    uartParams.baudRate = 9600;
    uartParams.readMode = UART_MODE_CALLBACK; // the uart uses a read interrupt
    uartParams.readCallback = &UART00_IRQHandler; // function called when the uart interrupt fires

    uart = UART_open(Board_UART0, &uartParams);

    if (uart == NULL) {
        /* UART_open() failed */
        while (1);
    }


    iError = sem_init(&SEM_uart_rx, 0, 0);

    /* Loop forever echoing */
    while (1) {
        UART_read(uart, &input, 1);
        iError = sem_wait(&SEM_uart_rx); // when a character is received via UART, the interrupt handler will release the binary semaphore
        while (iError) {
            // POSIX reported error with semaphore. Can't recover.
        }
        // in my case: I get an interrupt for a single character, no need to loop.
        scpi_instrument_input((const char *)&input, 1);
    }
}

 

Writing to UART hasn't changed from the original TI-RTOS implementation, because that's not using interrupts and only has dependencies on the TI Driver lib.

 

The task is created exactly the same as the heartbeat one:

 

    retc = pthread_create(&thread, &attrs, threadUART, NULL);
    if (retc != 0) {
        /* pthread_create() failed */
        while (1);
    }

 

I'll have to port all of the electronic load tasks. Most of that exercise will be a repeat from what you see in this post.

The exception is those locations where I use a mailbox to send info between tasks (and wait on traffic on the mailboxes).

I'll have to do some investigation first before I can do that. But if it's as easy as porting the threads and semaphores, I have good hope.

 

Related Blog
Switch from TI-RTOS to SimpleLink POSIX: Threads and Semaphores
Switch from TI-RTOS to SimpleLink POSIX: EEPROM API

Switch from TI-RTOS to SimpleLink POSIX: From MailBox to Message Queue

Switch from TI-RTOS to SimpleLink POSIX: LCD Display Driver
Switch from TI-RTOS to SimpleLink POSIX: Sleep when Idle
  • Sign in to reply

Top Comments

  • shabaz
    shabaz over 7 years ago +3
    Hi Jan, great post. SimpleLink is awesome : ) I only briefly got to explore it a while back (with a CC3200 device) but it really makes it friendly to develop with, knowing the APIs are so similar to working…
  • DAB
    DAB over 7 years ago +2
    Nice post. I wondered what was the advantage of Simplelink so I am very interested to see what happens. DAB
  • Jan Cumps
    Jan Cumps over 7 years ago in reply to fmilburn +2
    fmilburn wrote: Do you have any thoughts on TI-RTOS vs FreeRTOS underneath? I have no opinion on what's the best choice. I've developed with both RTOSes and have no preference. I like them both.
  • Jan Cumps
    Jan Cumps over 7 years ago

    I've added a second topic: writing and reading persistent (calibration) data: Switch from TI-RTOS to SimpleLink POSIX: EEPROM API

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • jomoenginer
    jomoenginer over 7 years ago in reply to Jan Cumps

    Jan,

     

    I had seen the move to POSIX as more of an option, but it certainly opens up many other options.  My comment regarding Android and such was more forward looking.  Perhaps TI is considering expanding to other processors such as the Sitara AM series or other line of processors.

     

    I look forward to seeing how you progress with this.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps over 7 years ago in reply to jomoenginer

    jomoenginer  wrote:

     

    Jan,

    Very cool.  It will be interesting to see how you progress with this.

     

    However, to understand this, you are not just dumping TI-RTOS for POSIX, but rather just moving up another level of abstraction above the RTOS implementation and use the POSIX APIs from the TI SimpleLink SDK, correct?  It does appear that TI has not implement all of the POSIX APIs and there are some limitations with FreeRTOS so that should be interesting.

     

    I wonder if this opens the door for someone to use another POSIX compliant OS such as Android, Nucleus, or Contiki with SimpleLink SDK in the future?

     

    For someone looking into this, it might be wise to understand the underlying RTOS that is used or at least the interaction between the POSIX API and the RTOS Kernel just in case something in the TI implementation is not completely ironed out. This would help with debugging as well.

    TI has moved to POSIX as the layer of choice. I’m adapting my firmware to that.

     

    yes, it’s a layer above the RTOS. You can still use the RTOS in a classic way (true for both TI-RTOS and FreeRTOS.

     

    I’m using the typical RTOS constructs, such as semaphores, threads and messages. They are all implemented. FreeRTOS has a limitation with functionality that I don’t use.

     

    Android may be a stretch, the SimpleLink range of controllers doesn’t have the oomph to run an OS.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • jomoenginer
    jomoenginer over 7 years ago

    Jan,

    Very cool.  It will be interesting to see how you progress with this.

     

    However, to understand this, you are not just dumping TI-RTOS for POSIX, but rather just moving up another level of abstraction above the RTOS implementation and use the POSIX APIs from the TI SimpleLink SDK, correct?  It does appear that TI has not implement all of the POSIX APIs and there are some limitations with FreeRTOS so that should be interesting.

     

    I wonder if this opens the door for someone to use another POSIX compliant OS such as Android, Nucleus, or Contiki with SimpleLink SDK in the future?

     

    For someone looking into this, it might be wise to understand the underlying RTOS that is used or at least the interaction between the POSIX API and the RTOS Kernel just in case something in the TI implementation is not completely ironed out. This would help with debugging as well. 

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps over 7 years ago in reply to fmilburn

    fmilburn  wrote:

     

    Do you have any thoughts on TI-RTOS vs FreeRTOS underneath?   

    I have no opinion on what's the best choice. I've developed with both RTOSes and have no preference. I like them both.

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • More
    • Cancel
>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube