zoukankan      html  css  js  c++  java
  • stm32 不使用MircoLib情况下使用printf方法

    不使用Microlib导致卡死的原理
    在使用CubeMX初始化代码时,生成的工程默认是使用Microlib的,正常情况下,在STM32CubeMX通过成的.s文件里可以看到一个__main函数,这个就是microlib的入口地址,他会完成创建栈空间,创建堆空间,初始化用户可能用到的系统库等初始化动作,最后跳转到我们熟悉的main,当使用Microlib时,__main链接的是Microlib,当不使用Microlib时,__main链接的是标准库的C/C++;

     

    至此,还并没有出现什么问题,但是,一旦在程序中调用printf等函数时,会让MCU进入半主机模式,进而程序会在__main位置卡死,这也就是为什么程序正常编译正常烧录正常调试,但是运行不起来而且Debug卡死在__main位置的原因。


    使用C标准库(stdio.h)中的函数,例如printf()之类的函数,会进入半主机模式,发生软件异常,会导致程序无法运行。半主机是这么一种机制,它使得在ARM目标上跑的代码,如果主机电脑运行了调试器,那么该代码可以使用该主机电脑的输入输出设备。 这点非常重要,因为开发初期,可能开发者根本不知道该 ARM 器件上有什么输入输出设备,而半主基机制使得你不用知道ARM器件的外设,利用主机电脑的外设就可以实现输入输出调试。 所以要利用目标 ARM器件的输入输出设备,首先要关掉半主机机制。然后再将输入输出重定向到 ARM 器件上。

    解决办法:

    1、使用Microlib

    2、关闭标准库下的半主机模式

    这里我们就学习一下如何不使用Microlib,关闭半主机模式

    在main.c文件或者其他任何一个文件中添加如下代码段

    #pragma import(__use_no_semihosting)
    //标准库需要的支持函数
    struct __FILE 
    {
      int handle; 
    };
    
    FILE __stdout;
    //定义_sys_exit()以避免使用半主机模式  
    void _sys_exit(int x) 
    { 
      x = x; 
    }

      void _ttywrch(int ch)
      {
        ch = ch;
      }

    //重定义fputc函数
    int fputc(int ch, FILE *f)
    {
        HAL_UART_Transmit(&DEBUG_UART, (uint8_t *)&ch, 1, 0x200);  //根据使用的库重定向
      return ch;
    }
    Talk is cheap, show me the code
  • 相关阅读:
    JavaScript 数组去重
    Javascript数组 reduce() 方法
    Vue事件总线(EventBus)
    前端多媒体-音频
    前端多媒体-视频
    VUE3.0 总结
    el-select地区区号选择
    vue中点击获取相应元素
    Markdown 语法
    Codeforces Round #295 (Div. 2) B. Two Buttons 520B
  • 原文地址:https://www.cnblogs.com/birdBull/p/15697213.html
Copyright © 2011-2022 走看看