Mail Box#
- 類似於 pipe,主要用來傳輸資料
- 每一封郵件大小為 4 bytes(即 32 位元)
結構#
File: rtdef.h
642 |
|
msg_pool
指向郵件堆的起點,entry
紀錄總郵件的數量
File: ipc.c
建立 mail box#
動態記憶體管理#
功能 | 回傳值 |
---|---|
建立 mail box | mail box |
*name |
size |
flag |
---|---|---|
名字 | mail box 大小 | FIFO / PRIO |
1348 | /** |
- 首先 allocate 一塊給 mailbox
1367 | /* set parent */ |
- 填入 flag 及初始化
1372 | /* init mailbox */ |
- 因使用動態記憶體的緣故,需 allocate 一塊給郵件堆
- 大小為一封一件的大小 * size
1382 | mb->entry = 0; |
- 最後初始化值及等待鏈
靜態記憶體管理#
功能 | 回傳值 |
---|---|
初始化 mail box | RT_EOK |
mb |
*name |
*msgpool |
size |
flag |
---|---|---|---|---|
mail box 本體 | 名字 | 存放郵件的地方 | mail box 大小 | FIFO / PRIO |
1278 | /** |
- 這裡就不需要 allocate,可直接初始化來使用
1306 | /* init mailbox */ |
- 一樣,郵件堆可直接拿來用,初始化值及等待鏈
刪除 mail box#
動態記憶體管理#
功能 | 回傳值 | mb |
---|---|---|
刪除 mail box | RT_EOK |
欲刪除的 mail box |
1395 | /** |
- 首先將正在等待郵件的,與正在等待傳送的 thread 叫醒
1416 | /* free mailbox pool */ |
- 歸還郵件堆,最後刪除 mail box
靜態記憶體管理#
功能 | 回傳值 | mb |
---|---|---|
刪除 mail box | RT_EOK |
欲刪除的 mail box |
1321 | /** |
- 首先將正在等待郵件的,與正在等待傳送的 thread 叫醒
1339 | /* detach mailbox object */ |
- 最後刪除 mail box(使用
detach
)
傳送郵件#
功能 | 回傳值 |
---|---|
傳送郵件 | RT_EOK |
mb |
value |
timeout |
---|---|---|
欲傳送的 mailbox | 郵件內容 | 等待時間(如果需要) |
1428 | /** |
- 如果 mail box 滿了,且不等待 (
timeout==0
),回傳FULL
1482 | RT_DEBUG_IN_THREAD_CONTEXT; |
- 若要等待,將 thread 掛上等待鏈,啟動一個 timer
1503 | /* enable interrupt */ |
- 再做一次調度
1508 | /* resume from suspend state */ |
- 如跳回來,重新計算
timeout
1527 | /* set ptr */ |
- 若可以寫入,將資料寫入,同時更新
offset
及entry
1535 | /* resume suspended thread */ |
- 如果有人在等待寄信,叫醒他,做一次調度
- 若是不想等待,可以使用
rt_mb_send
功能 | 回傳值 |
---|---|
傳送郵件(不等待) | RT_EOK |
mb |
value |
---|---|
欲傳送的 mailbox | 郵件內容 |
1560 | /** |
- 即
timeout == 0
接受郵件#
功能 | 回傳值 |
---|---|
接受郵件 | RT_EOK |
mb |
*value |
timeout |
---|---|---|
欲收信的 mailbox | 郵件內容 | 等待時間(如果需要) |
1576 | /** |
- 如果 mail box 沒東西,且不等待,回傳
TIMEOUT
1630 | RT_DEBUG_IN_THREAD_CONTEXT; |
- 若要等待,將 thread 掛上等待鏈,啟動一個 timer
1651 | /* enable interrupt */ |
- 再做一次調度
1656 | /* resume from suspend state */ |
- 如跳回來,重新計算
timeout
1675 | /* fill ptr */ |
- 若可以讀取,將資料寫入,同時更新
offset
及entry
1684 | /* resume suspended thread */ |
- 如果有人在等待收信,叫醒他,做一次調度
Message Queue#
- 特性:可接受不固定長度的訊息
結構#
File: rtdef.h
663 |
|
File: ipc.c
建立 message queue#
動態記憶體管理#
功能 | 回傳值 |
---|---|
建立 message queue | message queue |
*name |
msg_size |
max_msgs |
flag |
---|---|---|---|
名字 | 一封訊息的大小 | 訊息數上限 | FIFO / PRIO |
1852 | /** |
- 首先要一塊物件給 message queue,並同時填入 flag 及初始化
1883 | /* init message queue */ |
- 設定訊息的大小,與訊息數量的上限
RT_ALGIN
目的在對齊訊息的大小,根據不同板子所定義不同的 RT_ALIGN_SIZE
會有所差別
#define RT_ALIGN(size, align) (((size) + (align) - 1) & ~((align) - 1))
- 如傳進來的是
RT_ALGIN(7,8)
則結果是 8 - 如傳進來的是
RT_ALGIN(13,4)
則結果是 16 - 即結果為大於後值的最小倍數
1888 | /* allocate message pool */ |
- 接著需 allocate 適當的記憶體存放訊息
1896 | /* init message list */ |
- 先將頭尾設為空,再一塊一塊的將
msg_pool
插在 free list 的第一顆
1909 | /* the initial entry is zero */ |
- 最後設定
entry
為 0
靜態記憶體管理#
功能 | 回傳值 |
---|---|
初始化 message queue | RT_EOK |
mq |
*name |
*msgpool |
---|---|---|
message queue 本體 | 名字 | 存放訊息的位址 |
msg_size |
pool_size |
flag |
---|---|---|
一封訊息的大小 | 存放訊息的大小 | FIFO / PRIO |
1764 | /** |
- 這裡就不需要去要一塊物件,直接拿來用即可
1798 | /* set messasge pool */ |
- 其餘的動作皆與上面相同
刪除 message queue#
動態記憶體管理#
功能 | 回傳值 | mq |
---|---|---|
刪除 message queue | RT_EOK |
欲刪除的 message queue |
1920 | /** |
- 先把正在等待收訊息的 thread 叫醒
1938 | /* free message queue pool */ |
- 接著 free
msg_pool
,並刪除物件
靜態記憶體管理#
功能 | 回傳值 | mq |
---|---|---|
刪除 message queue | RT_EOK |
欲刪除的 message queue |
1827 | /** |
- 這裡的
msg_pool
就不需要 free
傳送訊息#
功能 | 回傳值 |
---|---|
傳送訊息 | RT_EOK |
mq |
*buffer |
size |
---|---|---|
欲傳送的 message queue | 訊息資料 | 訊息大小 |
1950 | /** |
- 首先確定 message queue 沒滿(即 free list 不為空)
- 如果滿了,回傳
FULL
1990 | /* move free list pointer */ |
- 接著 free list 往下一顆走
1992 | /* enable interrupt */ |
- 將訊息填入從 free list 拿的一顆(
msg
),這顆待會是新的尾巴(設定next = NULL
)
1999 | /* disable interrupt */ |
- 如果尾巴不為空(也就是 message queue 有東西),將原本的尾巴指向
msg
2007 | /* set new tail */ |
- 設定新的尾巴
- 如果頭為空(也就是 message queue 為空),設定新的頭
2012 | /* increase message entry */ |
- 最後更新
entry
2014 | /* resume suspended thread */ |
- 如果有人在等待接收訊息,叫醒他
傳送緊急訊息#
- 與上面不同的是:這裡將新訊息插入第一顆
功能 | 回傳值 |
---|---|
傳送緊急訊息 | RT_EOK |
mq |
*buffer |
size |
---|---|---|
欲傳送的 message queue | 訊息資料 | 訊息大小 |
2039 | /** |
- 因為要插在第一顆,
next
就不用設定為空了
2088 | /* disable interrupt */ |
- 這裡就將新訊息插在第一顆
2097 | /* if there is no tail */ |
- 如果原本的 message queue 為空,設定新的尾巴
2100 | /* increase message entry */ |
- 其他的動作皆相同
接收訊息#
功能 | 回傳值 |
---|---|
接收訊息 | RT_EOK |
mq |
*buffer |
size |
timeout |
---|---|---|---|
欲訊息 message queue | 訊息存放處 | 訊息存放處大小 | 等待時間(如果需要) |
2123 | /** |
- 如果 message queue 為空,且不等待,回傳
TIMEOUT
2186 | /* suspend current thread */ |
- 如要等待,將 thread 掛在等待鏈上
2190 | /* has waiting time, start thread timer */ |
- 並啟動一個 timer
2205 | /* enable interrupt */ |
- 開始等待,做一次調度
2210 | /* recv message */ |
- 如跳回來,重新計算
timeout
2229 | /* get message from queue */ |
- 如果 message queue 有資料,拿第一顆,同時更新 head(tail,如果需要)
2237 | /* decrease message entry */ |
- 更新 entry
2239 | /* enable interrupt */ |
- 接著複製找到的訊息
2244 | /* disable interrupt */ |
- 最後將
msg
插入 free list 的頭