Developing mbed applications with RTX and Visual Studio

This tutorial shows how to use the Keil RTX real-time operating system to create multi-threaded embedded applications with mbed and VisualGDB. Before you begin, install VisualGDB 5.1 or later and update your embedded tools via Embedded Tool Manager.

  1. Start Visual Studio and begin creating a new project with the VisualGDB Embedded Project Wizard:01-rtxdemo
  2. On the first page select “Create a new project” and ensure that the “Enable multi-threaded build” checkbox is checked:02-newbin
  3. Click “Use ARM mbed” and select your mbed board in the device list. In this tutorial we will use the STM32F4Discovery board (DISCO_F407VG). Ensure you have newlib-nano selected as the C library:03-device
  4. On the sample selection page select “LEDBlink (RTOS)” to create a project with RTOS support:04-rtos
  5. On the Debug Settings page select your debug method. If you are using Segger J-Link or a device that can be programmed with firmware from segger, use the J-Link debug method, otherwise use OpenOCD:05-debug
  6. Press “Finish” to generate your project. Build it via Build->Build Solution:06-build
  7. Start debugging by pressing F5. See how the 2 LEDs blink with different periods as 2 independent threads are controlling them. Set a breakpoint on the line modifying the value of g_LED1 and wait for it to trigger:07-breakpoint
  8. The line gets the current state of the LED, inverts it and sets the new state. Step into the operator that sets the new state by selecting Step Into Specific -> operator=(int):08-stepin
  9. Step into the write() method function and  into the gpio_write() function again to see what exactly happens when the new value is assigned to g_LED1:09-write
  10. Now we will modify our source code to demonstrate communication between the 2 threads. Replace the contents of your main file with this:
    #include <mbed.h>
    #include <rtos.h>
     
    DigitalOut g_LED1(LED1);
    DigitalOut g_LED2(LED2);
    Semaphore g_Semaphore(0);
     
    static void ThreadBody(const void *) 
    {
        for (;;)
        {
            g_LED1 = 0;
            g_Semaphore.wait();
            g_LED1 = 1;
            Thread::wait(100);
        }
    }
     
    int main()
    {
        Thread thread(ThreadBody);
        for (;;)
        {
            g_LED2 = !g_LED2;
            g_Semaphore.release();
            Thread::wait(300);
        }
    }

    This will create a global semaphore that will be signaled each time the main thread inverts the second LED. The background thread will wait for the signal and do a short pulse on the first LED when it receives it.

  11. Build and run your program:10-runObserve how the first LED pulses quickly each time the second one changes state.
  12. You can step into the RTOS methods (e.g. Semaphore::wait()) by pressing F11. As your project includes all necessary mbed code, you can easily step through it and even modify it: 11-sema