公告版位
1. 發現有錯誤, 請留言告知. (或者你 '覺得' 不對也行)
2. 用字措辭不當, 請留言告知.
3. 有看沒有懂? 幫到忙也好, 幫倒忙也罷, 總之留個言吧.
- Oct 19 Mon 2015 22:48
UART 轉無線傳輸 (APC220/APC230)
- Oct 12 Mon 2015 16:48
UART 接收同步機制及鮑率誤差計算
給用手機瀏覽的讀者
很抱歉, 這一篇因為用了 MathJax 套件來顯示分數, 目前設定和痞客邦的 "手機版模式" 有點小衝突 (它把行高設定死了), 要等改天有空才能修正. 請先改用 "電腦版模式" 或者換用 PC/平板 來閱讀. 已經修正好了, 如果閱讀上還有問題請留言告知.
UART 接收同步機制
下圖所示是經由 UART 輸送一個 ASCII 字元 'r' (0x72) 的 TTL 輸出 (未經過 RS-232 Transceiver). 圖上的小箭號所指的是接收端取樣訊號的相對時序位置, 上半部是理想狀況下接收 UART 資料的時序圖. 我們設定了鮑率之後, UART 在第一個向下訊號邊緣取得同步 (開始計時) 是為啟始位元, 然後以設定的鮑率開始取樣接收資料. 不過事情總不會如此美好. 萬一接收者和發送者的計時精準度不同 (即使是同樣的廠牌、型號, 總還是有製造上的誤差, 及操作溫度...等等因素的影響), 致使二者不完全一致, 下圖的下半部刻意把誤差放大, 我們很容易就看出一共有 4 個位元的資料錯了.
RS-232 時脈誤差造成取樣錯誤
- Oct 08 Thu 2015 01:10
HTML CSS 語法 Part1
參考手冊:
設定 CSS, 總會要查一下手冊, 下面列的是個人經常參考的 CSS 手冊及標準文件
- W3Scholl 教學網站的 CSS 參考
- mozilla 的 CSS 參考手冊
IE 的 CSS 參考手冊(微軟放棄它了, 已經轉向 mozilla)- W3C CSS Level 1 標準文件
- W3C CSS Level 2.1 標準文件
- W3C CSS Selectors 標準文件(Level 3, 20181106)
- W3C CSS Selectors 草案文件 (Level 4)
- W3C CSS Colors Level 3 標準文件
HTML CSS 的語法結構:
網頁作者的設定是 CSS style 中最重要的部份, 網頁作者可以運用的 CSS 設定有多種來源:
- inline style
- embedded stylesheet
- included stylesheet
修飾設定:
這些 CSS 設定的基礎是修飾設定: 一個 CSS 屬性和它的設定值, 中間以冒號 : 接連起來, 例如: font-size : 1.2em. 這三者之間可以任意加入空白, 以提高可讀性. 但是屬性的名稱和每一種屬性的可以接受的設定值只能依照 CSS 的標準文件來 (或者更嚴格的說只能依照 CSS 的標準文件和各家 browser 實作的交集部份來設定.)
- Oct 02 Fri 2015 15:51
Raspberry Pi and Pi2, Pi3 接腳圖 (Pinout)
型號
電路版的型號依時間序有
- Pi rev.1 (2012/02/29)
- Pi rev.2 (2012/09/05)
- Pi+ (2014/07/14)
- Pi2 (2015/02/02)
- Pi3 (2016/02/28)
- Pi3+ (2018/03/14)
- Pi4 (2019/06/24)
- Pi400 (2020/11/04)
- Pi5 (2023/09/28)
Pi rev.2 和 Pi+ 有分 Model A 和 Model B. 二者的差異是電子零件用料不同 (Model A 用料縮減, 主要為減少 RAM, 網路接口, 及部份 USB 接口)
Pi3+ 相對於 P3 只是 CPU 的執行速度加快 1400 MHz (雙核 ARM Cortex-A53), Ethernet 網路接口改為 10/100/1000 Mbit/s, Wi-Fi 改為 802.11ac Dual band, Bluetooth 改為 4.2 BLE, 以及可以經 PoE 取電 (需另購 PoE HAT 擴充板). (還有總耗電量變大)
- Sep 22 Tue 2015 17:04
可重入與執行緒安全 (reentrant vs thread-safe) Part3
Reentrant vs Thread-safe
Part 3: C 語言例子 (thread-safe function)
接下來, 我們來看一些 thread-safe 的例子: 首先是在 wiki 網站上的一個 Thread-safe 但不是 reentrant 的例子.
#include <pthread.h>
int increment_counter() {
static int counter = 0;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&mutex);
// only allow one thread to increment at a time
++counter;
// store value before any other threads increment it further
int result = counter;
pthread_mutex_unlock(&mutex);
return result;
}
這個例子中的 increment_counter() 可以被多個執行緒呼叫而不會產生任何問題, 因為它用了一個 mutex 來保護 (同步) 所有對共用的靜態變數 counter 的存取. 但是如果中斷服務程式 ISR 也呼叫了 increment_counter(), 就會很容易使系統當掉. 原因是如果中斷發生在執行緒正呼叫 increment_counter() 時 (尤其是 mutex lock 和 unlock 之間), 那 ISR 將永遠等不到 mutex 被 unlock. 因為 CPU 接受中斷進入 ISR 後, 只有 ISR 完成, 才會回到執行緒. 記住: 中斷永遠比正常執行優先, 所以 ISR 要比執行緒或者是 OS 核心優先執行.
- Sep 21 Mon 2015 10:29
可重入與執行緒安全 (reentrant vs thread-safe) Part2
Reentrant vs Thread-safe
Part 2: C 語言例子 (reentrant function)
先來看 reentrant 的例子: 最常見到用來說明 reentrant 的例子大概就屬 swap() 了
int t;
void swap(int *x, int *y) {
t = *x;
*x = *y;
*y = t;
}
void isr(void) {
int x = 1, y = 2;
swap(&x, &y);
...
return;
}
void main(void) {
int x = 3, y = 4;
...
swap(&x, &y);
...
}
這個例子中的 swap() 函數是 non-reentrant function (而且也不是 thread-save). 原因是第4行及第6行用到共用的變數 t. 即便是我們用的是 32bit CPU, 甚至也有技援 mem. to mem. 移轉資料不被中斷, 也還是有二個時間點(在第5行執行前或執行後) 發生中斷會產生錯誤的執行結果. 如下表的 NG Example 1 和 NG Example 2 所示 (在這裡為了讓這一張表格不致於太長, 我只把動作拆解到高階語言的單一指令階段, 實際上像 *x=*y 這樣的指令可能就要二個以上的低階組合語言指令.)
- Sep 19 Sat 2015 03:42
可重入與執行緒安全 (reentrant vs thread-safe) Part1
Reentrant vs Thread-safe
Reentrancy 和 thread-safty 是兩個容易被搞混了的觀念. 其中最嚴重的是誤以為 reentrant function 必定是 thread-safe 或者相反以為 thread-safe function 必為 reentrant, stackoverflow 網站上的答覆甚至同時出現二種答案的現象.
Reentrancy 和 Thread-safty 二者的差異
首先來看 reentrancy: 字面上的意思是可重入. Reentrancy 原先是討論單一執行緒環境下 (即沒有使用多工作業系統時) 的主程式和中斷服務程式 (ISR) 之間共用函數的問題. 當然現在多核心的 CPU 盛行, 討論範圍也必需擴充至多執行緒的情況. 重點是它討論的主體是: 在 ISR 中使用的函數 (不論是自己寫的或者是函數庫提供的) 是否會引發錯誤結果. 主要的達成條件是二者 (ISR 和非 ISR) 的共用函數中不使用靜態變數或全域變數 (意即只用區域變數). 一般是撰寫驅動程式 (device driver) 或者是寫 embedded system 的人會遇到這個問題.
再來是 thread-safety: 字面上的意思是執行緒 (線程) 安全. Thread-safe 一開始就針對多執行緒的環境 (CPU 可能單核也可能是多核), 討論的是某一段程式碼在多執行緒環境中如何保持資料的一致性 (及完整性), 使不致於因為執行緒的切換而產生不一致 (及不完整) 或錯誤的結果. 所以是程式中有運用到多執行緒的大型應用系統的程式人員會比較常遇到這類問題. 問題的產生點一般出現在對某一共用變數 (或資源) 進行 read-modify-write (或者類似的動作(註一)) 時, 還沒來得及完成整個動作, 就被其他的執行緒插斷, 並且該執行緒也一樣對這個共用變數 (或資源) 進行 read-modify-write (或者類似的動作). 例如Thread1 和 Thread2 之間我們需要一個作為計數器的共用變數:
- Sep 10 Thu 2015 19:28
C 語言:Keil C51 和標準 C 語言的差異
Keil C51 和標準 C 主要的差異
Keil 的 C51 是以 ANSI C90 為其設計基礎, 即便是如此, 它和標準 C 語言 (ANSI C90) 之間還是有幾個滿大的差異:
- Keil C51 因應 8051 的特性多了 bit, sbit, sfr, sfr16 等四種資料型態. 一般我們只會用到 bit, 其他三個是定義 CPU 的特殊功能暫存器用的.
- Keil C51 在定義變數時多了儲存空間修飾字, 用來修改變數使用記憶體空間. 詳細可參考我的這一篇貼文: "C 語言:Keil C51 Program Tips"
- 多了定義中斷服務常式 ISR 的方法及進入 ISR 時切換暫存器區段 (register bank) 的語法, 例如: static void UART0_ISR(void) interrupt 4 using 2
- 標準函數庫沒有依標準來實作, 如: printf()
- 在 Keil C51 中, 函數預設是 non-reentrant, 這點是最嚴重的差異. 我們在使用時要有所警覺才好, 才不致於掉到陷阱裡而不自知.
什麼是 reentrant
在此先來了解一下 reentrant 的定義, Wiki 網站上給 reentrancy 下的定義是
In computing, a computer program or subroutine is called reentrant if it can be interrupted in the middle of its execution and then safely called again ("re-entered") before its previous invocations complete execution.
- Sep 03 Thu 2015 15:32
IE11 scrollbar 捲動時隨機出現條紋的 bug
- Aug 19 Wed 2015 01:45
HTML 屬性的特別用途
有幾個 HTML 屬性用途相當特別, 特別記下以茲備忘:
1. title:
title 屬性可以附加在任何的 tag 上, 它的功用是產生類似 Tooltip Text 的提示效果: 當滑鼠停留在某個元素上面時, 就會出現提示文字. 例如:
<p title='簡介'>落落長的文章本文, 落落長的文章本文, 落落長的文章本文...</p>