指令執行的結束狀態是 waitpid 系統呼叫或等效函數的回傳值,範圍 0 ~ 255,0 表示成功 (true),否則表示失敗 (false)。shell 特別定義 126 以上的值。
- 2:所有內建指令回傳 2 表示使用不正確,一般是 invalid options 或 missing arguments。
- 126:檔案有找到,但不含可執行屬性。
- 127:檔案沒找到。
- 128+N:因 fatal signal N 而結束
參考:man bash 的 EXIT STATUS
BJT 是電流放大,在架構上帶限流,不用擔心瞬間電流過大弄垮系統,可避免一些雜訊減少 EMI。BJT 只要電流控制好不易燒毀~尤其是靜電。 BJT 非常強壯,不像 MOS,適合用在連外的電源開關上。 https://www.facebook.com/twembedded/posts/2915547031826847
BJT 大功率會比較燙。
應用:電流開關,天生防逆流
應用:電壓偵測器
應用:簡易耐十幾 V 小電流 LDO。例如用 12 Vin 供電給 RTC。https://www.facebook.com/twembedded/photos/a.336725383042371/3117519414962940
應用:OCP https://www.facebook.com/twembedded/posts/3072405346141014
應用:小電流系統
https://www.facebook.com/twembedded/posts/2915743455140538
https://www.facebook.com/twembedded/posts/2638640626184157
https://www.facebook.com/twembedded/posts/3018693128178903
https://www.facebook.com/twembedded/posts/2822064987841719
請求要在 64*T1 (T1 預設 0.5 秒,所以總共是 64*0.5 = 32 秒) 前要收到最後回應,不然就逾時而結束。
如果使用 UDP,由 Transaction 層提供重傳機制,Client Transaction 重送請求直到收到最後回應,間隔是 T1, 2*T1, 4*T1, ..., T2, T2, T2, ...。一開始是 T1,然後每次加倍直到 T2 或收到暫時回應後,改為 T2。
Server Transaction 收到重傳的請求,不往 TU 送,有回應過會重送回應。傳送最後回應後,有可能對方沒收到而收到重傳的請求,需使用 Timer J 等候 64*T1 才把 Transaction 結束。
T2
表示 server transaction 不馬上回應時應該的回應時間。
一般請求重送間隔照 T1 指數型退讓最大 T2,總共最長 64*T1。預設 T1 0.5 秒、T2 4 秒,間隔會是 0.5 秒、1 秒、2 秒、4 秒、4 秒、4 秒、4 秒、4 秒、4 秒、4 秒 (共 7 次 4 秒)。
Client Transaction 收到最後回應後,可能還會有重傳的回應在半路,等候 T4 才把 Transaction 結束,預設是 5
秒。
一般 Client Transaction 狀態流程 (修改自 RFC3261)
|Request from TU:
|send request
Timer E: V
send request +-----------+
+---------| |-------------------+
| | Trying | Timer F |
+-------->| | or Transport Err.:|
+-----------+ inform TU |
200-699: | |1xx: |
resp. to TU | |resp. to TU |
+---------------+ | |
| | |
| Timer E: V Timer F |
| send req +-----------+ or Transport Err.:|
| +---------| | inform TU |
| | |Proceeding |------------------>|
| +-------->| |-----+ |
| +-----------+ |1xx: |
| 200-699: | ^ |resp to TU |
| resp. to TU | +--------+ |
| V |
| +-----------+ |
+----------->| Completed | |
+-----------+ |
| Timer K: |
V |
+-----------+ |
| Terminated|<------------------+
+-----------+
註:Timer F 計數 64*T1 逾時,Timer E 在 UDP 時計數重傳間隔,Timer K 在 UDP 時計數 T4 等候可能還在半路的重傳回應。
一般 Server Transaction 狀態流程 (修改自 RFC3261)
| 收到請求:
| 轉給 TU
TU 最後回應: V
送回應 +-----------+
+-------------| Trying |
| +-----------+
| | TU 暫時回應:
| | 送回應
| TU 新暫時回應或 V Trnsprt Err:
| 再次收到請求:+-----------+ Inform TU
| 送回應 +----| Proceeding|-------------->+
| | +-----------+ |
| | ^ | |
| +------+ |TU 最後回應: |
+------------------>|送回應 |
V Trnsprt Err: |
再次收到請求:+-----------+ Inform TU |
送回應 +----| Completed |-------------->+
| +-----------+ |
| ^ |Timer J 到期 |
+------+ V |
+-----------+ |
| Terminated|<--------------+
+-----------+
註:
INVITE Transaction 比一般 Transaction 多了要對最後回應回送 ACK 作確認,形成三路交握 -- INVITE、回應、ACK。
如果使用 UDP,由 SIP Transaction 層提供重傳機制
|INVITE from TU:
Timer A fires: |INVITE sent
Reset A, V Timer B fires
INVITE sent +-----------+ or Transport Err.:
+---------| |---------------+inform TU
| | Calling | |
+-------->| |-------------->|
+-----------+ 2xx: |
| | 2xx to TU |
300-699: +---------------+ |1xx: |
ACK sent | |1xx to TU |
resp. to TU | 1xx: V |
| 1xx to TU -----------+ 2xx: |
| +---------| | 2xx to TU |
| | |Proceeding |-------------->|
| +-------->| | |
| +-----------+ |
| |300-699: |
+----------------->|ACK sent, |
|resp. to TU |
300-699: V |
ACK sent +-----------+Transport Err.:|
+---------| |Inform TU |
| | Completed |-------------->|
+-------->| | |
+-----------+ |
| Timer D fires: |
v |
+-----------+ |
| Terminated|<--------------+
+-----------+
註:Timer B 計數 64*T1 逾時,Timer A 在 UDP 時計數重傳間隔。INVITE Server Transaction 狀態流程 (修改自 RFC3261)
收到請求:|
轉給 TU | 如果無法在 200ms 內回應:
+-------+ 送 100 Trying
| |
TU 回應失敗: V | TU 回應成功:
送回應 +---------+ | 送回應
+---------| Trying |--|----------------->+
| +---------+ | |
| TU 暫時回應:| | |
| 送回應 | | |
| TU 暫時回應或 V v TU 回應成功: |
| 再次收到請求:+-----------+ 送回應 |
| 送回應 +----| Proceeding|-------------->+
| | | | |
| +--->| | |
| +-----------+ Trnsprt Err: |
| TU 回應失敗:| | Inform TU |
| 送回應 | +---------------->|
+------------------>| Timer H 到期或 |
再次收到請求或 V Trnsprt Err: |
Timer G 到期:+-----------+ Inform TU |
送回應 +----| Completed |-------------->+
| +-----------+ |
| ^ | ACK |
+------+ V |
+-----------+ |
| Confirmed | |
+-----------+ |
|Timer I 到期 |
V |
+-----------+ |
| Terminated|<--------------+
+-----------+
和一般 Transaction 差別:
Client Transaction
| 事件 | 狀態 | 主動重送 | 逾時 |
|---|---|---|---|
| 送INV請求 | Calling | Timer A | Timer B |
| 收到暫時回應 | Proceeding | 無 | 無 |
| 收到失敗回應送 ACK | Completed | 無 | Timer D |
| 逾時 或 無法送 或 收到 2xx | Terminated | NA | |
| 事件 | 狀態 | 主動重送 | 逾時 |
|---|---|---|---|
| 送一般請求 | Trying | Timer E | Timer F |
| 收到暫時回應 | Proceeding | Timer E | Timer F |
| 收到最後回應 | Completed | 無 | Timer K |
| 逾時 或 無法送 | Terminated | NA | |
Server Transaction
| 事件 | 狀態 | 再次收到請求 | 主動重送 | 逾時 |
|---|---|---|---|---|
| 收到請求 | Trying | 忽略 | 無 | 無 |
| 送暫時回應 | Proceeding | 重送回應 | 無 (PRACK) | |
| 一般送最後回應 | Completed | 無 | Timer J | |
| INV送失敗回應 | Timer G | 64*T1 | ||
| INV送成功回應 | ||||
| 收到 ACK (相同 Via branch) | Confirmed | 忽略 | 無 | Timer I |
| 收到 ACK (在 TU 有 Dialog) | ||||
| 逾時 或 無法送 (通知 TU) | Terminated | NA | ||
| 送成功回應 | 在 TU 有 Dialog | TU 處理 | TU 處理 | |
| 收到 ACK (不同 Via branch) | TU 處理 | |||
INV 成功回應的重傳本來是在 TU 處理的,可整合到 Completed 狀態,採用 INV 失敗回應相同的 Timer G 重送和 Timer H 結束,變成 INV 最後回應都採用相同的處理方式。此時收到 ACK 也要進到 Confirmed 狀態。
註:transaction 源自 HTTP
參考
Linked List 是程式常見的資料結構,通常是指 Double Linked List (如 linux/list.h),但這裡說 Singly Linked List。
Singly linked list 第一個 node 透過 head 指標存取,每個 node 有一個 next 指標串下個 node,最後 node (稱為 tail) 的next 為 nil。
移除 node
typedef struct list {
item *head;
} list;
static inline item **ll_find(list *list, item *node)
{
item **pp = &list->head;
while(*pp != node)
pp = &(*pp)->next;
return pp;
}
void ll_remove(list *list, item *node)
{
item **pp = ll_find(list, node);
*pp = node->next;
}
如果作為 FIFO 常常需要將 node 放到 tail,額外紀錄 tail 指標:
typedef struct list {
item *head;
item *tail;
} list;
// 先準備好 node, node->next = null;
void ll_insert_tail(list *list, item *node)
{
if (list->tail)
list->tail->next = node; // 避免 node 加入時,tail 剛好刪除
else
list->head = node;
list->tail = node;
}
item *ll_remove_head(list *list)
{
item *node = list->head;
list->head = node->next;
if (list->tail == node)
list->tail = NULL;
return node;
}lock-free linked list 用在 concurrent 環境:兩個或以上 thread 執行操作不干擾彼此間的工作。
基本操作有兩個
// compare and swap
void *cas(void **addr, void *old, void *new)
{
void *value = ∗addr
if (value == old)
∗add = new
return value;
}
void ll_insert_after(item *p, item *n)
{
do {
item *next = p->next;
n->next = next;
} while (cas(address-of(p->next), next, n));
}
itme *ll_remove_after(item *p)
{
}
問題:如何確認某個 node 是否有其它 thread 仍在使用?例如 thread A 停在 node n (可能搜尋一半,或其它),此時 thread B 移除 node n 並釋出記憶體,會造成 thread A 問題
問題
cache unfriendly
https://en.wikipedia.org/wiki/Non-blocking_linked_list
https://ithelp.ithome.com.tw/articles/10214944
https://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html
Circular doubly linked list
| 無免持 | KX-TS500 | KX-TSC60 | KX-T7703 | KX-TSC11 | KX-TS560 |
|---|---|---|---|---|---|
| 有免持 | | KX-TSC62 | KX-T7705 | ? | KX-TS580 |
| 電源 | 免 | 電池 | |||
| 來電顯示 | 無 | 30 組 | 50 組 | ||
| 脈衝撥號 | 有 | 有 | 有 | 有 | ? |
| 鈴聲 | 大/小/關 | 大/小/關 | 大/小/關 | 大/小/關 | 大/小/關 |
| 聽筒音量 | 4 段 | 4 段 | 可調整 | 4 段 | 4 段 |
| 暫切 | 有 | 100/300/600ms | 有 | 有 | 有 |
| 靜音 | 無 | 有 | 有 | ? | 有 (KX-TS580) |
| 音樂保留 | 無 | 無 | 無 | ? | 有 |
| 重撥 | 有 | 5 組 | 5 組 | 20組 | 20組 |
| 自動重撥 | 無 | 15次 | 無 | ? | ? |
| 日期時間 | 無 | 有 | 有 | 有 | 有 |
| 其它 | 秘密撥號 | 50組電話簿 長途限撥 按鍵鎖 暫停鍵 LCD 亮度調整 | 50組電話簿 限制撥號 長途限撥(限0,或2位數) 按鍵鎖 暫停鍵 | ||
20151011 購買 KX-TSC62 NT$1090, KX-TS500 NT$488
中諾話機 F013 響鈴太大聲,喇叭串 200Ω (後來發現可設定鈴聲)
有免電池變壓器,但支援耳麥的話機嗎?
轉藍牙
WiFi+DECT雙系統 Panasonic KX-PRW120 智慧型無線電話
Homesitter HS-700/E 保護神 四合一 警報器: 淹水 + 高溫/低溫 + 斷電(竊盜) + 主機低電量
所有 SIP 訊息 都要有 Via,縮寫 v。一開始的 UAC 和後續途經的每個 proxy 都會疊加一個 Via 放傳送的位址,依序作為回應的路徑。 格式 sent-protocol sent-by [ ;branch= branch ][ ; 參數 ...] s...