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窗口的信息感知到。

发布了436 篇原创文章 · 获赞 126 · 访问量 175万+

猜你喜欢

转载自blog.csdn.net/LostSpeed/article/details/92111589
今日推荐