FreeRTOS API Semaphore / Mutexes

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

Previous topic - Next topic

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.

ตัวอย่างของ a mutex ที่ถูกใช้เพื่อจัดให้มีใช้ mutual exclusion ถูกจัดให้มีบน the xSemaphoreTake() documentation page.

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.

Handles สำหรับทั้ง mutexes and binary semaphores ถูกกำหนดไปยังตัวแปรของชนิด SemaphoreHandle_t, และสามารถถูกใช้ใน any task level (เนื่องจากตรงข้ามกับ interrupt safe) API function ที่ใช้ a parameter ของชนิดนั้น.

Returns:

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


tha

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

xSemaphoreCreateMutexStatic
[Semaphores]

semphr. h

SemaphoreHandle_t xSemaphoreCreateMutexStatic(
                            StaticSemaphore_t *pxMutexBuffer );


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

configSUPPORT_STATIC_ALLOCATION ต้องถูกเซ็ตเป็น 1 ใน FreeRTOSConfig.h, สำหรับ 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).

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.

ตัวอย่างของ a mutex ที่ถูกใช้เพื่อจัดให้มีใช้ mutual exclusion ถูกจัดให้มีบน the xSemaphoreTake() documentation page.

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.

Handles สำหรับทั้ง mutexes and binary semaphores ถูกกำหนดไปยังตัวแปรของชนิด SemaphoreHandle_t, และสามารถถูกใช้ใน any task level (เนื่องจากตรงข้ามกับ interrupt safe) API function ที่ใช้ a parameter ของชนิดนั้น.

Parameters:

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

Returns:

     ถ้า the mutex type semaphore ถูกสร้างสำเร็จดังนั้น a handle to the created mutex จะถูกส่งคืนกลับ. ถ้า the mutex ไม่ถูก
     สร้างเนื่องจาก pxMutexBuffer เป็น NULL ดังนั้น NULL จะถูกส่งคืนกลับ.


tha

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

xSemaphoreCreateRecursiveMutex
[Semaphores]

semphr. h

SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void )

สร้าง a recursive mutex, และส่งคืนกลับ a handle ซึ่ง the mutex สามารถถูกอ้างอิง. Recursive mutexes ไม่สามารถถูกใช้ใน interrupt service routines. configSUPPORT_DYNAMIC_ALLOCATION and configUSE_RECURSIVE_MUTEXES ทั้งคู่ต้องถูกเซ็ตเป็น 1 ใน FreeRTOSConfig.h สำหรับ xSemaphoreCreateRecursiveMutex() นี้มีให้ใช้เป็นประโยชน์. (configSUPPORT_DYNAMIC_ALLOCATION สามารถถูกทิ้งไว้ไม่กำหนดได้อีกด้วย (ซึ่งในกรณีนี้จะมีค่าเริ่มต้นเป็น 1).

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

Recursive mutexes  ถูก 'taken(เอา)' (ได้รับ) โดยใช้ the xSemaphoreTakeRecursive() และถูกให้ (ปลดปล่อย) โดยใช้ the xSemaphoreGiveRecursive() API functions ตามลำดับ. xSemaphoreTake() and xSemaphoreGive() ต้องไม่ถูกใช้.


tha

Non-recursive mutexes ถูกสร้างโดยใช้ xSemaphoreCreateMutex() and xSemaphoreCreateMutexStatic(). A non-recursive mutex สามารถถูก 'เอา(taken)' ได้โดย a task เพียงครั้งเดียว. ความพยายามใดๆโดย a task เพื่อเอา a non-recursive mutex ที่มันถูกยึดแล้วจะล้มเหลว - และ the mutex จะถูกให้กลับในครั้งแรกที่ the task 'ให้'  the mutex.

ตรงกันข้ามกับ non-recursive mutexes, a task สามารถ 'take' a recursive mutex ได้หลายครั้ง, และ the recursive mutex จะถูกส่งคืนกลับเฉพาะหลังจาก the holding task  'given(ให้)' the mutex ในจำนวนครั้งเท่ากันที่มัน 'took(เอา)' the mutex.

tha

เหมือน non-recursive mutexes, recursive mutexes จัดให้มีใช้ a priority inheritance algorithm. 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.

Returns:

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


tha

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

xSemaphoreCreateRecursiveMutexStatic
[Semaphores]

semphr. h

SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic(
                              StaticSemaphore_t *pxMutexBuffer )


สร้าง a recursive mutex, และส่งคืนกลับ a handle ซึ่ง the mutex สามารถถูกอ้างอิง. Recursive mutexes ไม่สามารถถูกใช้ใน interrupt service routines. configUSE_RECURSIVE_MUTEXES และ configSUPPORT_STATIC_ALLOCATION ทั้งคู่ต้องถูกเซ็ตเป็น 1 ใน FreeRTOSConfig.h สำหรับ xSemaphoreCreateRecursiveMutexStatic() นี้มีให้ใช้เป็นประโยชน์.

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

Recursive mutexes  ถูก 'taken(เอา)' (ได้รับ) โดยใช้ the xSemaphoreTakeRecursive() และถูกให้ (ปลดปล่อย) โดยใช้ the xSemaphoreGiveRecursive() API functions ตามลำดับ. xSemaphoreTake() and xSemaphoreGive() ต้องไม่ถูกใช้.

Non-recursive mutexes ถูกสร้างโดยใช้ xSemaphoreCreateMutex() and xSemaphoreCreateMutexStatic(). A non-recursive mutex สามารถถูก 'เอา(taken)' ได้โดย a task เพียงครั้งเดียว. ความพยายามใดๆโดย a task เพื่อเอา a non-recursive mutex ที่มันถูกยึดแล้วจะล้มเหลว - และ the mutex จะถูกให้กลับในครั้งแรกที่ the task 'ให้'  the mutex.

ตรงกันข้ามกับ non-recursive mutexes, a task สามารถ 'take' a recursive mutex ได้หลายครั้ง, และ the recursive mutex จะถูกส่งคืนกลับเฉพาะหลังจาก the holding task  'given(ให้)' the mutex ในจำนวนครั้งเท่ากันที่มัน 'took(เอา)' the mutex.

เหมือน non-recursive mutexes, recursive mutexes จัดให้มีใช้ a priority inheritance algorithm. 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.

Parameters:

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

Returns:

     ถ้า the recursive mutex ถูกสร้างสำเร็จดังนั้น a handle to the created mutex จะถูกส่งคืนกลับ. ถ้า the recursive mutex ไม่
     ถูกสร้างเนื่องจาก pxMutexBuffer เป็น NULL ดังนั้น NULL จะถูกส่งคืนกลับ.



tha

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

xSemaphoreGetMutexHolder
[Semaphores]

semphr. h

TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex );

INCLUDE_xSemaphoreGetMutexHolder ต้องถูกเซ็ตเป็น 1 ใน FreeRTOSConfig.h สำหรับฟัชชั่นนี้มีให้ใช้เป็นประโยชน์.

ส่งคืนกลับ the handle of the task ที่เก็บ the mutex ที่ระบุโดย the function parameter, หากมี.

xSemaphoreGetMutexHolder() สามารถถูกใช้อย่างน่าเชื่อถือเพื่อตรวจสอบว่า the calling task เป็น the mutex holder หรือไม่, แต่ไม่สามารถถูกใช้ได้อย่างน่าเชื่อถือถ้า the mutex ถูกยึดโดย task อื่นนอกเหนือจาก the calling task. นี้เนื่องจาก the mutex holder อาจเปลี่ยนระหว่าง the calling task ที่กำลังเรียก the function, และ the calling task ที่กำลังทดสอบ the function's return value.

configUSE_MUTEXES ต้องถูกเซ็ตเป็น 1 ใน FreeRTOSConfig.h สำหรับ xSemaphoreGetMutexHolder() มีให้ใช้เป็นประโยชน์.

Parameters:
     
     xMutex          The handle of the mutex ที่กำลังถูกสอบถาม.

Returns:

     The handle of the task ที่ยึด the mutex ที่ระบุโดย the xMutex parameter. NULL ถูกส่งคืนกลับถ้า the semaphore ที่ส่ง
     ผ่านใน the xMutex parameter ไม่ใช่ a mutex type semaphore, หรือถ้า the mutex มีให้ใช้เป็นประโยชน์และดังนั้นไม่ถูกยึด
     โดย task ใดๆ.

tha

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

uxSemaphoreGetCount
[Semaphores]

semphr. h

UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );
   
ส่งคืนกลับจำนวนของ a semaphore.

Parameters:

     xSemaphore     The handle of the semaphore ที่กำลังถูกสอบถาม.

Returns:

     ถ้า the semaphore เป็น a counting semaphore ดังนั้น the semaphores current count value ถูกส่งคืนกลับ. ถ้า the
     semaphore เป็น a binary semaphore ดังนั้น 1 ถูกส่งคืนกลับถ้า the semaphore มีให้ใช้เป็นประโยชน์, และ 0 ถูกส่งคืนกลับถ้า
     the semaphore ไม่มีให้ใช้เป็นประโยชน์.