Table of Contents

OSA : Binary semaphores

Introduction

A binary semaphore is a system variable that can contain the value 0 or 1. This is the simplest way of exchanging data between tasks and synchronizing them. All binary semaphores have a size of one bit. The programmer can set the number of binary semaphores by defining the OS_BSEMS constant in OSAcfg.h and the system will allocate the appropriate number of bytes. Therefore memory for binary semaphores is reserved at compile time and their number can't be changed at run time.

.

Identification

When using services controlling binary semaphores it is necessary to provide the semaphore's ID (between 0 and OS_BSEMS-1). It is convenient to assign IDs using enum:

enum OSA_BINSEMS_ENUM
{
    BS_BUTTON_PRESSED,
    BS_USART_FREE,
    BS_WRITE_COMPLETE,
    . . .
};

By using enum we can be sure that each ID is unique.

Using binary semaphores

After system initialization (OS_Init) all binary semaphores are reset. A task which waits for a binary semaphore will be put into a waiting state until the binary semaphore is set.

Here is an example of using a binary semaphore to access a common resource - external EEPROM:

#include <osa.h>
 
enum OSA_BINSEMS_ENUM {
    BS_EEPROM_FREE
};
 
void Task1 (void)
{
    for (;;) {
        ...
        OS_Bsem_Wait(BS_EEPROM_FREE);     // Wait until EEPROM becomes free (unused by other tasks)
                                          // After this service the binary semaphore is reset
                                          // automatically so other tasks will not get this resource.
 
                                          // Here we know that EEPROM is unused by other tasks.
        eeprom_read(1);
        eeprom_read(2);
        OS_Bsem_Set(BS_EEPROM_FREE);      // After using EEPROM we free this resource
        ...
    }
}
 
void Task2 (void)
{
    for (;;) {
        ...
        OS_Bsem_Wait(BS_EEPROM_FREE);     // Wait until EEPROM becomes free (unused by other tasks)
                                          // After this service the binary semaphore is reset
                                          // automatically so other tasks will not get this resource.
 
                                          // Here we know that EEPROM if unused by other tasks.
        eeprom_write(5, 10);
        OS_Delay(5);                      // Wait for the end of write operation.
                                          // When waiting other tasks are executed. But since the
                                          // binary semaphore is reset none of them can start
                                          // to use EEPROM
        eeprom_write(6, 20);
        OS_Delay(5);
        OS_Bsem_Set(BS_EEPROM_FREE);      // After using EEPROM we free this resource
        ...
    }
}

Allocation

You can select which memory bank to allocate binary semaphores in. To do this, you need to set the constant OS_BANK_BSEMS in OSAcfg.h.

Services for binary semaphores

Service Arguments Description Properties
Management
OS_Bsem_Set (bsem) Signal binary semaphore Has alternate service for use in ISR (suffix "_I")
OS_Bsem_Reset (bsem) Reset binary semaphore Has alternate service for use in ISR (suffix "_I")
OS_Bsem_Switch (bsem) Change binary semaphore's state Has alternate service for use in ISR (suffix "_I")
Checking
OST_WORD
OS_Bsem_Check
(bsem) Check if binary semaphore is set Has alternate service for use in ISR (suffix "_I")
Waiting
OS_Bsem_Wait (bsem) Wait for binary semaphore to be set Allowed only in taskSwitches context
OS_Bsem_Wait_TO (bsem, timeout) Wait for binary semaphore to be set. Exit if timeout expired Allowed only in taskSwitches contextService uses system timer