=======================================================================================================
轉載請註明原文地址:http://blog.csdn.net/crushonme/article/details/14517109
=======================================================================================================
最近在TI的e2e以及相關QQ羣衆討論時很多同學在做DSP算法或者在使用中斷時SYS/BIOS被異常掛起,最終分析下來的原因是因爲在中斷上下文中使用了Vps_printf()或者是在禁止中斷後恢復中斷前的期間內使用了Vps_printf(),即hwi_disable()和hwi_restore()的上下文中使用。
在TI提供的RDK(包括DVRRDK和IPNCRDK)中Ducati-M3和DSP中運行的實時操作系統爲SYS/BIOS,在SYS/BIOS中輸出到串口的打印API爲System_printf()。提供的能輸出到linux串口的API即爲Vps_printf()和Vps_rprintf()。
下面我們來分析下Vps_printf()和Vps_rprintf的源代碼和相關限制。
首先我們來看下兩個API的實現代碼:
01 |
int Vps_printf( char *format,
...) |
08 |
cookie
= Hwi_disable(); |
10 |
buf
= &gRemoteDebug_serverObj.printBuf[0]; |
12 |
va_start (vaArgPtr,
format); |
13 |
vsnprintf(buf,
REMOTE_DEBUG_SERVER_PRINT_BUF_LEN, format, vaArgPtr); |
16 |
retVal
= RemoteDebug_serverPutString(gRemoteDebug_serverObj.coreId, buf); |
20 |
if (BIOS_getThreadType()
== BIOS_ThreadType_Task) |
01 |
int Vps_rprintf( char *format,
...) |
08 |
cookie
= Hwi_disable(); |
10 |
buf
= &gRemoteDebug_serverObj.printBuf[0]; |
12 |
va_start (vaArgPtr,
format); |
13 |
vsnprintf(buf,
REMOTE_DEBUG_SERVER_PRINT_BUF_LEN, format, vaArgPtr); |
16 |
retVal
= RemoteDebug_serverPutString(gRemoteDebug_serverObj.coreId, buf); |
由上面兩端代碼可以很明顯的看出Vps_printf()和Vps_rprintf()的前半部分都是講輸出到共享內存中供A8側打印線程輸出,唯一的區別就是Vps_printf()會 判斷當前thread類型是否是Task,如果是Task則調用SYS/BIOS下的System_printf(),將數據輸出到對應處理器的串口或者是Circular
Buffer中。
在Vps_printf()中有下列註釋:
即表示Vps_printf()只能被用於Task任務類型的 thread,在其他類型的thread中會導致異常情況。( thread未翻譯成線程,因爲這裏的thread和我們通常理解的線程有差異)
此外,需要注意的是在Vps_printf()和Vps_rprintf()的實現中均需要屏蔽硬件中斷,因此不能用於硬件中斷類型的thread。下面有個童鞋使用的錯誤的例子:
注:
1、在SYS/BIOS下線程可以分爲以下幾類,如下圖所示:
2、SYS/BIOS下的System_printf()可以配製成兩種模式,一種是輸出到串口,另一種是將內容輸出到SYS/BIOS下配置的靜態circular buffer中。System_printf()的靜態circular buffer配置及輸出方式配置如下圖所示:
相關文檔:
1、SYS/BIOS wiki:鏈接地址
2、SYS/BIOS API: 鏈接地址
3、e2e問答:鏈接地址
鏈接地址