RDK中的Vps_printf()與Vps_rprintf()

=======================================================================================================

轉載請註明原文地址: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, ...)
02 {
03     int retVal;
04     va_list vaArgPtr;
05     char *buf = NULL;
06     UInt32 cookie;
07  
08     cookie = Hwi_disable();
09  
10     buf = &gRemoteDebug_serverObj.printBuf[0];
11  
12     va_start(vaArgPtr, format);
13     vsnprintf(buf, REMOTE_DEBUG_SERVER_PRINT_BUF_LEN, format, vaArgPtr);
14     va_end(vaArgPtr);
15  
16     retVal = RemoteDebug_serverPutString(gRemoteDebug_serverObj.coreId, buf);
17  
18     Hwi_restore(cookie);
19  
20     if (BIOS_getThreadType() == BIOS_ThreadType_Task)
21     {
22         /* Printf should be called only from Task context as it does pend.
23          * Calling from other context will cause exception
24          */
25         System_printf(buf);
26     }
27  
28     return (retVal);
29 }
01 int Vps_rprintf(char *format, ...)
02 {
03     int retVal;
04     va_list vaArgPtr;
05     char *buf = NULL;
06     UInt32 cookie;
07  
08     cookie = Hwi_disable();
09  
10     buf = &gRemoteDebug_serverObj.printBuf[0];
11  
12     va_start(vaArgPtr, format);
13     vsnprintf(buf, REMOTE_DEBUG_SERVER_PRINT_BUF_LEN, format, vaArgPtr);
14     va_end(vaArgPtr);
15  
16     retVal = RemoteDebug_serverPutString(gRemoteDebug_serverObj.coreId, buf);
17  
18     Hwi_restore(cookie);
19  
20     return (retVal);
21 }
       由上面兩端代碼可以很明顯的看出Vps_printf()和Vps_rprintf()的前半部分都是講輸出到共享內存中供A8側打印線程輸出,唯一的區別就是Vps_printf()會 判斷當前thread類型是否是Task,如果是Task則調用SYS/BIOS下的System_printf(),將數據輸出到對應處理器的串口或者是Circular Buffer中。

       在Vps_printf()中有下列註釋:

1 /* Printf should be called only from Task context as it does pend.
2  * Calling from other context will cause exception
3  */
即表示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問答:鏈接地址

鏈接地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章