STM32中标准输入输出导致的程序崩溃问题

作者在开发环境检测设备时遇到程序在包含fprintf函数的cJSON修改后直接崩溃。经分析,问题出在链接阶段,由于printf依赖于底层未实现的I/O接口。解决方法是避免使用printf或提供相应接口实现。
摘要由CSDN通过智能技术生成

一、背景

        笔者正在写一个以stm32为微控制器的环境检测设备,将数据通过wifi模块上传到云服务的程序。当写到数据解析部分的时候,使用了cJSON库。并在cJSON库中做了一些修改。

        奇怪的问题来了,本来烧录程序后,应该先运行设备初始化等信息才对 (如下图)

 

         但是当我移植cJSON库并且修改了代码后,发现程序直接跑崩溃了,我甚至还没调用相关的json解析函数,怎么就能跑丢了呢?

 

二、分析

        理论上程序如果产生段错误,堆栈溢出等现象,会在运行时才崩溃,这还没运行到这个函数呢呢,说明bug不是产生在运行时,那么设想一下程序编译运行的几个步骤:预处理->编译->汇编->链接->可执行文件。

        很显然 (其实也不显然,折磨了我一个下午) 就联想到,是不是在链接的时候出的问题。我就找到了我新增的函数部分。慢慢调试。 

这里我使用了#if 预处理指令方便调试,可以发现当编译包含了fprintf语句时,程序直接崩溃,而不编译这段程序则正常输出。

那么本质问题是什么呢?

        在许多嵌入式系统和特别是裸机环境中,标准C库函数(如 printf)可能依赖于底层的I/O实现,这通常需要开发者提供,比如 putchar_write 等函数。这些底层函数可能与具体的硬件接口(例如UART)交互,而这些接口在嵌入式环境中可能没有默认实现。如果这些函数没有被正确实现但被调用了,可能会导致不确定的行为或运行时错误。这种情况下的“错误”通常不会在编译阶段捕捉到,因为从编译器的角度看,printf 是一个完全合法的函数调用。问题通常在链接阶段或运行时暴露出来,因为那时缺少了实际的函数实现。

        所以解决办法,就是不使用fprintf或者printf啦,或者将printf重定向,重写putchar、wirite函数的实现即可。故在keil中要慎用标准输入输出!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值