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明明睡眠不够,精神却很好,这不正常,让我有点担心明明要猝死了

### STM32F103RCT6与WiFi的相关教程及使用指南 STM32F103RCT6是一款基于ARM Cortex-M3架构的高性能微控制器,其具体型号定义如下: - **R** 表示该芯片具有64个引脚。 - **C** 表示闪存容量为256KB。 - **T6** 是封装形式的一部分,表示LQFP64封装。 当涉及到WiFi功能时,通常需要借助外部模块来实现无线通信能力,因为STM32F103本身并不具备内置WiFi硬件支持。常见的解决方案包括使用ESP8266或ESP32作为WiFi模块,并通过串口或其他接口与STM32F103进行通信[^1]。 #### 硬件连接方案 为了使STM32F103RCT6能够支持WiFi功能,可以采用以下方法之一: 1. **UART接口连接ESP8266/ESP32模块** 将STM32F103的USART端口配置为主设备模式,用于发送AT指令控制ESP8266的工作状态。例如,在初始化阶段可以通过发送`AT+CWMODE=1`命令设置ESP8266进入Station模式[^3]。 2. **SPI/I²C协议扩展** 如果项目需求更高带宽的数据传输,则可以选择利用SPI或者I²C总线替代传统的UART方式完成两者间的信息交换过程。不过需要注意的是这种情况下可能还需要额外增加一些驱动程序开发工作量。 #### 软件设计思路 以下是构建一个简单的WiFi客户端应用程序的大致框架: ```c #include "stm32f1xx_hal.h" #include <string.h> #define ESP8266_BAUDRATE 9600U // 初始化串口函数 void MX_USART_Init(void){ huart2.Instance = USART2; huart2.Init.BaudRate = ESP8266_BAUDRATE; HAL_UART_Init(&huart2); } int main(void){ char buffer[100]; uint8_t response; /* MCU Initialization */ HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART_Init(); // 发送启动命令给ESP8266并等待回应 while(1){ memset(buffer,'\0',sizeof(buffer)); sprintf(buffer,"AT\r\n"); HAL_UART_Transmit(&huart2,(uint8_t*)buffer,strlen((char *)buffer),HAL_MAX_DELAY); delay_ms(100); HAL_UART_Receive(&huart2,&response,1,HAL_MAX_DELAY); if(response == 'O') break;// 假设收到'O'字符即认为成功建立链接 } // 继续执行其他操作... } ``` 此代码片段展示了如何向ESP8266发送基础测试命令(AT),并通过读取返回值判断当前模块是否正常响应。 #### 注意事项 - 在实际应用过程中应充分考虑信号强度、干扰源等因素的影响; - 对于长时间运行的应用场景建议加入看门狗机制防止死机现象发生; - 根据具体的业务逻辑调整相应的参数设定比如超时时间等。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值