STM32 使用sprintf 导致死机的一个解决方法

 我在使用sprintf 进行字符串格式化处理的时候,一执行到sprintf,STM32就死机(必死),看了很多博客,包括

 但是都没能解决问题。

经过两天的摸索,终于在机缘巧合之下,让我到了解决方法!

原理我没有办法解释,在这里把解决方法写出来供各位参考。

问题描述:

  • 原代码是为了实现通过MQTT协议连接阿里云,代码有点大,所以我就单门把出错的代码拎出来。
  • 首先我使用C语言在线调试工具测试了一下,结果居然没有问题,程序能够正常执行
  • 接着建立了一个新的keil工程,工程里只加了这一个函数,居然也没有问题

代码如下:

uint8_t ProductKey[50]="a1tN8jvX8cW";
uint8_t DeviceName[10]="D001";
uint32_t packetID=1;

void sendPUBLISH(uint8_t param[0xff])
{
  uint8_t TopicName[0xff];
  uint8_t Payload[0xff];
  
  sprintf((char*)TopicName,"/sys/%s/%s/thing/event/property/post",ProductKey,DeviceName);

  sprintf((char*)Payload,"{\"method\":\"thing.event.property.post\",\"id\":\"%09d\",\"params\":{%s},\"version\":\"1.0.0\"}",packetID++,param);
}

解决方案:

将数组的定义由局部变成全局——即把TopicName、Payload的定义放到函数外面,原程序就可以正常执行了

一言以蔽之

        sprintf 中使用到的数组全部定义成全局数组。

uint8_t ProductKey[50]="a1tN8jvX8cW";
uint8_t DeviceName[10]="D001";
uint32_t packetID=1;

/***********无法解释的解决方法***********/
uint8_t TopicName[0xff];
uint8_t Payload[0xff];
/***************************************/

void sendPUBLISH(uint8_t param[0xff])
{
  uint8_t i=0;
  
  sprintf((char*)TopicName,"/sys/%s/%s/thing/event/property/post",ProductKey,DeviceName);
  
  sprintf((char*)Payload,"{\"method\":\"thing.event.property.post\",\"id\":\"%09d\",\"params\":{%s},\"version\":\"1.0.0\"}",packetID++,param);
}

 sprintf 简介

sprintf指的是字符串格式化命令,函数声明为 int sprintf(char *string, char *format [,argument,...]);,主要功能是把格式化的数据写入某个字符串中,即发送格式化输出到 string 所指向的字符串。sprintf 是个变参函数。使用sprintf 对于写入buffer的字符数是没有限制的,这就存在了buffer溢出的可能性。解决这个问题,可以考虑使用 snprintf函数,该函数可对写入字符数做出限制。

简介来自百度百科

百度百科已经很详细了,但还是要推荐另一篇可以参考的文章:C 库函数 - sprintf()


昨晚看孙俪的新剧《理想之城》到两点多,今天正常上班。的现象就像这个bug明明睡眠不够,精神却很好,这不正常,让我有点担心明明要猝死了

  • 8
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: 使用 `sprintf` 函数的前提是需要引入 `<stdio.h>` 头文件,该头文件中包含了该函数的声明。此外,还需要确保所使用的编译器中有该函数的实现。对于嵌入式系统中的使用,需要注意所使用的编译器是否支持 `printf` 和 `sprintf` 等函数,并且需要根据实际情况选择合适的格式化字符串和参数类型。另外,使用 `sprintf` 函数也需要注意内存的大小和安全性,避免造成缓冲区溢出等安全问题。 ### 回答2: 使用stm32 sprintf函数的前提是需要正确配置和初始化相关硬件和软件环境。 首先,需要正确配置和初始化微控制器的串行通信接口(USART,UART等),以便与外部设备(如计算机)进行通信。这包括设置波特率、数据位数、奇偶校验位、停止位等通信参数,以确保数据能够正确地传输。 其次,需要配置和初始化使用的GPIO引脚,将其配置为对应的串行通信功能。这涉及到设置引脚的工作模式(输入/输出)以及引脚的复用功能。 接下来,在使用sprintf函数之前,需要包含相关头文件,以便在代码中使用该函数。通常,需要包含<stdio.h>头文件来使用sprintf函数。 最后,在调用sprintf函数之前,需要准备好相关变量和字符串格式。sprintf函数的第一个参数是一个字符数组,用于存储格式化后的字符串。根据实际需要,可以使用不同的格式指示符(如%d,%s,%f等)来指定数据的格式和输出方式。其余参数是要格式化的数据,可以是整数、浮点数、字符串等类型。 以上是使用stm32 sprintf函数的前提。在正确配置和初始化硬件和软件环境后,即可使用该函数将数据格式化为字符串,以满足不同的输出需求。 ### 回答3: 使用stm32 sprintf函数的前提是需要先进行一些配置和准备工作。 首先,需要在STM32的开发环境中包含相应的头文件,这些头文件通常是通过包含"stdio.h"来实现的。"stdio.h"头文件包含了一系列输入输出的函数声明和相关常量的定义。 其次,需要配置适当的编译选项。在使用sprintf函数之前,需要确保编译器开启了对标准I/O库的支持。这可以通过在编译选项中包含"-u _printf_float"参数来实现。另外,还需要选择正确的浮点格式,以确保sprintf函数能够正确地处理浮点数。 最后,在使用sprintf函数之前,需要确保已经初始化了用于输出的串口或LCD等设备。sprintf函数通常通过调用与设备相关的底层函数来将输出发送到目标设备上。 总结来说,使用stm32 sprintf函数的前提是:包含相应的头文件、配置适当的编译选项、初始化输出设备。只有在这些准备工作完成之后,才可以安全地使用sprintf函数来进行字符串的格式化输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值