Arduino 开发中遇到的奇葩问题

项目场景:

合宙Esp32C3(¥9.9简约版),连了个1.69寸spi屏(240*280),通过WIFI获取并显示“和风天气”的信息。
使用vs2022加Visual Micro插件作为开发环境。
在花了2天解决问题后,实在忍不住,记录一下,希望少点人掉这个大坑里面^_^


问题描述

开始一切尚好,除了Deep search和编译确实相当慢(电脑是FX8300的老CPU,程序改动大的时候,平均5~8分钟左右才能上传),断点也完全没有win程序环境那么方便有效。

在解析出JSON数据后,各种莫名其妙崩溃,板子反复重启;串口反馈原因多种多样:什么指针异常、没有权限、栈粉碎【第一次搜索出这个高大上的词,感觉异常无语/惊人^_^】……(实际报错都是英文,比如:Guru Meditation Error: Core 0 panic‘ed (Load access fault). Exception was unhand)

程序崩溃点,位于调用方法执行完毕,返回的时候,感觉栈确实粉碎了,程序无论如何都回不到父级。

//这里涉及两个class:CWeatherData跟CNetWeather,位于同一个cpp文件中;
//只要通过m_pWS指针,调用CWeatherData中的方法,比如MakeStr(),程序就会大概率崩溃
CWeatherData::CWeatherData()
{
	m_pBuf = new char[2000];
	memset(m_pBuf, 0, 2000);
}
int CWeatherData::MakeStr(WeatherField* pW)
{
	int pos = 0;
	m_Weather.temp = m_pBuf + pos;
	pos += 1 + sprintf(m_pBuf + pos, "%s℃ ", pW->temp);

	m_Weather.feelsLike = m_pBuf + pos;
	pos += 1 + sprintf(m_pBuf + pos, "体感温度:%s℃ ", pW->feelsLike);
	m_Weather.obsTime = m_pBuf + pos;
	pos += 1 + sprintf(m_pBuf + pos, "观测时间:%s ", pW->obsTime);//观测时间
	//....................
	return 1;
}
CNetWeather::CNetWeather()
{
	m_UesdBufferSize = 0;
	m_pZipDataBuffer = new uint8_t[3000];
	m_pJsonStr = NULL;
	m_JsonStrLen = 0;

	m_pWS = new CWeatherData;
}

原因分析:

Arduino的一对.cpp/.h文件里面不能写两个或多个不同的平级class,否则就会各种崩溃【尤其是执行包含sprintf()函数调用的方法,有时连Serial.println()都会导致崩溃】
至于嵌套class如何,没有测试……


解决方案:

把两个class放到不同的文件中,问题解决。
这个问题迷惑人的关键是:编译、链接、上载没有任何异常或错误提示,在调用第二个class的方法前,程序执行一切正常;一旦调用第二个class的方法,程序大概率直接崩溃,板子自动重启,难以查找问题。

另外附录一些我遇到的,真正的程序Bug导致反复重启的情况:
1、TridentTD_EasyFreeRTOS32,默认线程栈只给了2k字节,在网络操作的时候,很容易爆栈导致反复重启,需要适当加大。
2、TFT_eSPI,必须全局静态实例化,如果试图用new来动态实例化,也会反复重启。
3、在多线程环境下,TFT_eSPI 必须由单一线程渲染【常见的各种程序:QT、MFC、Winform、Android等等,基本上都不允许跨线程修改UI,只能由UI主线程来修改UI本身,其它工作线程直接操作修改UI会导致严重错误】。估计付出足够代价来同步/类似Dx12那样搞围栏之类是可以多线程的,但在ESP32的环境下,就单线程吧😁。
4、代码编码问题,UTF-8编码的cpp文件,串口输出调试才能正常显示中文(波特率也要匹配),此时中文编码是UTF-8,可不一定是一个汉字2字节,不少汉字是3字节甚至4字节长1个^_^。
5、数组越界、指针未指向已分配的空间等等。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值