平臺:s3c2440 內核版本:linux-2.6.22.6
源碼位置https://github.com/yogach/Ebook
描述:使用命令行方式打開電子書應用。支持自定義顯示設備(目前只支持lcd顯示),支持選擇字庫文件,支持ASCII、UTF8、UTF16LE、UTF16BE編碼格式的文本文件,使用freetype庫通過Unicode碼從字庫文件中獲取字體位圖,支持顯示字體大小設置,支持標準輸入(stdin)、觸摸屏輸入(tslib庫)與按鍵(Key)輸入,並由這些輸入控制電子書翻頁,標準輸入同時支持輸入指定頁碼進行跳頁。支持標準輸出(stdout)與網絡打印(socket)調試信息。
框圖:
輸入事件讀取:對每種輸入方式實現一個獨立的子線程,在子線程中對輸入事件進行阻塞讀取(降低cpu佔用),當讀取到符合要求的輸入事件之後,先獲取互斥量,取得符合要求的輸入事件,然後喚醒主線程,返回已經得到的輸入事件。
按鍵驅動未使用輸入子系統,使用的是自己寫的一個驅動。
觸摸屏控制支持滑動與點擊指定區域進行翻頁。
標準輸入支持輸入n爲下一頁 u爲上一頁 q退出
指定頁碼跳頁功能:支持跳轉到已顯示過的頁面。程序定義了一個雙向鏈表,鏈表節點中記錄了當前頁碼、當前頁面內容在文本文件的起始地址以及下一頁內容的起始地址。已經顯示過的頁面,都會放入此鏈表中。使用時根據頁碼檢索到指定節點,然後進行跳轉。
打印信息調試:支持標準輸出(stdout)與網絡打印(socket)調試信息。
網絡打印選擇使用UDP方式進行數據傳輸(打印數據的數據準確性要求不高),程序中使用了數據發送子進程和數據接收子進程。在每次打印數據時,會先將數據放入循環緩衝區,之後喚醒發送進程,發送進程會查看是否已經有客戶端連接,如果已有客戶端連接則發送打印數據。接收數據進程一直處於接收客戶端信息狀態,如果接收到客戶端的開始打印信息會設置一個標誌位告訴發送線程可以進行發送操作。在開啓接收打印數據之前,也可先行設置打印等級,以及開關打印通道。
UDP的特性是:數據報,無連接,簡單,不可靠,會丟包,會亂序(實際中遇到的主要是丟包)。
TCP的特性是:流式,有連接,複雜,可靠,延遲較大、帶寬佔用較大(均是相對於UDP來說)。
打印信息封裝:可打印所屬文件與行數,方便調試
DebugPrint("%s[%d]:"fmt,__FILE__,__LINE__,##__VA_ARGS__)
1) __VA_ARGS__ 是一個可變參數的宏,很少人知道這個宏,這個可變參數的宏是新的C99規範中新增的,目前似乎只有gcc支持(VC6.0的編譯器不支持)。宏前面加上##的作用在於,當可變參數的個數爲0時,這裏的##起到把前面多餘的","去掉的作用,否則會編譯出錯, 你可以試試。
2) __FILE__ 宏在預編譯時會替換成當前的源文件名
3) __LINE__ 宏在預編譯時會替換成當前的行號
字符的顯示:首先通過open()打開文本文件,使用fstat()獲取文件大小,根據其大小使mmap()函數將文本文件內容映射到內存中。根據文件開頭的數據(可參照第5點)得到符合的文件編碼處理方式。顯示時,獲取一個字符的unicode碼,判斷是否是回車換行TAB等特殊字符。如果是一個普通的字符,使用freetype庫提供的API,從字庫文件中找到該字符的位圖文件,如果頁面還能繼續顯示字符,就將字體位圖像素(支持1,8位像素格式)拷貝顯存中。
判斷文件編碼格式的方式:文件起始位置上的幾個字節數據標識了文件編碼格式
utf8 - 0xEF 0xBB 0xBF
utf16le - 0xFF 0xFE
utf16be - 0xFE 0xFF
ACSII - 如果以上三者都不是的話 則是ASCII編碼方式
如UTF8碼爲 0xe4 0xb8 0xad
0xe4 1110 0100 前面有三個1 代表該字符需要三個字節表示,00100需要保存下來
0xb8 1011 1000 10需要去掉
0xad 1010 1101 10需要去掉
得到的Unicode編碼是 00100 111000 101101 4E 2D
freetype庫:使用提供的API,通過字符unicode碼在字庫文件中獲取到的字體位圖。位圖文件的起始座標位置在左下角,而LCD座標系的起始位置在左上角,在寫入到顯存之前需要進行Y軸座標系轉換。通常爲轉化座標Y值=屏幕分辨率-原始座標Y值。對於單個字體而言,即轉化座標Y值=字體大小-原始座標Y值。
lcd顯示刷新:在程序運行的最開始,使用open()函數打開/dev/fb0幀緩衝設備文件,打開後使用ioctl()函數獲得LCD的x,y分辨率以及像素深度(BPP,每個像素所佔位數),然後根據以上信息使用mmap將幀緩衝設備映射到內存中,以後如果想在lcd上顯示內容,可直接對這塊內存(FrameBuffer)操作即可。
https://www.cnblogs.com/xiaojianliu/p/8473095.html
使用getopt處理命令行指令:見鏈接。