串口 終端(原創)

來源:互聯網
上載者:User

標籤:

  --------------------------- 串口晶片, 配置, 使用 --------------- 
  串口晶片整合到了主晶片內部, 串口晶片一般包括, 接收緩衝區, 發送緩衝區. 這是硬體緩衝區.  主晶片一般有三條串口線, 就像可以有多條i2c匯流排.
 
  相應的gpio可以選擇配置成串口, 並不是每個gpio都能配置成串口, 從gpio配置表dws檔案, 可以看到gpio是否支援串口模式. 
    
  從feature phone調試來看, 串口只能被一個模組使用, 可以用setowner函數來切換被哪個模組使用. 有一個nv項會決定, 串口給哪個模組用. 

  每次串口在接收到資料時, 都會發送串口訊息, 在feature phone中, 訊息中都會指定發給哪個task. task中都會有一個迴圈, 來接收task.  迴圈中會相應的receive函數, 接收訊息, 如果沒訊息過來, 則會阻塞. 
 
  實際中遇到的問題:
 
  1.  在開啟串口時, 本來要開啟串口1, 而開啟了串口3, 結果Task迴圈中, 一直沒收到訊息.
 
  2. 配置串口時, 沒調setowner, 導致open串口時指定的模組, 與串口的owner不一致, 導致電流一直在巨大跳變. 一插上usb, 電腦的services進程佔用40%
 
  3. uart_getbytes函數的指定的軟體緩衝區length大小為0, 導致硬體緩衝區的資料沒有被接收, 串口驅動的接收標誌沒有被置位,
     導致下一次串口接收資料時, 沒有發串口訊息. 把length改大即可.  
    
  4. 串口的owner切換, 預設配置的是給at模組用. 為了給2502傳送資料, 添加一個at命令, 完成模組切換. 即將串口由at模組轉給自訂的task模組.
 
  5.  task 配置,  在hal_task_config.h配置,  編譯不過. 要在app_task_config.h配置, task所做的事情, 應該都屬於mmi層. 對應linux, 應該是串口使用者空間編程.
 
  6. 因持續收到的串口訊息沒有釋放, 導致收到第600個左右的位元組時, 系統掛掉.
  先說一下訊息的一般機制:
  java, c, c++, 訊息架構都是, 訊息對象裡都會指定訊息的接收者, 訊息的接收者, 一般都是一個迴圈,
  迴圈裡有個函數會等待訊息, 如果訊息沒來, 就會阻塞在那, 如果訊息過來, 才會繼續執行.
  mtk Task接收uart訊息, 就是使用這個機制.
  串口有資料發來, 就會有個串口訊息發出來, 通過對串口設定owner, 即該task的mod id, 這樣對訊息體裡id就指定這個task. 訊息發送這個task.
 
  task while 迴圈接收到訊息, 實際接收的訊息的對象, 一般的機制都是由接收者來釋放這個訊息在記憶體中申請的空間.
 
  若沒有釋放, 這裡碰到一個問題, 由於空間不斷泄漏, 到收到第600多個位元組, 訊息對象數量不斷增多, 泄漏的記憶體不斷增大, 導致系統掛住.
 
  串口工具有時at命令無響應, 串口工具重新開啟就好

 

------------------ cts rts配置 -----------------
  解釋cts/rts流控,要從接收緩衝區說起. 當初遇到了什麼問題, 而想出了這個東西. 

  流控是為了接收緩衝區沒有準備好, 發送方還在發資料的問題, 資料丟失的問題. 

  解決的辦法, 就是多連一條線, 接收方通過控制這根線的高低電平, 來告訴發送方, 接收緩衝區是否準備好. 

   接收緩衝區如果沒準備好, 會把這根線拉高,  如果準備好, 就把這根線拉低.
  從術語上講, 這根線在rx這邊, 對應引腳是rts,  在tx那邊, 接引腳cts.  在資料沒準備好時,   rts拉低. 預設rts配置成內部拉高.

 

接線:

rx要接到對方的tx, tx要接到對方的rx. 在調ble與2502通訊時, ble要配成與2502相反. 

rts要接到對方的cts.  rts電位由接收方控制.

 

通過控制電平, 通知對方:

當接收方還沒準備好, 接收方會把rts拉高, 即發送方的cts被拉高, 這樣發送方就知道接收發沒有準備好, 就不發送了.
當接收方準備好時, 接收方會把rts拉低, 即發送方的cts被拉低, 這樣發送方就知道接收發準備好, 就發送資料.

 

gpio配置:

從Datashee可確認, 開啟dws, 可看到支援硬體流控的gpio. 2502隻有兩個gpio支援硬體流控,  從gpio選項中可確認.

 

測試硬體是否起作用:

 

 

對於ble與2502, 因為2502給ble發送大資料, ble是接收方, 所以rts訊號由接收方控制, 這就是ble支援硬體流控.  而2502的cts收到這個訊號, 能不發送資料, 說明2502也支援硬體流控.

 

分包大小要受對方緩衝區限制, 最大不能超過對方接收緩衝區. 

 

-----  串口速率 ---------

   
   串口傳輸速率, 50K, 20K分別對應哪個檔. 115200 對應多少.  除以8, 得14402, 即15K. 是吧
   串口傳輸速率有兩種表示方法, 一種bps, 如115200. 一種是KBps, 一般一個資料佔8位.  所以115200對應的是14.4KBps. 理論上每秒傳14K.   傳輸速率是否受接收方的限制. 

 

---------- 協調串口資料轉送的訊號線 ----------------

uart可以有18根訊號線, unix環境只用了6根.


GND - Logic Ground 地線, 提供了一個參考電壓, 基於這個參考電壓, 有兩種電壓, space電壓, mark電壓.
TXD - Transmitted Data發送訊號線
RXD - Received Data接收訊號線
DCD - Data Carrier Detect表示另一端已經串連好的訊號線, space電壓表示另一端已經串連, mark電壓表示沒準備好
DTR - Data Terminal Ready表示另一端是否已經準備好的訊號線, space電壓表示已經準備好
CTS - Clear To Send space電壓表示本地這端可以送出更多資料
RTS - Request To Send space電壓表示本地已經準備好了資料可以傳送.

以後再看到這些字母就不犯迷糊了. 這些訊號線都是來協調資料傳送的, 就是為了給你百分之百的保證. 才有了這麼多訊號線.

晶片從串列匯流排接到資料, 資料都是一個位元組一個位元組傳送的, 必須知道位元組的開始位置, 與結束位置.
串列線在沒有資料傳送時, 都是mark電壓.
在變到space電壓, 說明有資料來了,
每個位元組前都有一個space電壓的start位, 表示位元組的開始
在每個位元組的最後都一個parity校正位, 和一個停止位.

資料一般表示為8N1, 表示8個資料位元, 無校正位, 有一個停止位.
7E1 表示7個資料位元, Even偶數校正位, 和一個停止位.


-------------
雙工之雙字,就表示雙向, 接收與發送兩個方向
全雙工系統,  就是同一時刻, 可以同時接收與發送資料,  一個發送線, 一個接收線
半雙工, 在同一時刻, 只能發送, 或只能接收.

----------------
為了協調串列資料流, 有軟體和硬體兩種方法,
軟體方式即是用特殊字元來開始或結束資料流, 這些特殊字元有: 開始的有XON, DC1, 結束的有XOFF, DC3.
硬體方式, 接收方準備好時, 將CTS置為space電壓, 沒有準備好就置為mark電壓.  這樣發送方就知道可以發送資料了.  CLEAR to send, 即告訴發送方可以發送了.
發送方準備好時,  將RTS置為space電壓, 這樣接收方就知道可以接收資料了.   Request to send, 即發送請求發送資料, 讓接收方接收.
這就是CTS/RTS通知機制.  

有資料正在傳輸時, 接收訊號線和發送訊號線, 都會保持在mark電壓. 如果傳著傳著, 從mark電壓掉到space電壓,  並且持續了1/4秒, 說明傳輸break了, 這時break條件就存在了.
break一般被用來重設資料線.

 

---------------  串口線 -------------
串口線的地線是必須串連的, 若只看log, 則只連tx和地線, tx對應白線. 若要通過串口發at命令, 則要tx, rx, 地線三根線.

電源引出的線有可能燒掉, 用萬用表量一下電阻, 正常的會有一個值.

2502引出的uart1, 與藍芽通訊, 接收藍芽發來的At命令, (應該是位元組), 然後2502向藍芽通過串返回資料.

 

--------------  串口log  --------------------

串口線的發送或接收, 都是基於板子命名的, 串口資料從板子出去的, 就叫發送。 串口線裡面,有一條線專門是發送的, 這條線叫發送線, 原理圖上的焊點叫tx。
t (transmit)表示發送,從板子到電腦,
r (receive)接收,從電腦到板子,接收電腦發來的命令。
原理圖上有注釋,uar1 for ap log, 從原理圖對應的pcb圖上找到測試的uart點。


串口線裡有個轉喚器, 白色線表示發送, 綠色線表示接收,黑線表示接地。 一般看串口log,  只用發送,即只連白線與黑線。 如果黑線接到了rx上,即接收點,串口log就是亂碼。

 

lk傳過disable_uart參數決定了,串口是否吐log.  如果lk後面的階段,如kernel, recover模式,如果不吐log. 就要檢查這個參數。

串口如果想吐android log, 就必須在命令列下,輸入logcat。 如果沒有這個命令, 串口是不會吐android log 的。

 

串口可以看到初始化log, preloader, lk, 核心的,串口日誌是非常需要的。usb無法看到初始化日誌。

pcb一般只選pads, vias兩項, 從sch對應找到pcb鐘的測試點

 

需要一個usb轉串口驅動的軟體,如果環境變數有修改,這個軟體就安裝失敗。

用secureCRT看串口log輸出:
從裝置管理員上,找到連接埠,這裡10
串連速率選最大,其它預設
如果有游標,說明連上了,可以看串口log了。


------------- 將串口註冊為一個終端 ------------
tty_io.c 註冊tty裝置

adb shell
setprop persist.uartconsole.enable 1

uart0:ap 側log
uart1: modem側log

如果不接rx拿掉,則無此問題
終端是與外部與電腦互動的一個視窗

------------------------


pty是虛擬終端,
pts, ptmx是pty的實現
每開啟一個終端, /dev/pts/ 下就有一個檔案


先從外部特性認識一下
一個串口(序列埠),就是一個終端,對應/dev/ttySn
在圖形介面下,開啟終端實際是開啟依終端,對應/dev/pts/ 下面的一個檔案,可以開啟終端,看一下pts目錄下多了一個檔案。
用echo "1" > /dev/pts/n 可以看到終端下面出現相應字元。
查看當前終端, 用tty, 如可看到/dev/pts/2
對於/dev/console, 只有單一使用者模式下,才可登入到控制台
用who, 可看到開啟了多少個虛擬終端。
/dev/tty始終代表當前終端,如果當前終端為/dev/pts/2, 則/dev/tty/就代表/dev/pts/2
echo "1" > /dev/tty等同於 echo "1" > /dev/pts/2

ps -aux 的TTY列,顯示在哪個終端上運行


再從代碼上分析實現:
從上層到驅動層:
tty_io.c read
線路層:tty_ldisc.c read 等待隊列機制進入睡眠
驅動層:以串口為例,則應為 serial_core.c


fs_initcall與module_initcall, 都是define_initcall宏函數,被放在vmlinux.lds.s連結指令碼的INIT_CALLS宏指定的init段中,該宏在vmlinux.lds.h中定義。

調用過程: start_kernel-> init-> init線程函數調用do_initcalls來調用這些init函數。

字元裝置初始化(drivers/char/mem.c)主要就是tty初始化,chr_dev_init->tty_init,完成tty裝置初始化,總算看到字元裝置的應用樣本了, 裝置初始化一定會建立裝置模型,

--------------------
串口線中:白線為tx, 即發送線。  綠線為rx. 即接收線。

接上rx線,不會有機器掛掉的問題,把軟體重新firmware upgrade一下,就解決休眠後掛掉的問題,

用rx,向機器發送命令,需要機器亮屏,可使用tab鍵,在usb線不夠用,或usb口不能用時,用rx串口, 一樣看到adb shell所能看到的檔案資訊,調用otg,usb被佔用,這時用串最合適。
若想看log, 可以直接aee -k 6就顯示log.
選中後,可以直接尋找

control+f 進入debug模式, 這個模式能看到arm各寄存器的值,中斷號資訊,

   

開機初始化log只能看串口,因為adb shell就核心完全啟動後的使用者空間的一個進程,所以adb shell 看不到核心初始化的log, 這包括各個驅動的probe初始化log. mtk log建立在檔案系統上,所以也沒有核心初始化log.

preloader lk 核心初始化log都可通過串口看到。 

 有亂碼時,重啟secure  uart就好了。

 

-----------   串列匯流排基本原理  -------------

RS-232是串列匯流排標準.該匯流排按位傳送.
串列匯流排由發送線tx,接收線rx,地線組成.
發送線在發送的同時,接收線可以接收,即非同步通訊
傳輸速率是每秒傳送的位元.單位是bps. 一般一個字元有10位,1個起始位.1個結束位,8個資料位元. 每秒字元數(即資訊包數,一個資訊包含一個字元)乘上字元的位元,即是傳輸速率.
資料位元,一個資訊包有一個開始位,一個結束位.資料位元有的7位,有的是8位.這個要根據協議確定.

停止位一方面表示一個資訊包的結束,一方面提供校正同步時鐘

校正用同位.如果是偶校正,資料1的個數為偶數,校正位就為0. 可以判斷是否有雜訊幹擾了訊號.

uart串連的串列裝置, i2c串連的平行裝置. 
uart一般用於電腦與外部裝置的通訊,如鍵盤等. i2c一般用於內部模組通訊.sensor都是用i2c. gps, 藍芽等射頻相關的都走串口.

顯示器也用串口,有9針串口, 也有25針串口. 

所謂協議,接收方與發送方確定,一個資訊包的每個位表示的含義.雙方對此的理解必須是一致的.

接收過程:由傳輸速率和接收時鐘,確定每一位的時間長度.
當訊號線從1跳到0,表示開始接收.
一偵一幀的接收. 在一幀之內,用時鐘確定接收特定的位.
每隔8個時鐘,來接收一位.

把資料放到寄存器中,在發送時鐘的控制下,將寄存器的資料移位輸出.

在接收端,在接收上升沿的那個時刻,對資料採樣,把資料放到移位寄存器中,組成並行資料取出.

傳輸速率是一秒鐘發送的位元.傳輸速率因子發送或接收一個資料位元需要的時鐘數. 
顯示屏25針的串口有4條資料線,11條控制線,其餘備用線.

 

-----------------------------

串口也可以同步通訊, 這時需要多出一個時鐘線, 因為同步通訊需要硬體上額外支援, 一般不用同步通訊.

訪問串口裝置檔案的方法:
改變串口裝置檔案的許可權, 以讓一般程式可以訪問

一切皆是檔案,  開啟串口裝置, 就中開啟這個檔案, 即
open("/dev/ttyS0", );

進程開啟一個串口裝置, 預設,進程就是這個串口裝置的終端, 控制終端,  串口裝置上的訊號都會影響這個進程, 如ctrl+C這個訊號就會終止這個進程.

如果不想接收這個串口的訊號, 使進程不成為這個串口的終端, 就不會收到串口的訊號了. 用O_NOCTTY.

如果進程不關心另一端是否串連,  即不關心dcd訊號的狀態, 就用O_NODELAY.

向串口可以寫入資料, 發at命令就是寫資料, 用write系統調用. 

從串口讀資料, 就是從串口緩衝區上讀資料,  如果得不到資料, read就不返回.

如果想讓read立即返回, 就要用fcntl設定一下, fcntl(fd, F_SETFL, FNDELAY);

關閉串口, 直接關閉這個裝置檔案即可, 就會將dtr訊號拉低.

CLOCAL與CREAD, 保證程式不會成為連接埠的所有者, 所有者必須處理各種訊號.
options.c_cflag |= (CLOCAL | CREAD);

控制選項還可設定同位.
沒有同位:
options.c_cflag &= ~PARENB
options.c_cflag &= ~CSTOPB
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
奇數校正:

options.c_cflag |= PARENB  // 使能校正位options.c_cflag &= ~PARODDoptions.c_cflag &= ~CSTOPBoptions.c_cflag &= ~CSIZE;options.c_cflag |= CS7;

即c_cflag設定成7E1

偶數校正:
options.c_cflag |= PARENB
options.c_cflag |= PARODD
options.c_cflag &= ~CSTOPB
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS7;
即c_cflag設定成7O1

 

控制選項中設定了同位,  在輸入選項就要把奇偶項剝去, 設定為:

options.c_iflag |= (INPCK | ISTRIP);

如果發生了同位錯誤, DEL字元和NUL字元和出錯的字元一起發出.

 

如果開啟了使能了同位, 又要做一些特別實驗, 如在發生同位錯誤, 也要忽略, 允許存取資料, 可用

options.c_iflag |=IGNPAR;

這時只有NUL字元送出

 

如果硬體上支援cts/rts, 就要設定:
options.c_cflag |= CNEW_RTSCTS
如果不支援:
options.c_cflag &= ~CNEW_RTSCTS;

 

舊的介面沒有c_ispeed,和c_ospeed兩個成員.  所以就用了CBAUD,B9600等傳輸速率常數

常量TCSANOW標誌所有改變必須立刻生效而不用等到資料轉送結束

tcsetattr 可以設定的有:
TCSANOW標誌所有改變必須立刻生效而不用等到資料轉送結束
TCSADRAIN  等待傳輸完之後再生效.

串口串連兩台機器, 傳輸速率應為兩個中較小的那個.

設定一個字元大小:
options.c_flag &= ~CSIZE;
options.c_flag |= CS8; 也可以CS8.

 

 

 

--------------------------

------------------------

 

 

串口 終端(原創)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.