caohenry999

今天我用到RTX里面使用printf ,发现程序死掉了

我发现很多人遇到了这样的问题

找了网上很多的文章,说是这个是RTX的一个先天不足的问题

我发现了正点原子的 原子哥的解决方案,如下所示:

-------------------------------------------------------------------------------

产生原因:

   使用库里的printf函数在输出结束后会调用__used void _mutex_acquire (OS_ID *mutex)这个方法,

   但是传入的参数mutex并未进行初始化,所有内存访问地址出错。造成hardfault

解决方案:
1.修改RTX_Lib.c文件中的__used void _mutex_acquire (OS_ID *mutex)函数,在函数开始部分手动初始化互斥量。
__used void _mutex_acquire (OS_ID *mutex) {
  /* Acquire a system mutex, lock stdlib resources. */
    static int initialized = 0;
    if (initialized == 0)
    { /* initialize the mutex */
        _mutex_initialize(mutex);
        initialized = 1;
    }//printf使用进入硬件中断的解决方法
    if (runtask_id ()) {
    /* RTX running, acquire a mutex. */
    mutex_wait (*mutex);
  }
}

2.重定义ferror函数,因为此函数是被库中的ferro函数调用的。
int ferror(FILE *f)
{
    return EOF;
}

两个方法都可以解决该问题。

----------------------------------------------------------------------------------------------------

以上的两种情况 我都使用了,但是发现 :

方法1还是有问题,在任务调度之后还是软件死掉了;

方法2 目前使用软件正常;

 

以下的代码可以放在 uUARTx_printf.c 中,然后把这个文件放在你的开发工程文件列表中加入编译

代码包含了 fputc重新定向

 1 /* Includes ------------------------------------------------------------------*/
 2 #include "stm32f10x.h"
 3 #include "stdio.h"
 4 
 5 
 6 //加入以下代码,支持printf函数,而不需要选择use MicroLIB      
 7 #if 1
 8 #pragma import(__use_no_semihosting)             
 9 //标准库需要的支持函数                 
10 struct __FILE 
11 { 
12     int handle; 
13 
14 }; 
15 
16 FILE __stdout;
17 
18 //定义_sys_exit()以避免使用半主机模式    
19 void _sys_exit(int x) 
20 { 
21     x = x; 
22 }  
23 //重定义fputc函数 
24 int fputc(int ch, FILE *f)
25 {      
26     
27     /*
28     while((USART1->SR&0X40)==0);
29     USART1->DR = (u8) ch;      
30     */
31     //while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);        //等待上次发送结束
32     //USART_SendData(USART1, (unsigned char)ch);                //发送数据到串口
33     
34     
35     
36     while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){}
37     USART_SendData(USART1, (unsigned char)ch);
38     while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET){}
39     
40     
41     return ch;    
42 }
43 
44 
45 int ferror(FILE *f)
46 {
47     return EOF;
48 }
49 
50 #endif 

 

感谢原子哥的方法

也希望更多的人,有更好的办法解决这个问题

大家讨论解决方案

 

相关文章: