liteos semaphore (eight)

1 Overview

1.1 Basic Concepts

Semaphore (Semaphore) is a mechanism to achieve inter-task communication, to achieve mutually exclusive access to critical synchronization between tasks or resources. Commonly used to help a group of tasks competing for access to critical resources.

In a multitasking system, requires synchronization between tasks or implement a mutex to protect critical resources, semaphores can provide this support function for the user.

Typically a count value signal corresponding to an amount effective for the number of resources, the mutex remaining number of resources may be occupied. Meaning the value of the two cases:

  • 0, indicating no accumulated Post operation, and there may be blocking on this semaphore task.
  • Positive value, it indicates that the release operation of one or more Post down.

Semaphore and mutual exclusion semaphore to synchronous for the purpose of use for the purpose of the following differences:

  • When used as a mutex, semaphore creation number postscript is full, the use of critical resources when needed, first take the semaphore, to empty, because it will not get blocked when the semaphore so that other tasks require the use of critical resources, thus ensuring the security of critical resources.
  • When used as a synchronization signal after the amount of created as null, the signal amount of blocked task 1, task 2 after certain conditions occur, releasing the semaphore, the task 1 is then entered RUNNING or READY state, so as to achieve two synchronization between tasks.

1.2 operating mechanism

1.2.1 semaphore control block

/**
* @ingroup los_sem
* Semaphore control structure.
*/
typedef struct
{
    UINT8 usSemStat; /**是否使用标志位*/
    UINT16 uwSemCount; /**信号量索引号*/
    UINT32 usSemID; /**信号量计数*/
    LOS_DL_LIST stSemList; /**挂接阻塞于该信号量的任务*/
}SEM_CB_S;

How it works 1.2.2 Semaphore

Initializing semaphores, for the configuration of the N application memory semaphore (N values ​​can be configured by the user, by memory limitations, see Chapter X configuration reference), and all the unused semaphore is initialized, and is not added to the use the list for system use.

Semaphore creation, semaphore list from unused acquire a semaphore resource, and set the initial value.

Semaphore request, if its counter value is greater than 0, then subtract 1 directly returns success. Otherwise task blocks waiting for the other task releases the semaphore wait timeout can be set. When a task is a blocking semaphore, to the semaphore linked tasks waiting tasks end of the queue.

Semaphore is released, if there is no task waiting for the semaphore is returned directly to the counter is incremented. Otherwise, wake up the semaphore wait for the first task on the task queue.

Semaphore deleted, the amount of signal being used to set the amount of unused signal, and hung back unused list.

Semaphore allows multiple tasks access the same resource at the same time, but will limit the maximum number of tasks the same time access this resource. When the number of tasks access the same resource reaches the maximum number of the resource block other attempts to acquire the resources to task until the task releases the semaphore.

2. Development Guidance

2.1 usage scenarios

Semaphore is a very flexible way synchronization, can be used in a variety of occasions, to achieve lock, synchronization, resource counting and other functions, but also convenient for tasks and task synchronization and interrupt tasks.

2.2 features

Huawei LiteOS signal system modules to provide users with several functions described below.

Functional Classification Interface name description
Semaphore creation and deletion LOS_SemCreate Create Semaphore
- LOS_SemDelete Delete the specified amount of signal
Semaphore application and release LOS_SemPend Application specified semaphore
- LOS_SemPost Release semaphore specified

2.3 Development Process

Semaphore typical development process:

  1. Create Semaphore LOS_SemCreate.
  2. Application semaphore LOS_SemPend.
    There are three modes semaphores application: non-blocking mode, the permanent blocking mode, timing of blocking mode
  • Non-blocking mode: Task need to apply for a semaphore, if the number of tasks currently semaphore semaphore set no upper limit to, the application is successful. Otherwise, the application fails to return immediately
  • Permanent blocking mode: the task need to apply for a semaphore, if the current number of semaphore task is not to limit the semaphore set, the application is successful. Otherwise, the task enters the blocking state, the system switches to the highest priority task ready to continue execution. After the task into the blocking state until some other task releases the semaphore, blocking task will be performed again
  • Timing blocking mode: the task need to apply for a semaphore, if the number of tasks currently semaphore semaphore set no upper limit to, the application is successful. Otherwise, the task enters the blocking state, the system switches to the highest priority task ready to continue execution. After the task into the blocking state, before the specified timeout other task releases the semaphore, or a user specified time expires, blocking task will be performed again
  1. Release the semaphore LOS_SemPost.
  • If there are tasks blocking the specified semaphore, then wake up the semaphore blocking the first task on the queue. The task ready, and scheduling
  • If there is no obstruction to the task specified semaphore, releasing the semaphore success
  1. Delete semaphore LOS_SemDelet

2.4 Semaphore error code

The situation could lead to a semaphore operation to fail, including the creation of a semaphore, the semaphore application, release the semaphore, delete semaphores, etc., are required to return the corresponding error code, in order to quickly locate the cause of the error.

No. definition The actual value description Reference solutions
1 LOS_ERRNO_SEM_NO_MEMORY 0x02000700 Memory space is insufficient Allocate a larger memory partition
2 LOS_ERRNO_SEM_INVALID 0x02000701 Illegal parameter passing Change data transmission to a legal value
3 LOS_ERRNO_SEM_PTR_NULL 0x02000702 Incoming null pointer Incoming legitimate pointer
4 LOS_ERRNO_SEM_ALL_BUSY 0x02000703 Semaphore control block is unavailable Resource release semaphore resource
5 LOS_ERRNO_SEM_UNAVAILABLE 0x02000704 Illegal regular time Incoming correct timing time
6 LOS_ERRNO_SEM_PEND_INTERR 0x02000705 Illegal call during a break LOS_SemPend During the interruption prohibit calls LOS_SemPend
7 LOS_ERRNO_SEM_PEND_IN_LOCK 0x02000706 The task is locked, unable to obtain the semaphore When the task is locked, you can not call LOS_SemPend
8 LOS_ERRNO_SEM_TIMEOUT 0x02000707 Gets semaphore timeout Set in a reasonable time within the range

No Error: the error code is a 32-bit memory cells, 31 to 24 indicate an error level, 23 to 16 indicate an error code flags, 15 to 8 bits represent the error code belongs module 7 ~ 0 indicates an error code number, as follows

#define LOS_ERRNO_OS_NORMAL(MID,ERRNO) \
(LOS_ERRTYPE_NORMAL | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | (ERRNO))
LOS_ERRTYPE_NORMAL :Define the error level as critical
LOS_ERRNO_OS_ID :OS error code flag.
MID:OS_MOUDLE_ID
ERRNO:error ID number

E.g:

LOS_ERRNO_SEM_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x00))

2.5 platform differences

2.6 Considerations

  • Since the interrupts can not be blocked, therefore blocking mode can not be used when the interrupt request signal amount.

3. Programming Example

3.1 Example Description

This example accomplish the following functions;

  1. Testing task Example_TaskEntry create a semaphore lock task scheduling, create two task Example_SemTask1, Example_SemTask2, Example_SemTask2 higher priority than Example_SemTask1, the same semaphore two tasks in the application, two tasks to unlock blocked after task scheduling, task Example_TaskEntry test release semaphore .
  2. Example_SemTask2 obtained signal amount, is scheduled, then task sleeps 20Tick, Example_SemTask2 delay, Example_SemTask1 be awakened.
  3. Example_SemTask1 timed blocking mode application semaphore wait time is 10Tick, because semaphores still held Example_SemTask2, Example_SemTask1 suspended after 10Tick not been semaphores, Example_SemTask1 wake up, tried to apply for permanent blocking mode semaphores, Example_SemTask1 suspended .
  4. After 20Tick Example_SemTask2 wake, after the release of the semaphore, Example_SemTask1 get semaphore is scheduled to run, and finally release the semaphore.
  5. Example_SemTask1 executed, the task Example_TaskEntry wakes up after 40Tick, delete semaphore, delete the two tasks.

3.2 Programming Example

Prerequisites:

  • In los_config.h, the LOSCFG_BASE_IPC_SEM configured to YES.
  • LOSCFG_BASE_IPC_SEM_LIMIT configuring user-defined maximum number of signals, such as 1024.

Code to achieve the following

#include "los_sem.h"
/*任务PID*/
static UINT32 g_TestTaskID01,g_TestTaskID02;
/*测试任务优先级*/
#define TASK_PRIO_TEST 5
/*信号量结构体ID*/
static SEM_HANDLE_T g_usSemID;
VOID Example_SemTask1(void)
{
    UINT32 uwRet;
    printf("Example_SemTask1 try get sem g_usSemID ,timeout 10 ticks.\n");
    /*定时阻塞模式申请信号量,定时时间为10Tick*/
    uwRet = LOS_SemPend(g_usSemID, 10);
    /*申请到信号量*/
    if(LOS_OK == uwRet)
    {
        LOS_SemPost(g_usSemID);
        return;
    }
    /*定时时间到,未申请到信号量*/
    if(LOS_ERRNO_SEM_TIMEOUT == uwRet)
    {
        printf("Example_SemTask1 timeout and try get sem g_usSemID wait forever.\n");
        /*永久阻塞模式申请信号量*/
        uwRet = LOS_SemPend(g_usSemID, LOS_WAIT_FOREVER);
        printf("Example_SemTask1 wait_forever and get sem g_usSemID .\n");
        if(LOS_OK == uwRet)
        {
            LOS_SemPost(g_usSemID);
            return;
        }
    }
    return;
}
VOID Example_SemTask2(void)
{
    UINT32 uwRet;
    printf("Example_SemTask2 try get sem g_usSemID wait forever.\n");
    /*永久阻塞模式申请信号量*/
    uwRet = LOS_SemPend(g_usSemID, LOS_WAIT_FOREVER);
    if(LOS_OK == uwRet)
        printf("Example_SemTask2 get sem g_usSemID and then delay 20ticks .\n");
        /*任务休眠20 Tick*/
        LOS_TaskDelay(20);
        printf("Example_SemTask2 post sem g_usSemID .\n");
        /*释放信号量*/
        LOS_SemPost(g_usSemID);
        return;
}
UINT32 Example_TaskEntry()
{
    UINT32 uwRet;
    TSK_INIT_PARAM_S stTask1;
    TSK_INIT_PARAM_S stTask2;
    /*创建信号量*/
    LOS_SemCreate(0,&g_usSemID);
    /*锁任务调度*/
    LOS_TaskLock();
    /*创建任务1*/
    memset(&stTask1, 0, sizeof(TSK_INIT_PARAM_S));
    stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_SemTask1;
    stTask1.pcName = "MutexTsk1";
    stTask1.uwStackSize = OS_TSK_DEFAULT_STACK_SIZE;
    stTask1.usTaskPrio = TASK_PRIO_TEST;
    uwRet = LOS_TaskCreate(&g_TestTaskID01, &stTask1);
    if(uwRet != LOS_OK)
    {
        printf("task1 create failed .\n");
        return LOS_NOK;
    }
    /*创建任务2*/
    memset(&stTask2, 0, sizeof(TSK_INIT_PARAM_S));
    stTask2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_SemTask2;
    stTask2.pcName = "MutexTsk2";
    stTask2.uwStackSize = OS_TSK_DEFAULT_STACK_SIZE;
    stTask2.usTaskPrio = (TASK_PRIO_TEST - 1);
    uwRet = LOS_TaskCreate(&g_TestTaskID02, &stTask2);
    if(uwRet != LOS_OK)
    {
        printf("task2 create failed .\n");
        return LOS_NOK;
    }
    /*解锁任务调度*/
    LOS_TaskUnlock();
    uwRet = LOS_SemPost(g_usSemID);
    /*任务休眠40 Tick*/
    LOS_TaskDelay(40);
    /*删除信号量*/
    LOS_SemDelete(g_usSemID);
    /*删除任务1*/
    uwRet = LOS_TaskDelete(g_TestTaskID01);
    if(uwRet != LOS_OK)
    {
        printf("task1 delete failed .\n");
        return LOS_NOK;
    }
    /*删除任务2*/
    uwRet = LOS_TaskDelete(g_TestTaskID02);
    if(uwRet != LOS_OK)
    {
        printf("task2 delete failed .\n");
        return LOS_NOK;
    }
    return LOS_OK;
}

3.3 verify the results

The results compiled to run were as follows:

Example_SemTask2 try get sem g_usSemID wait forever.
Example_SemTask1 try get sem g_usSemID ,timeout 10 ticks.
Example_SemTask2 get sem g_usSemID and then delay 20ticks .
Example_SemTask1 timeout and try get sem g_usSemID wait forever.
Example_SemTask2 post sem g_usSemID .
Example_SemTask1 wait_forever and get sem g_usSemID 

Guess you like

Origin www.cnblogs.com/linhaostudy/p/10948357.html