ITM printf nothing with ucOS-II

前言

在產品板子(STM32F407 + ucOS-II)上, 加入printf後,用MDK單步時,必然進入HardFault.
開始懷疑是硬件問題,於是用開發板先驗證程序是否寫錯?
後來發現是編譯前勾選了微庫, 不勾選微庫, 就不會進入HardFault.

	// 不能勾選微庫(Target => Code Generation => Use MIcroLIB), 否則啓動ucOS任務後,會進入HardFault
	// 浮點運算選上(407支持浮點運算)

然後看printf是否能打印到MDK串行調試窗口。
先改fputc實現。

#include <stdio.h>

#define ITM_Port8(n)    (*((volatile unsigned char *)(0xE0000000+4*n)))
#define ITM_Port16(n)   (*((volatile unsigned short*)(0xE0000000+4*n)))
#define ITM_Port32(n)   (*((volatile unsigned long *)(0xE0000000+4*n)))
#define DEMCR           (*((volatile unsigned long *)(0xE000EDFC)))
#define TRCENA          0x01000000

//////////////////////////////////////////////////////////////////
//加入以下代碼,支持printf函數,而不需要選擇use MicroLIB	  
#if 1
#pragma import(__use_no_semihosting)             
//標準庫需要的支持函數                 
struct __FILE 
{ 
	int handle; 
}; 

FILE __stdout;       
//定義_sys_exit()以避免使用半主機模式    
_sys_exit(int x) 
{ 
	x = x; 
} 
//重定義fputc函數 
int fputc(int ch, FILE *f)
{ 	
	if (DEMCR & TRCENA) 
	{
			while (ITM_Port32(0) == 0);
			ITM_Port8(0) = ch;
	}

	return(ch);
		
	/*
	while((USART1->SR&0X40)==0);//循環發送,直到發送完畢   
	USART1->DR = (u8) ch;      
	return ch;
	*/
}
#endif

程序跑起來後,設置正確的前提下,printf信息無法打印到MDK串行調試窗口。
然後試了開發板對應的ucOS-III工程,printf可以正常打印到MDK串行調試窗口。

結論

ucOS-II不兼容printf, 更準確的說,是不支持F407的ITM.
因爲以前維護過一個F103的ucOS-II的工程,是可以正常將printf信息打到MDK調試窗口的。

本來維護工程的原則,都是要保持最小化的修改,防止帶入更多的bug。
這下,不得已要將工程將ucOS-II遷移到ucOS-III去。
這樣可以用MDK帶着板子長時間跑, 不加斷點全速跑,如果有潛在錯誤,可以通過printf打到MDK窗口的信息感知到。

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