在單片機(jī)的軟件開發(fā)中,經(jīng)常會(huì)遇到各種各樣的問題,很多時(shí)候?yàn)榱硕ㄎ坏匠霈F(xiàn)bug的地方,我們可能會(huì)借助很多的手段或者工具。比如串口打印、MDK在線仿真、上位機(jī)調(diào)試工具等等的。但是,有時(shí)候想要用串口打印輸出某些結(jié)果,而硬件設(shè)計(jì)又沒有預(yù)留串口,這種時(shí)候就感覺很不方便。我個(gè)人使用串口調(diào)試的頻率還是蠻多的,主要是簡(jiǎn)單易操作,可以在想要觀察運(yùn)行結(jié)果的代碼位置隨便加調(diào)試輸出,很方便定位問題。在硬件上沒有多余的串口預(yù)留的話,如果有外接仿真引腳出來的話,在MDK環(huán)境下就可以使用ST-LINK、J-LINK等的各種LINK進(jìn)行調(diào)試,實(shí)現(xiàn)printf輸出的功能,簡(jiǎn)直是不要太棒了!在MDK的開發(fā)IDE環(huán)境下,支持仿真調(diào)試的組件有好幾個(gè),我這里使用的是Event Recorder。這個(gè)組件功能是在MDK5.22的版本是哪個(gè)開始增加的,所以想要使用這個(gè)組件功能,需要將自己的MDK開發(fā)工具升級(jí)到5.22以上,建議是當(dāng)前最新的版本!
1、添加 Event Recorder 組件
1)打開你需要添加調(diào)試組件的項(xiàng)目工程,點(diǎn)擊如下圖所示的圖標(biāo):
2)選擇 “Compiler”,并按照如下勾選,勾選之后點(diǎn)擊“ok”即可。如下圖:
勾選之后可以看到工程目錄上出現(xiàn)一個(gè)“Compiler”的選項(xiàng),說明組件添加成功了,如下圖:
3)檢查組件的工程配置,如下:
說明如下:
Number of Records:表示 Event Recorder 緩沖可以記錄的消息條數(shù)。Time Stamp Source:表示時(shí)間戳的來源其中,Time Stamp Source 有如下四種可以選擇,一般使用 DWT 時(shí)鐘周期計(jì)數(shù)器。如下圖:
至此,Event Record組件就已經(jīng)添加完成了。
2、printf 重定向
在Event Recorder 實(shí)現(xiàn)printf輸出需要使用MDK的 Debug 功能,輸出的效果就跟串口調(diào)試工具上的顯示效果是一樣的。Event Recorder 中的重定向代碼如下:
int fputc (int c, FILE * stream) {
#if (!defined(RTE_Compiler_IO_STDOUT) && !defined(RTE_Compiler_IO_STDERR))
(void)c;
(void)stream;
#endif
#ifdef RTE_Compiler_IO_STDOUT
if (stream == &__stdout) {
#if (STDOUT_CR_LF != 0)
if (c == 'n') stdout_putchar('r');
#endif
return (stdout_putchar(c));
}
#endif
#ifdef RTE_Compiler_IO_STDERR
if (stream == &__stderr) {
#if (STDERR_CR_LF != 0)
if (c == 'n') stderr_putchar('r');
#endif
return (stderr_putchar(c));
}
#endif
return (-1);
}
注意:使用 Event Recorder 實(shí)現(xiàn)printf重定向時(shí),一定要取消掉自己的項(xiàng)目中原本的重定向!
1)進(jìn)入仿真調(diào)試模式,如下:
2)選中 Debug(printf)Viewer 調(diào)試組件,如下圖:
3)選擇仿真時(shí)周期更新,如下圖:
4)添加初始化代碼,如下:
/* 初始化 EventRecorder 并開啟 */
EventRecorderInitialize(EventRecordAll, 1U);
EventRecorderStart();
5)全速運(yùn)行即可以看到結(jié)果。
示例:
測(cè)試代碼如下:
仿真結(jié)果如下:
鼠標(biāo)右鍵還可以對(duì) Debug(printf)Viewer 進(jìn)行設(shè)置,如下圖:
3、簡(jiǎn)單方便的時(shí)間測(cè)量功能
Event Recorder 也可以測(cè)量代碼運(yùn)行的時(shí)間,時(shí)間測(cè)量功能簡(jiǎn)單易用,僅需一個(gè)起始函數(shù),一個(gè)停止函數(shù)即可。
3.1、時(shí)間測(cè)量起始函數(shù)
EventStartG (slot)
或者
EventStopGv (slot, val1, val2)
函數(shù)說明:
1)函數(shù)中的字母 G 是表示分組 A,B,C,D,即實(shí)際調(diào)用函數(shù)為 EventStartA,EventStartB,EventStartC 和 EventStartD。2)函數(shù)的第一個(gè)形參 slot 的范圍是 0-15,也就是最大可以測(cè)量 16 路。3)函數(shù)后面的兩個(gè)形象 val1 和 val2 是 32 Bit變量,用戶可以用這兩個(gè)形參來傳遞變量數(shù)值給 Event Statistics 調(diào)試組件里面,用于圖形化展示。
3.2、時(shí)間測(cè)量結(jié)束函數(shù)
EventStopG (slot)
或者
EventStopGv (slot, val1, val2)
函數(shù)說明:
1)函數(shù)中的字母G是表示分組A,B,C,D,即實(shí)際調(diào)用函數(shù)為EventStopA,EventStopB,EventStopC 和 EventStopD。2)函數(shù)的第一個(gè)形參 slot 的范圍是 0-15,也就是最大可以測(cè)量 16 路。3)函數(shù)后面的兩個(gè)形象 val1 和 val2 是 32 位變量,用戶可以用這兩個(gè)形參來傳遞變量數(shù)值給 Event Statistics 調(diào)試組件里面,用于圖形化展示。
3.3、使用示例
1)添加初始化代碼
/* 初始化 EventRecorder 并開啟 */
EventRecorderInitialize(EventRecordAll, 1U);
EventRecorderStart();
2)在代碼前后加上起始和結(jié)束時(shí)間的測(cè)量API函數(shù),如下所示:
3)選擇 Event Statistics 調(diào)試組件,如下:
4)全速運(yùn)行,查看結(jié)果,如下:
從圖中可以看出,開始測(cè)量的位置是在 149 行處,結(jié)束測(cè)量的位置是在152 行處,下方的紅色方框處標(biāo)出了測(cè)量的最大時(shí)間和最小時(shí)間。
-
單片機(jī)
+關(guān)注
關(guān)注
6037文章
44558瀏覽量
635301 -
軟件開發(fā)
+關(guān)注
關(guān)注
0文章
614瀏覽量
27360 -
上位機(jī)
+關(guān)注
關(guān)注
27文章
942瀏覽量
54814
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論