STM--KEIL printf打印--ITM機制(親測成功)

Jlink/STLink自帶一個SWO接口,使用這個接口配合keil可以輸出一些簡單的調試信息,在沒有串口可以使用的時候,SWO也可很方便的打印一些信息,比如F303RE這個板子在我的電腦上一直沒法安裝虛擬串口的驅動,所以我可以用這個SWO輸出調試信息。論壇送的STM32F303RE上自帶的stlink正好有這個SWO口,而且也接到了MCU上,所以正好可以使用,好像有的ST的板子也帶了這個接口,但是其中橋接電阻並沒有貼到板子上,如果要使用的話,就要自己連接起來(比如STM32F429DISCO好像就沒有接上)。



對於stlink的驅動好像也有一些要求,我使用keil4帶的有點舊的stlink驅動就會提示驅動不支持,後來使用keil5帶的stlink驅動據可以了。


如果硬件和軟件都沒有問題了,還需要設置下kei:
首先打開Micro LIB

然後打開keil的Trace功能,具體設置如下:時鐘一定要對應上,否則是亂碼。

然後就是一些重定向printf的函數了,如果之前將printf重定向了串口,那麼要修改並添加如下代碼:

  1. #define ITM_Port8(n)    (*((volatile unsigned char *)(0xE0000000+4*n)))
  2. #define ITM_Port16(n)   (*((volatile unsigned short*)(0xE0000000+4*n)))
  3. #define ITM_Port32(n)   (*((volatile unsigned long *)(0xE0000000+4*n)))

  4. #define DEMCR           (*((volatile unsigned long *)(0xE000EDFC)))
  5. #define TRCENA          0x01000000

  6. struct __FILE { int handle; /* Add whatever needed */ };
  7. FILE __stdout;
  8. FILE __stdin;

  9. int fputc(int ch, FILE *f) {
  10.   if (DEMCR & TRCENA) {
  11.     while (ITM_Port32(0) == 0);
  12.     ITM_Port8(0) = ch;
  13.   }
  14.   return(ch);
  15. }

複製代碼

打開調試即可得到調試信息:

輸出調試信息

測試代碼:
F303RE_SWO.rar(394.54 KB, 下載次數: 307)


*******************************************一天過去了***************************************
上面說了輸出的功能,其實如果需要的話,重定向下scanf()函數即可完成從Debug Viewer向程序輸入參數的,這在調試某些需要動態調整參數的程序裏面應該有幫助,比如按下某個按鍵,激活輸入功能,重新配置下參數,然後繼續運行程序。
調試的時候有個變量在一直檢測是否有數據輸入,如果有數據輸入,那麼輸入的數據就傳到這個變量,這個接口在內核的頭文件有相關的定義,我們只需要定義這個變量即可。
將下面的main.c代碼完整的替換掉上面的mian.c就可以使用了。
  1. #include "main.h"
  2. #include "string.h"
  3. //SWV test
  4. //2015-6-15
  5. //by creep
  6. #define ITM_Port8(n)    (*((volatile unsigned char *)(0xE0000000+4*n)))
  7. #define ITM_Port16(n)   (*((volatile unsigned short*)(0xE0000000+4*n)))
  8. #define ITM_Port32(n)   (*((volatile unsigned long *)(0xE0000000+4*n)))

  9. #define DEMCR           (*((volatile unsigned long *)(0xE000EDFC)))
  10. #define TRCENA          0x01000000

  11. struct __FILE { int handle; /* Add whatever needed */ };
  12. FILE __stdout;
  13. FILE __stdin;

  14. volatile int32_t ITM_RxBuffer=ITM_RXBUFFER_EMPTY;

  15. int fputc(int ch, FILE *f) {
  16.   if (DEMCR & TRCENA) {
  17.     while (ITM_Port32(0) == 0);
  18.     ITM_Port8(0) = ch;
  19.   }
  20.   return(ch);
  21. }
  22. int fgetc(FILE *f)
  23. {
  24.         while(ITM_CheckChar() == 0)
  25.         {               
  26.         }
  27.         return ITM_ReceiveChar();
  28. }

  29. u8 Write_buff[30] = "\n\r\n\rPlease enter your name:\n\r";
  30. u8 read_buff[50]= "";
  31. u8 name[100]="\n\rYour name is : ";
  32. int main(void)
  33. {
  34.         static u8 led_sta = ON;
  35.     LED_Init();
  36.     delay_init();
  37.                 delay_ms(1000);
  38.     while(1)
  39.     {
  40.                                 //將數據發送到Debug Viewer
  41.                                 printf((const char*)Write_buff);
  42.                                 memset(read_buff,0,50);
  43.                                 //等待輸入
  44.                                 scanf("%s",read_buff);
  45.                                 //將姓名輸出
  46.                                 printf((const char*)name);
  47.                                 printf((const char*)read_buff);
  48.                                 LED(led_sta);
  49.                                 led_sta = !led_sta;
  50.         delay_ms(1000);
  51.     }
  52. }



複製代碼
直接在debug viewer窗口輸入內容然後回車即可,輸入的內容不會回顯在窗口中,輸入也支持中文。運行結果如下:



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