在計算機系統中,串口是“古老”的通信方式,和它同時代的“并口”通信方式已經消失了。但它仍然頑強的存活著,主要原因是在開發和調試底層軟件時還經常用到串口。
正因為有這樣的需求,幽蘭代碼本是支持串口的,而且有兩種方式。第一種是主板上接頭,需要打開后蓋。第二種方式是通過SD卡接口,不需要打開后蓋,非常方便,得到很多蘭友的好評。
比幽蘭更早的GDK8也支持串口,但是要打開后蓋。不夠方便,因為此,這幾天在準備GDK8的新版本鏡像時,我根據GDK8用戶的意見提了一個需求,把幽蘭的SD串口做法應用到GDK8上。
格蠹的小伙伴Jack接到這個需求,這兩天在著手實現。
Jack是格蠹的老程序員了,有比較豐富的底層開發經驗。為了方便寫代碼和試驗,他輕車熟路地選擇用“劉姥姥”驅動做原型。
GDK8使用的是RK3328 SoC。與幽蘭使用的RK3588 SoC相似,3328的串口信號也是與SD卡信號復用的,而且復用的都是2號串口,即UART2。
?不同的是,3328的UART2有兩種連接模式,分別稱為UART2m0和UART2m1。下面這張表來自RK3328 TRM的第17章接口描述一節。
對于上表中的m縮寫,手冊中沒有給出任何解釋,很讓軟件工程師困惑。
雖然m的含義不是很明確,但因為m0接口是與SD信號復用的,所以應該按m0方式來設置寄存器。Jack這樣修改劉姥姥驅動,把改寄存器的想法轉化為代碼。
臨近中飯時,Jack報告第一個壞消息,“寄存器不能寫”。
考慮到這個任務有難度和重要性,我走過去和他一起看寄存器的描述。
首先,RK的SPEC中有時也有明顯的錯誤,比如上面截圖中的GRF_COM_MUX應該是GRF_CON_MUX,CON是Control的縮寫,MUX是復用的縮寫。
RK的很多寄存器都是一個套路:高16位是掩碼,低16位負責具體功能,高位為1時,低位的值才有效。但這個規則在上表中解釋的很啰嗦。Jack說話很少,交流一番,他可能是被解釋中的“when bit16=0, bit 0 cannot be written by software”迷惑了。也可能是被冗長的spec搞暈頭了。
午飯后,我看Jack的代碼,發現一個明顯的問題。
我們要選擇m0模式,按照第一張截圖中表格下面的描述,需要把GRF_CON_MUX[0]寫為0。寫寄存器時應該寫0x10000。但可能是被SPEC中的真真假假搞暈,Jack的代碼里把本來想寫的0x30000寫成了30000。16進制變成10進制了。
糾正了這個bug后,寄存器寫成功了。GRF_CON_IOMUX[0]位成功被設置為0。
這個比特位的設置之前為1,說明是工作在m1模式。我特意與GDK8的硬件工程師確認,GDK8主板上的串口使用的正是UART2m1。
但寄存器寫成功的喜悅還沒持續幾分鐘,Jack報告了第二個壞消息:接了SD串口轉接頭后,主機端還是收不到串口數據。
我說是不是軟件寫的設備文件不對,Jack說他寫了個腳本,把dev下的所有串口設備都試過了。
對于通信問題來說,收不到數據是最讓人頭痛的。剛好今天早上,我順手把調試WIFI驅動的幾張截圖發到WOA技術群,引來多位同行發表感想,普遍覺得涉及到通信的問題有很多坑。
還有真實的案例。
看到Jack前進受挫,我決定放下手頭的其它事情,進來助力。
一方面,先匯總手頭的各種信息,做些歸納和總結,夯牢基礎。查看RK3328硬件設計手冊,3328的最初開發板EVB也是使用UART2m1方式來做調試口。根據硬件工程師的回復,GDK8是沿用了EVB的設計。GDK8主板背面的TX、RX、GND三個信號是便是UART2m1實物。
其實,這個設計也延續到幽蘭使用的RK3588,也是使用UART2做為默認的調試口。
另一方面,我聯系做硬件的Intel老同事,請他幫忙解釋SPEC中m縮寫的含義。
術業有專攻,硬件工程師果然不一樣,明確給出了m縮寫的含義。
清楚了m縮寫的含以后,我徹底明白了SPEC的意思,腦海中浮現出一張比較清晰的硬件路線圖。
有了這個路線圖之后,我更加堅定了信念,認為這個方向是可以走的通的。為了避免單一試驗的局限性,我決定增大投入,安排小伙伴Bob也投入戰斗,搭建環境,編譯新代碼。
?但還沒有等到Bob把新環境搭建好,Jack發出好消息:
上面這條信息是從GDK8上通過SD轉接頭發送到主機端的,也就是說,是以新規劃的m0路線傳遞的。這條消息代表新的串口通道打通了!
我詢問Jack哪里做了改動,原來只是改了波特率。因為以前使用m1方式調試時,dts里配置的波特率是115200,所以下午試驗時誤以為還是這個值,但其實根據UART_DLL和UART_DLH寄存器的值計算,應該是1.5M。
dlh=1,uart_clk_sel=2’b10-24mhz,波特率=24m/(1*16)=1.5
經過一天的努力,期待許久的串口新通道終于打通了。回顧整個過程,其實主要的改動就是配置寄存器。
一件事情,做成功了之后,再回頭看就覺得沒什么復雜,但是在沒有做成之前,則充滿了困惑。對于這個問題,有很多可能失敗和放棄。雖然失敗也是一種選項,可它是無法和成功相比的。
GDK8是2021年發布的,在硬件高速度發展的今天,有些人可能覺得它有些老了,但其實,對于很多用戶來說,GDK8具有很多不可多得的優點,比如:
- 非常穩定地支持JTAG調試。
-?超低功耗,開機半個月也用不到一度電,所以有些用戶從不關機。
- 積累了大量文檔、代碼以及開發經驗,比如今天這樣的踩坑實踐。
-?小巧玲瓏,節約空間。
今天,它又多了一個優點,可以非常方便的通過SD插槽連接串口。手里有GDK8的小伙伴可以親自體驗一下!對于沒有GDK8的朋友,有一種特殊的方式可以得到GDK8 +?揮碼槍伴侶,那就是參加格蠹的調試研習班,人手一套。研習班的上海站正在招生之中。
(寫文章很辛苦,懇請各位讀者點擊“在看”,也歡迎轉發)
*************************************************
正心誠意,格物致知,以人文情懷審視軟件,以軟件技術改變人生
掃描下方二維碼或者在微信中搜索“盛格塾”小程序,可以文章和有聲讀物
也歡迎關注格友公眾號