車機項目中用到了很多序列槽外設,如DVD機芯、GPS、藍牙、雷達和胎壓監測等,而主CPU(TCC89XX)與小MCU(STM32)之間也是通過序列槽通訊的。一時之間,序列槽使用有點捉襟見肘的感覺,隻能把調試序列槽拿出來用做普通序列槽。
調試序列槽用作普通序列槽本身沒什麼問題,之前在S3C2410上也做過。當時是把2410的調試序列槽強制改為普通序列槽,系統啟動後調試序列槽就無法正常使用了。但目前的項目仍在進一步完善之中,調試序列槽還是相當重要的,經常需要通過它,抓一些TRACE來分析和定位問題。是以,希望UART0能在調試序列槽和普通序列槽之間友善切換。
同一時刻,UART0既用作調試序列槽,又用作普通序列槽似乎不可能,并且意義也不大。考慮了一個簡單的方法,系統預設将UART0用作普通序列槽,需要抓取TRACE時,在應用程式中配置UART0的工作模式為調試序列槽,然後重新開機系統。
1 void OEMInitDebugSerial()
2 {
3 pVirtualBOOTARGS = (tSYSTEM_PARAM *)OALPAtoVA(SYSTEM_PARAM_BASEADDRESS,FALSE);
4 }
此處增加了擷取系統配置參數的虛拟位址。
1 //------------------------------------------------------------------------------
2 //
3 // Function: OEMWriteDebugString
4 //
5 // Output unicode string to debug serial port
6 //
7 VOID OEMWriteDebugString(UINT16 *string)
8 {
9 if (!pVirtualBOOTARGS->SysConfig.fDisableDebugSerial)
10 {
11 while (*string != L'\0') OEMWriteDebugByte((UINT8)*string++);
12 }
13 }
其中,pVirtualBOOTARGS->SysConfig.fDisableDebugSerial為控制調試序列槽是否正常輸出字元的變量。SysConfig是儲存在NAND Flash中特定區域的一個結構體,BOOT啟動時可以讀取到,并且放在記憶體的指定位置。應用程式中可以修改該結構,相關代碼如下。
1 void SysDisableDebugSerial(int nDisable)
2 {
3 GetSysConfig(&gSYSCONFIG);
4 gSYSCONFIG.fDisableDebugSerial = nDisable;
5 SetSysConfig(&gSYSCONFIG);
6 }
7
8
9
10 void CSysAppDlg::OnBnClickedCheckDebugserial()
11 {
12 // TODO: 在此添加控件通知處理程式代碼
13 CReg Reg;
14
15 UpdateData(TRUE);
16 SysDisableDebugSerial(m_bDisableDebugSerial);
17
18 Reg.Open(HKEY_LOCAL_MACHINE, _T("Drivers\\BuiltIn\\Serial3"), KEY_ALL_ACCESS);
19 Reg.SetSZ(_T("Dll"), m_bDisableDebugSerial ? _T("tcc_serial.dll") : _T("-tcc_serial.dll"));
20 Reg.Flush();
21 }
可以看到,在修改變量fDisableDebugSerial的同時,還需要修改UART0對應的系統資料庫。在禁用調試序列槽時,DLL鍵值設定為正确的,在啟用調試序列槽時,DLL鍵值前加一個中橫杠。確定UART0要麼用作調試序列槽,要麼用作普通序列槽,二者必居其一。應用程式設定界面如下圖所示。

經測試,以上修改基本達到了預計的效果,實作了WinCE下調試序列槽的動态複用。