FreeRTOS API Semaphore / Mutexes

Started by tha, January 09, 2022, 11:03:11 AM

Previous topic - Next topic

tha

https://www.freertos.org/a00121.html

vSemaphoreCreateBinary
[Semaphores]

semphr. h

vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )

NOTE: The vSemaphoreCreateBinary() macro ยังคงอยู่ใน the source code เพื่อให้แน่ใจว่าเข้ากันได้แบบย้อนหลัง, แต่มันไม่ควรถูกใช้ใน new designs. ใช้ the xSemaphoreCreateBinary() function แทน.

นอกจากนี้ ในหลายกรณี , มันจะเร็วกว่าและ memory มีประสิทธิภาพมากขึ้นเมื่อใช้ a direct to task notification แทนที่ a binary semaphore.

Macro ที่สร้าง a semaphore โดยการใช้ the existing queue mechanism. The queue length เป็น 1 เนื่องจากนี้คือ a binary semaphore. The data size เป็น 0 เนื่องจากเราไม่ต้องการเก็บ data ใดๆจริงๆ - เราเพียงแค่ต้องการทราบว่า the queue ว่างเปล่าหรือเต็ม.

tha

Binary semaphores และ mutexes จะคล้ายกันมากแต่มีความแตกต่างเล็กน้อย: Mutexes รวม a priority inheritance mechanism เอาไว้, binary semaphores ไม่มี. นี้ทำให้ binary semaphores เป็นตัวเลือกที่ดีกว่าสำหรับการจัดให้มีใช้ synchronisation (ระหว่าง tasks หรือระหว่าง tasks and an interrupt), และ mutexes เป็นตัวเลือกที่ดีกว่าสำหรับการจัดให้มีใช้การกันไว้สำหรับคนพิเศษอย่างง่ายๆ (simple mutual exclusion).

A binary semaphore ไม่จำเป็นต้องถูกให้คืนเมื่อได้รับ, ดังนั้น task synchronisation สามารถถูกจัดให้มีใช้โดย one task/interrupt  'ให้' the semaphore อย่างต่อเนื่องในขณะที่อีก task/interrupt หนึ่ง 'เอา' the semaphore อย่างต่อเนื่อง. นี้ถูกสาธิตโดย the sample code บน the xSemaphoreGiveFromISR() documentation page. โปรดทราบว่าฟังชั่นเดียวกันมักจะสามารถถูกทำให้สำเร็จในวิธีที่มีประสิทธิภาพมากกว่าโดยใช้ a direct to task notification.

tha

The priority of a task ที่ 'takes(เอา)' a mutex สามารถถูกทำให้พุ่งขึ้นอย่างมีศักยภาพถ้าอีก task หนึ่งที่มี higher priority พยายามได้รับ the same mutex. The task ที่เป็นเจ้าของ the mutex 'inherits(สืบทอด)' the priority of the task ที่กำลังพยายาม 'take(เอา)' the same mutex. นี้หมายความว่า the mutex ต้องถูก 'given(ให้)' กลับเสมอ - มิฉะนั้น the higher priority task จะไม่สามารถได้รับ the mutex, และ the lower priority task จะไม่ 'disinherit(ละทิ้ง)' the priority. An example of a mutex ที่กำลังถูกใช้เพื่อจัดให้มีใช้ mutual exclusion ถูกจัดให้มีบน the xSemaphoreTake() documentation page.

ทั้ง mutex and binary semaphores ถูกอ้างอิงโดยตัวแปรของชนิด SemaphoreHandle_t และสามารถถูกใช้ใน task level API function ใดๆก็ตามที่เอา a parameter ของชนิดนั้น.

Parameters:

     xSemaphore          Handle to the created semaphore. ควรเป็นของชนิด SemaphoreHandle_t.



tha

https://www.freertos.org/CreateCounting.html

xSemaphoreCreateCounting
[Semaphores]

เคล็ดลับ: 'Task Notifications' สามารถจัดให้มี a light weight alternative แทน counting semaphores ในหลายสถานะการณ์

semphr. h

SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount,
                                            UBaseType_t uxInitialCount);


สร้าง a counting semaphore และส่งคืนกลับ a handle ซึ่ง the newly created semaphore สามารถถูกอ้างอิง. configSUPPORT_DYNAMIC_ALLOCATION ต้องถูกเซ็ตเป็น 1 ใน FreeRTOSConfig.h, หรือทิ้งไว้ไม่กำหนด (ซึ่งในกรณีนี้จะมีค่าเริ่มต้นเป็น 1), สำหรับ RTOS API function นี้มีให้ใช้เป็นประโยชน์.

แต่ละ counting semaphore ต้องการจำนวนน้อยๆของ RAM ที่ถูกใช้เพื่อเก็บ the semaphore's state. ถ้า a counting semaphore ถูกสร้างโดยใช้ xSemaphoreCreateCounting() ดังนั้น RAM ที่ต้องการจะถูกจัดสรรโดยอัตโนมัติจาก the FreeRTOS heap. ถ้า a counting semaphore ถูกสร้างโดยใช้ xSemaphoreCreateCountingStatic() ดังนั้น the RAM ถูกจัดให้มีโดย the application writer, ซึ่งต้องการ parameter เพิ่มเติม, แต่ยอมให้ the RAM ถูกจัดสรรแบบคงที่ที่เวลา compile. ดู the Static Vs Dynamic allocation page สำหรับข้อมูลเพิ่มเติม.

tha

Counting semaphores โดยปกติถูกใช้สำหรับสองสิ่ง:

1. Counting events

ในสถานการณ์การใช้งานนี้ an event handler จะ 'GIVE(ให้)' a semaphore แต่ละครั้งที่ an event เกิดขึ้น (เพิ่ม the semaphore count value), และ a handler task จะ 'TAKE(เอา)' a semaphore แต่ละครั้งที่มันประมวลผล an event (ลด the semaphore count value). The count value จึงเป็นความแตกต่างกันระหว่างจำนวนของ events ที่เกิดขึ้นแล้วและจำนวนที่ถูกประมวลผลแล้ว. ในกรณีนี้ ขอแนะนำให้ค่าการนับเริ่มต้นเป็นศูนย์.

โปรดทราบว่าฟังชั่นเดียวกันนี้มักจะสามารถถูกทำให้สำเร็จด้วยวิธีที่มีประสิทธิภาพมากขึ้นโดยใช้ a direct to task notification.

2. Resource management.

ในสถานการณ์การใช้งานนี้ the count value แสดงจำนวนของ resources ที่มีให้ใช้ประโยชน์. เพื่อให้ได้มาซึ่งการควบคุม a resource a task ต้องได้รับ a semaphore ก่อน - ลด the semaphore count value. เมื่อ the count value ถึงศูนย์จะไม่มี free resources. เมื่อ a task เสร็จสิ้นการใช้ the resource มันจะ 'gives(ให้)' the semaphore กลับ - เพิ่ม the semaphore count value. ในกรณีนี้ขอแนะนำให้  the initial count value เป็นเท่ากับ the maximum count value ซึ่งบ่งชี้ว่าทรัพยากรทั้งหมดนั้นถูกปล่อยฟรี.

tha

Parameters:

     uxMaxCount            The maximum count value ที่สามารถถูกถึง. เมื่อ the semaphore ถึงค่านี้มันไม่สามารถถูก
                                         'given(ให้)' อีกต่อไป.

     uxInitialCount          The count value ที่กำหนดไปยัง the semaphore ตอนที่มันถูกสร้าง.

Returns:

     ถ้า the semaphore ถูกสร้างสำเร็จดังนั้น a handle to the semaphore จะถูกส่งคืนกลับ. ถ้า the semaphore ไม่สามารถถูกสร้าง
     เนื่องจาก the RAM ที่ต้องการเพื่อเก็บ the semaphore ไม่สามารถถูกจัดสรรดังนั้น NULL จะถูกส่งคืนกลับ.


tha

https://www.freertos.org/xSemaphoreCreateCountingStatic.html

xSemaphoreCreateCountingStatic
[Semaphores]

  เคล็ดลับ: 'Task Notifications' สามารถจัดให้มี a light weight alternative แทน counting semaphores ในหลายสถานะการณ์

semphr. h

SemaphoreHandle_t xSemaphoreCreateCountingStatic(
                                 UBaseType_t uxMaxCount,
                                 UBaseType_t uxInitialCount
                                 StaticSemaphore_t *pxSemaphoreBuffer ); );


สร้าง a counting semaphore และส่งคืนกลับ a handle ซึ่ง the newly created semaphore สามารถถูกอ้างอิง. configSUPPORT_STATIC_ALLOCATION ต้องถูกเซ็ตเป็น 1 ใน FreeRTOSConfig.h, หรือทิ้งไว้ไม่กำหนด (ซึ่งในกรณีนี้จะมีค่าเริ่มต้นเป็น 1), สำหรับ RTOS API function นี้มีให้ใช้เป็นประโยชน์.

แต่ละ counting semaphore ต้องการจำนวนน้อยๆของ RAM ที่ถูกใช้เพื่อเก็บ the semaphore's state. ถ้า a counting semaphore ถูกสร้างโดยใช้ xSemaphoreCreateCounting() ดังนั้น RAM ที่ต้องการจะถูกจัดสรรโดยอัตโนมัติจาก the FreeRTOS heap. ถ้า a counting semaphore ถูกสร้างโดยใช้ xSemaphoreCreateCountingStatic() ดังนั้น the RAM ถูกจัดให้มีโดย the application writer, ซึ่งต้องการ parameter เพิ่มเติม, แต่ยอมให้ the RAM ถูกจัดสรรแบบคงที่ที่เวลา compile. ดู the Static Vs Dynamic allocation page สำหรับข้อมูลเพิ่มเติม.

Counting semaphores โดยปกติถูกใช้สำหรับสองสิ่ง:

1. Counting events

ในสถานการณ์การใช้งานนี้ an event handler จะ 'GIVE(ให้)' a semaphore แต่ละครั้งที่ an event เกิดขึ้น (เพิ่ม the semaphore count value), และ a handler task จะ 'TAKE(เอา)' a semaphore แต่ละครั้งที่มันประมวลผล an event (ลด the semaphore count value). The count value จึงเป็นความแตกต่างกันระหว่างจำนวนของ events ที่เกิดขึ้นแล้วและจำนวนที่ถูกประมวลผลแล้ว. ในกรณีนี้ ขอแนะนำให้ค่าการนับเริ่มต้นเป็นศูนย์.

โปรดทราบว่าฟังชั่นเดียวกันนี้มักจะสามารถถูกทำให้สำเร็จด้วยวิธีที่มีประสิทธิภาพมากขึ้นโดยใช้ a direct to task notification.

2. Resource management.

ในสถานการณ์การใช้งานนี้ the count value แสดงจำนวนของ resources ที่มีให้ใช้ประโยชน์. เพื่อให้ได้มาซึ่งการควบคุม a resource a task ต้องได้รับ a semaphore ก่อน - ลด the semaphore count value. เมื่อ the count value ถึงศูนย์จะไม่มี free resources. เมื่อ a task เสร็จสิ้นการใช้ the resource มันจะ 'gives(ให้)' the semaphore กลับ - เพิ่ม the semaphore count value. ในกรณีนี้ขอแนะนำให้  the initial count value เป็นเท่ากับ the maximum count value ซึ่งบ่งชี้ว่าทรัพยากรทั้งหมดนั้นถูกปล่อยฟรี.

Parameters:

     uxMaxCount              The maximum count value ที่สามารถถูกถึง. เมื่อ the semaphore ถึงค่านี้มันไม่สามารถถูก
                                           'given(ให้)' อีกต่อไป.

     uxInitialCount            The count value ที่กำหนดไปยัง the semaphore ตอนที่มันถูกสร้าง.

   pxSemaphoreBuffer   ต้องชี้ไปยังตัวแปรของชนิด StaticSemaphore_t, ซึ่งจากนั้นจะถูกใช้เพื่อเก็บ the semaphore's data
                                           structures.

Returns:

     ถ้า the semaphore ถูกสร้างสำเร็จดังนั้น a handle to the semaphore จะถูกส่งคืนกลับ. ถ้า pxSemaphoreBuffer เป็น NULL
     ดังนั้น NULL จะถูกส่งคืนกลับ.


tha

https://www.freertos.org/CreateMutex.html

xSemaphoreCreateMutex
[Semaphores]

semphr. h

SemaphoreHandle_t xSemaphoreCreateMutex( void )

สร้าง a mutex,  และส่งคืนกลับ a handle ซึ่ง the created mutex สามารถถูกอ้างอิง. Mutexes ไม่สามารถถูกใช้ใน interrupt service routines.

configSUPPORT_DYNAMIC_ALLOCATION ต้องถูกเซ็ตเป็น 1 ใน FreeRTOSConfig.h, หรือทิ้งไว้ไม่กำหนด (ซึ่งในกรณีนี้จะมีค่าเริ่มต้นเป็น 1), สำหรับ RTOS API function นี้มีให้ใช้เป็นประโยชน์.

แต่ละ mutex ต้องการจำนวนน้อยๆของ RAM ที่ถูกใช้เพื่อเก็บ the mutex's state. ถ้า a mutex ถูกสร้างโดยใช้ xSemaphoreCreateMutex() ดังนั้น RAM ที่ต้องการจะถูกจัดสรรโดยอัตโนมัติจาก the FreeRTOS heap. ถ้า a mutex ถูกสร้างโดยใช้ xSemaphoreCreateMutexStatic() ดังนั้น the RAM ถูกจัดให้มีโดย the application writer, ซึ่งต้องการ parameter เพิ่มเติม, แต่ยอมให้ the RAM ถูกจัดสรรแบบคงที่ที่เวลา compile. ดู the Static Vs Dynamic allocation page สำหรับข้อมูลเพิ่มเติม.

Mutexes ถูกเอาโดยใช้ xSemaphoreTake(), และถูกให้โดยใช้ xSemaphoreGive(). xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() สามารถถูกใช้เฉพาะบน mutexes ที่สร้างโดยใช้ xSemaphoreCreateRecursiveMutex().

Binary semaphores และ mutexes จะคล้ายกันมากแต่มีความแตกต่างเล็กน้อย: Mutexes รวม a priority inheritance mechanism เอาไว้, binary semaphores ไม่มี. นี้ทำให้ binary semaphores เป็นตัวเลือกที่ดีกว่าสำหรับการจัดให้มีใช้ synchronisation (ระหว่าง tasks หรือระหว่าง tasks and an interrupt), และ mutexes เป็นตัวเลือกที่ดีกว่าสำหรับการจัดให้มีใช้การกันไว้สำหรับคนพิเศษอย่างง่ายๆ (simple mutual exclusion).