跳转到主内容
Knowledgebase
Home
Renesas Electronics China - Knowledgebase

How to run Blinky with a semaphore

Latest Updated:10/04/2016

Overview

This example design illustrates the simple use of a semaphore and two threads to control a blinking LED. This exercise uses brief descriptions of several common actions within the tool flow. This assumes you are somewhat familiar with the various operations within e2 studio. Feel free to 'pop out' of this guide and refresh your understanding of e2 studio operations by referring to the non-threaded example designs that illustrate each step in full step-by-step detail.

Goal

After completing this how-to you will have a better understanding of how to implement a simple semaphore to pass control information between two threads. This will help you to create your own designs using threads and semaphores.

Use each step section to describe the instructions needed to achieve the goal.

Design Description

In this design two threads communicate using a semaphore. One thread does the timing function and generates a shared semaphore once every second. The second thread waits for the semaphore and when it is available, toggles the signal that controls the LED. The simple block diagram below illustrates the overall flow.

Semaphore.PNG

Initial Set-Up

You must first have the Synergy software tool flow installed and a target Synergy board available to see Blinky work in hardware.

Create Your Project

If you followed the previous step you should have the Synergy Platform tool flow working and you should have exercised your target board, most likely with the non-threaded version of Blinky. Now you are ready for a threaded version using two threads and a semaphore.

  1. Open e2 studio and create a new Synergy Project (refer back to the above How To if you need a reminder).
  2. Target your board and select the BSP with Thread-X option.
  3. You should now have familiar a starting point for adding new Blinky code.

Add Semaphore Blinky Code

In this step you will add the code for implementing the semaphore version of Blinky. You will add code to two threads- one thread manages the Timer and one the LED. They communicate using a shared semaphore.

  1. Open the Threads Tab in the Configuration Window.
  2. Click on New to bring up a New Thread. Edit the name to be Timer Thread and the symbol to be timer_thread.
  3. Select Timer Thread in the Threads window and select New> next to the Timer_Thread Objects window. Select Semaphore to add g_new_semaphore Semaphore to the Timer_Thread Objects list.
  4. Click on New next to the Threads window to create another thread and name it LED Thread with a symbol name of led_thread.
  5. Press the Generate Project Content button.
  6. You should now have files called timer_thread_entry.c and led_thread_entry.c.
  7. Open timer_thread_entry.c and replace all the code below the first line in the file with the following code:

#include"timer_thread.h"

void timer_thread_entry (void)

{

while (1)

   {

   tx_semaphore_put (&g_new_semaphore);

   tx_thread_sleep (100);

   }

}

  1. Save the changes to the file.
  2. Replace the code in led_thread_entry.c after the first line in the file with the following code

#include"led_thread.h"

#include"timer_thread.h"

#include<stdio.h>

#include"r_ioport.h"

bsp_leds_t Leds;

void led_thread_entry (void) {

/* Get LED information for this board */

R_BSP_LedsGet(&Leds);

/* If this board has no LEDs then trap here */

if (!Leds.led_count) {

   while(1); // There are no LEDs on this board

   }

ioport_level_t level = IOPORT_LEVEL_HIGH;

while (1) {

   /* Toggle the LED */

   tx_semaphore_get (&g_new_semaphore, TX_WAIT_FOREVER);

   g_ioport_on_ioport.pinWrite(Leds.p_leds[0], level);

   level = !level;

   }

}

  1.  Save all the files and build the debug configuration of your project. It may take a minute or two (or perhaps more) so be patient. Also- it may stay 'stuck' on Build Project (55%) for a while and then finish up all at once. Don't worry if something like that happens on your design.
  2. The design should build without errors. If not, look carefully at your added code.You may have missed or added some characters. When your code builds without errors, you are ready to run semaphore blinky on your target board.

Run Semaphore Blinky on Your Board

  1. Connect your board as you did when running your previous example design.
  2. Initialize the Debugger and select your new project build configuration.
  3. Click the Debug button to bring up the debug perspective.
  4. The debug session will halt at the beginning of the design, so you need to press the Resume button twice to get it to begin execution on your board.
  5. Your LED should now be blinking on and off. It should stay on for 1 second and then go off for 1 second until you pause or stop the debug session.
  6. You have completed your first semaphore design with Synergy!

How Semaphore Blinky Works

Semaphore Blinky begins operation in the threads instead of in hal_entry as you may have noticed in previous examples (such as Hal Blinky). Both LED Thread and Timer Thread are activated at the start of program execution.

Timer Thread controls the delay used to blink the LED. It does this by setting the shared semaphore to allow the LED Thread to toggle the LED signal using the tx_semaphore_put function on the semaphore variable created when the semaphore was added to the Timer Thread during configuration (g_new_semaphore is the default name for the semaphore. The semaphore is defined and created in  timer_thread.c. For a detailed description of how semaphores are used, search for the Semaphore FAQ in the Synergy Knowledge Base). Once the semaphore is 'put', Timer Thread waits for 100 'ticks' (a tick is 10mS so the wait is for 1 sec). The While loop keeps executing so a 'put' is placed every second.

LED Thread begins by finding the first available LED on the board using the BSP function R_BSP_LedsGet. If an LED isn't available the program traps. If an LED is available, execution continues by setting the level of the LED control signal to a high and entering the while loop. Within the while loop the tx_semaphore_get function waits until a semaphore is available (that's what the get function does) using the same variable as the one used in the Timer Thread routine. TX_WAIT_ FOREVER indicates that the function will wait until the semaphore is available and won't 'time out'. Once the semaphore is obtained (remember that the Timer Thread creates a semaphore every second) the g_ioport_on_ioport.pinWrite function is used to write to the LED control signal. Level is then toggled so that the next execution of the while loop will 'flip' the signal driving the LED.

The semaphore used in this example design is often used in threaded applications to communicate between different threads. The semaphore can take on integer values (usually 32 bits) and can thus count resources (such as memory blocks in a queue or peripheral channels) that are shared between multiple threads. It can also be used as a simple communication mechanism, as shown in this example.

Use the section below to describe additional considerations that were omitted for brevity and to guide the reader to further how-to's.

What's Next

Now that you have completed this example design here are some suggestions for building on this exercise to extend your knowledge and skills with the Synergy Platform.

  • Learn more about how to use semaphores in threaded designs by reading the Semaphore chapter in the <ThreadX on Synergy PDF Book>.
  • Learn more about how semaphores are created, accessed and used by reading the <SSP User's Manual>.

 

Please provide feedback on this article if you found it useful or if you have suggestions for improvement by using the feedback buttons below.

  • 这篇文章对您有帮助吗?