5.5.11 · D5 · HinglishEmbedded Systems & Real-Time Software

Question bankFreeRTOS IPC — queues, semaphores, mutexes, event groups

1,754 words8 min read↑ Read in English

5.5.11 · D5 · Coding › Embedded Systems & Real-Time Software › FreeRTOS IPC — queues, semaphores, mutexes, event groups


True or false — justify

Neeche har statement ya toh subtly sahi hai ya subtly galat. Dekhne se pehle kyun bolo.

A queue hamesha manually copying se zyada fast data transfer karta hai, kyunki kernel optimized hai.
False — ek queue bytes copy karta hai bilkul waise hi jaise aap karte, plus list bookkeeping aur ek critical section add hoti hai. Iska value safety aur blocking hai, raw speed nahi.
Ek binary semaphore aur ek mutex interchangeable hain kyunki dono "count of 1" hain.
False — woh counter mechanism share karte hain lekin ek mutex ke paas owner aur priority inheritance hoti hai; binary semaphore mein dono nahi hote, isliye sirf mutex hi lock ke taur par safe hai.
Ek counting semaphore ko utni baar give kiya ja sakta hai jitni baar take kiya gaya.
True — Give sirf counter ko uske max tak increment karta hai; aap ise pre-load kar sakte hain ya events accumulate hone de sakte hain. Woh "surplus count" exactly wahi hai jisse yeh un events ko yaad rakhta hai jo tab aaye jab task busy tha.
xQueueSend ek full queue par xTicksToWait = 0 ke saath error return karta hai block karne ki bajaye.
True — zero timeout matlab hai "try karo, lekin kabhi sleep mat karo." Yeh turant pdFALSE (errQUEUE_FULL) return karta hai, jo correct non-blocking pattern hai.
Ek event group ek single bit-set operation se kai tasks ko wake kar sakta hai.
True — kyunki tasks bits par wait karte hain, ek bit set karna kai blocked tasks ke wait-mask ko satisfy kar sakta hai ek saath, isliye yeh broadcast karta hai. Ek semaphore ka Give sirf ek taker ko wake karta hai.
Priority inheritance permanently low-priority task ki priority raise kar deti hai.
False — boost temporary hai; jis waqt low task mutex release karta hai, kernel uski original priority restore kar deta hai.
Ek mutex ko same task dwara koi bhi number of times recursively liya ja sakta hai bina deadlock ke (FreeRTOS mein).
Sirf ek recursive mutex (xSemaphoreCreateRecursiveMutex) ke liye True hai. Apne owner dwara do baar liya gaya plain mutex us task ko khud par hi deadlock kar deta hai.
Queue ke through pointer bhejna hamesha galat hota hai.
False — yeh bade payloads ke liye ek legitimate pattern hai, besharte aap ownership explicitly transfer karein (sender ise touch karna band kar de, receiver ise free kare). Trap ek dangling pointer hai agar lifetimes manage nahi ki gayi.

Spot the error

Har snippet ya claim mein ek defect hai. Use naam do aur fix do.

xSemaphoreTake(mutex, portMAX_DELAY) ek ISR ke andar call kiya gaya shared buffer lock karne ke liye.
Do errors hain: ISRs block nahi kar sakte (no portMAX_DELAY) aur mutexes ka ISR mein koi matlab nahi (no owner). Signal karne ke liye ek ...FromISR semaphore use karo, aur locking ek task mein karo.
Ek task xSemaphoreTake(m,…) karta hai, aur baad mein ek alag task usi mutex par xSemaphoreGive(m) karta hai.
Ek mutex sirf us task dwara wapas diya ja sakta hai jisne use liya tha. Yeh "kahin aur se give karo" pattern ownership violate karta hai — agar aap sach mein alag tasks ke beech hand-off chahte hain toh binary semaphore use karo.
xQueueSend(q, v, …) jahan v ek uint32_t value hai (na ki &v).
Send ek pointer to the item to copy leta hai, isliye aapko &v pass karna hoga. Value pass karna number ko ek address ki tarah reinterpret karta hai aur garbage copy karta hai.
Ek ISR xSemaphoreGiveFromISR(sem, &woke) call karta hai lekin kabhi portYIELD_FROM_ISR(woke) call nahi karta.
Higher-priority woken task tab tak nahi chalega jab tak agla scheduler tick nahi aata, latency add hoti hai. woke flag ko ISR exit par turant ek context switch trigger karna chahiye.
xEventGroupWaitBits(eg, MASK, pdFALSE, pdTRUE, …) ek loop mein use kiya gaya jo har cycle mein fresh triggers expect karta hai.
Clear-flag ke liye pdFALSE bits ko set rehne deta hai, isliye wait har loop mein stale bits par turant return karta hai. Edge-style events ke liye exit par auto-clear ke liye pdTRUE use karo.
Ek "lock" implement kiya gaya: while(flag) {} flag = 1; …; flag = 0; har task mein, koi kernel object nahi.
Check-and-set atomic nahi hai — flag read karne aur set karne ke beech ek preemption do tasks dono ko enter hone deta hai. Yeh wahi race condition hai jise IPC objects eliminate karne ke liye exist karte hain; ek mutex use karo.

Why questions

"What" nahi, "why" answer karo.

Queue default roop se sender ka pointer store karne ki bajaye by value copy kyun karta hai?
Kyunki sender ki local variable out of scope ja sakti hai ya override ho sakti hai jis pal use preempt kiya jaata hai. Copying message ko self-contained aur lifetime-safe banata hai.
Semaphore ko "itemSize = 0 wali queue" kyun kaha jaata hai?
FreeRTOS literally queue code reuse karta hai: Give ≡ Send with no data, Take ≡ Receive with no data, aur count present zero-byte items ki sankhya hai. Ek implementation, do faces.
ISRs ko ...FromISR API variants kyun use karni chahiye?
Regular APIs block kar sakti hain, aur ek ISR ke paas block/reschedule karne ka koi task context nahi hota — wahan block karna system ko freeze kar deta. FromISR variants kabhi block nahi karte aur woke flag ke zariye needed yield report karte hain.
Mutex unbounded priority inversion kyun prevent karta hai lekin binary semaphore nahi?
Sirf mutex ek owner record karta hai, isliye kernel jaanta hai kise boost karna hai. Yeh low-priority holder ko temporarily waiter ki priority tak lift karta hai taaki ek medium task use indefinitely preempt na kar sake.
"ISR se semaphore give karo, kaam task mein handle karo" ko ISR mein kaam karne se zyada prefer kyun kiya jaata hai?
ISRs ko interrupt latency kam rakhne ke liye short rehna chahiye; semaphore heavy processing ko ek schedulable task par defer karta hai (deferred interrupt processing).
Kai separate semaphores ek AND-condition ke liye ek event group replace kyun nahi kar sakte?
Aapko unhe ek-ek karke lena padega, aur ek task ek waqt mein sirf ek object par block ho sakta hai — isliye aap cleanly "A aur B" ka ek single atomic condition ki tarah wait nahi kar sakte. Event group ek combined mask par wait karta hai.
Consumer ke xQueueReceive par portMAX_DELAY aksar accha design kyun hai, aalsipan nahi?
Ek blocked task ready list se remove ho jaata hai, isliye CPU zero cycles busy-waiting mein spend karta hai. Kernel use precisely tab jagata hai jab data aata hai — dekho Producer–Consumer Pattern.

Edge cases

Woh scenarios jinhein naive mental model bhool jaata hai.

xSemaphoreTake kya return karta hai jab timeout expire ho jaata hai aur count abhi bhi 0 tha?
Yeh pdFALSE return karta hai. Task phir bina resource hold kiye continue karta hai, isliye aapko return value check karni chahiye yeh assume karne se pehle ki aapko mila.
Ek counting semaphore apni maximum count tak pahunch jaata hai aur ek aur Give aata hai — kya hota hai?
Give reject ho jaata hai (pdFALSE return karta hai) aur count max par rehta hai; extra event lost ho jaata hai. Max ko worst-case burst ke mutabik size karo taaki aap silently signals drop na karo.
Same priority ke do tasks dono ek hi empty queue par block hain; ek Send aata hai — kaun jaagta hai?
Woh task unblock hota hai jo sabse zyada waqt se wait kar raha tha (equal priorities mein FIFO). Priority primary key hai; wait order ties todta hai.
Ek high-priority task ek mutex hold karta hai aur phir ek doosre mutex par block ho jaata hai jo ek low task ke paas hai — kya inheritance chain hoti hai?
FreeRTOS basic inheritance support karta hai lekin nested mutexes mein full chain nahi; deep nesting abhi bhi inversion cause kar sakta hai. Safe design hai do mutexes ek saath hold karne se bachna (ya deadlock se bachne ke liye hamesha fixed order mein lock karo).
Ek event group WaitBits xWaitForAllBits = pdTRUE aur xClearOnExit = pdTRUE ke saath timeout ho jaata hai — kya bits clear ho jaati hain?
Nahi — clearing tab hoti hai sirf jab wait satisfy ho. Timeout par bits untouched rehti hain, isliye ek baad ka cycle unhe dekh sakta hai.
Ek queue xQueueCreate(0, …) (length 0) ke saath create ki gayi hai.
Yeh invalid hai — ek queue mein kam se kam ek item honi chahiye, aur creation NULL return karta hai. Handle ko use karne se pehle hamesha check karo (heap allocation failures ke liye bhi relevant).
Ek ISR ek binary semaphore give karta hai jo ek task ne already give kar diya hai (toh woh full hai) — kya yeh problem hai?
Ek binary semaphore count 1 par saturate hota hai, isliye redundant give simply drop ho jaata hai. Aap "doosra event hua" information lose kar lete hain — agar har event yaad rakhna ho toh counting semaphore use karo.

Recall Ek-line self-test

Upar ke har answer ko cover karo aur justification re-derive karo. Agar koi bhi answer aapke dimag mein ek bare "haan/nahi" mein collapse ho gaya, wahi concept hai jise parent note mein dobara dekhna hai.