FreeRTOS introductory tutorial (the concept of semaphores and the use of API functions)


Preface

This article officially takes you to learn what a semaphore is, master the basic usage of the semaphore function, and compare it with the queue.

1. What is a semaphore?

Semaphores in FreeRTOS are a mechanism for synchronization and mutual exclusion between tasks. It allows tasks to protect resource access in critical sections, inter-thread communication, and synchronization operations between tasks. Semaphores can be used to protect shared resources, limit concurrent access to resources, and notify events between tasks.

2. Types and comparison of semaphores

FreeRTOS provides two types of semaphores: Binary Semaphore and Counting Semaphore.

二值信号量(Binary Semaphore):

The binary semaphore is the simplest kind of semaphore, it can only have two states: 0 and 1. It is often used for mutually exclusive access to shared resources, such as protecting shared data structures and ensuring that only one task executes a critical section at a time. Tasks can request or release access to shared resources by acquiring or releasing binary semaphores.

创建二值信号量使用 xSemaphoreCreateBinary 函数,并通过 xSemaphoreGive 和 xSemaphoreTake 函数来释放和获取信号量。

计数型信号量(Counting Semaphore):

Counting semaphores can have multiple status values, allowing multiple tasks to access shared resources at the same time, and can be used to control the availability of resources. Counting semaphores are often used to limit the number of concurrent executions of tasks, or in scenarios such as the producer-consumer model between tasks.

创建计数型信号量使用 xSemaphoreCreateCounting 函数,并通过 xSemaphoreGive 和 xSemaphoreTake 函数来增加和减少信号量的计数值。

When using a semaphore, the task attempts to occupy the resource by acquiring the semaphore, and blocks waiting if it fails to acquire it. Once the resource is available or the conditions are met, the task releases the semaphore so that other tasks can obtain the resource or continue execution. This ensures security and correctness of shared resources.

需要注意的是,使用信号量时要小心处理同步和互斥问题,以避免竞态条件和死锁。此外,信号量的使用应该遵循良好的软件设计原则,以避免过度使用和滥用信号量。

二种信号量的对比:

1.功能:

Binary Semaphore: has only two states, 0 and 1. It is mainly used for mutually exclusive access to shared resources, protects shared data structures, and limits concurrent access to resources. Generally used for exclusive operations, try to keep resources exclusive to one task operation.

Counting Semaphore: It can have multiple status values ​​and is used to control the availability of resources. It can be used in scenarios such as limiting the number of concurrent executions and the producer-consumer model between tasks.

2.创建和初始化:

Binary semaphore: It can be created using the xSemaphoreCreateBinary function, initialized using xSemaphoreGive, and calling xSemaphoreTake to obtain the semaphore.
Counting semaphore: You can create it using the xSemaphoreCreateCounting function, initialize it using xSemaphoreGive, and call xSemaphoreTake to obtain the semaphore.

3.值的范围:

Binary semaphore: has two states, 0 and 1. Its value can only be switched from 0 to 1 or from 1 to 0 via xSemaphoreGive and xSemaphoreTake.
Counting semaphore: has a larger range and can count from 0 to a set maximum value.

4.使用场景:

Binary semaphore: Suitable for scenarios of mutually exclusive access to shared resources, such as protecting shared data structures, ensuring that only one task executes critical sections at a time, etc.
Counting semaphore: suitable for scenarios where the number of concurrent executions is controlled, or used in the producer-consumer model between tasks, etc.

3. The difference between semaphores and queues

1.功能:

Semaphore: A semaphore is a mechanism for synchronization and mutual exclusion between tasks. It can be used to protect shared resources, limit concurrent access, control the execution order of tasks, etc. There are two types of semaphores: binary semaphores and counting semaphores.

Queue: A queue is a mechanism for passing data between tasks. It allows tasks to share data in a first-in-first-out (FIFO) order. Tasks can send data to the queue and receive data from the queue. The length of a queue limits the number of data items that can be queued in it.

2.数据传输方式:

Semaphore: Semaphore is generally used for synchronization and mutual exclusion, and does not directly transmit data. Control task access to resources by acquiring and releasing semaphores. The acquisition and release operations of binary semaphores and counting semaphores can be used to represent task events and counts.

Queue: Queue is used to transfer data between tasks. Tasks pass data items from one task to another through send and receive operations. The send operation copies the data item to the queue, and the receive operation copies the data item from the queue into the buffer of the receiving task.

3.数据复制:

Semaphores: Semaphores usually do not involve data copying during data sharing between tasks. They are typically used for access control of resources between tasks rather than actual data transfer. Binary semaphores and counting semaphores control the behavior of tasks by manipulating the count value of the semaphore.

Queue: Queue involves copying data when transferring data between tasks. When a send task sends a data item to a queue, a copy of the data item is stored in the queue. When a receive task receives a data item from the queue, the queue copies a copy of the data item into the receive task's buffer.

4.用途:

Semaphores: Semaphores are very useful in scenarios where tasks need to be synchronized and mutually exclusive. For example, protect shared resources, control concurrent access, event notification of tasks, etc.

Queue: Queue is very useful in scenarios where data needs to be transferred between tasks. For example, implement the producer-consumer model, message passing between tasks, data communication between tasks, etc.

综上所述,信号量主要用于同步和互斥,控制任务对资源的访问。它们不直接传输数据,而是控制任务的行为。队列则用于任务间传递数据,按照先进先出的顺序共享数据项。选择使用信号量还是队列取决于需求,如任务间的数据传输、共享资源的访问控制,以及任务的同步需求。

4. Functions related to semaphores

1.Create a function

创建二值信号量函数:

xSemaphoreCreateBinary function prototype:

SemaphoreHandle_t xSemaphoreCreateBinary( void );

Parameters: None
Return value: SemaphoreHandle_t, a handle to a binary semaphore.

创建计数信号量函数:

xSemaphoreCreateCounting function prototype:

SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount );

Parameters:
uxMaxCount: The maximum count value of the semaphore, that is, the maximum count that can be counted.
uxInitialCount: The initial count value of the semaphore, usually 0.
Return value: SemaphoreHandle_t, a handle to a counting semaphore.

2. Delete function

void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );

Parameters:
xSemaphore: The handle of the semaphore to be deleted.
It should be noted that before deleting a semaphore, please ensure that no tasks are waiting for the semaphore, otherwise undefined behavior may result. Before deleting the semaphore, you can use the uxSemaphoreGetCount function to get the current semaphore count value to ensure that no tasks are waiting.

3. Obtain and release semaphore functions

获取信号量函数:

xSemaphoreGive function prototype:

BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore );

Parameters:
xSemaphore: The handle of the semaphore.
Return value: If the semaphore is successfully released, pdPASS(1) is returned, otherwise pdFAIL(0) is returned.

中断中释放信号量函数:

xSemaphoreGiveFromISR function prototype:

BaseType_t xSemaphoreGiveFromISR( SemaphoreHandle_t xSemaphore, BaseType_t *pxHigherPriorityTaskWoken );

xSemaphore: The handle of the semaphore.
pxHigherPriorityTaskWoken: A pointer to a variable of type BaseType_t that indicates whether a higher priority task was awakened when called in the ISR.
Return value: If the semaphore is successfully released, pdPASS(1) is returned, otherwise pdFAIL(0) is returned.

xSemaphoreGive function prototype:

BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore );

Parameters:
xSemaphore: The handle of the semaphore.
Return value: If the semaphore is successfully released, pdPASS(1) is returned, otherwise pdFAIL(0) is returned.

Summarize

This article mainly explains the concept of semaphore and the use of API functions. After reading it, you can make a summary and conduct corresponding experiments.

Guess you like

Origin blog.csdn.net/m0_49476241/article/details/133618534