zoukankan      html  css  js  c++  java
  • [原创]RTX使用printf输出后进入hardfault中断的处理方法

    今天我用到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 

    感谢原子哥的方法

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

    大家讨论解决方案

  • 相关阅读:
    [安装程序配置服务器失败]解决SQL Server2000安装失败
    C# 操作 XML 增 删 改 查
    批量修改文件的编码格式
    获取SqlServer2005表结构(字段,主键,外键,递增,描述)
    .NET 特性Attribute[一]
    windows2003远程桌面退出后系统自动注销的解决方法
    SqlServer 无日志文件附加
    接受来自服务器的数据连接时发生超时(30000 毫秒)问题原因及解决方法
    .net中数据集合导出为Excel(支持泛型及显示字段顺序,可自定义显示列名)
    EF中自编写SQL脚本查询结果(适用于复杂SQL逻辑提高查询效率)
  • 原文地址:https://www.cnblogs.com/caohenry999/p/12957503.html
Copyright © 2011-2022 走看看