硬件环境:F103ZET6,DM9000
软件环境:ucosii,lwip1.4.1
在开发mqtt应用的时候,遇到如下问题:
(1)程序进入 HardFault_Handler ,并且没有什么规律,有时候运行几小时,有时候运行数天才会进入,日志输出lwip的断言错误:Assertion "tcp_write: pbufs on queue => at least one queue non-empty" failed at line 329 in ..\LWIP\lwip-1.4.1\src\core\tcp_out.c
(2)调用过程如下:
解决过程:
(一)查看堆栈
(1)通过Keil的Register Window查看MSP地址
(2)打开Memory Window,查看内存
按照网上查的资料,堆栈内的地址分别为(可能与CPU有关):R0,R1,R2,R3,R12,LR,PC 。在Disassembly中跳转到PC指向的地址,发现提示 OSStartHang 错误。
在网上查OSStartHang错误,都在说同一个问题,就是PendSVHandler中断与ucos中的OSPendSV冲突,检查自己的配置发现没有这个问题。
问题没有解决,继续找原因吧。
(二)怀疑堆栈空间不足
(1)在startup_stm32f10x_hd.s 文件中查看栈区大小为:Stack_Size EQU 0x00000400
(2)在 .map文件中查看
0x2000e300 - 0x00000400 Zero RW 4558 STACK startup_stm32f10x_hd.o
(3)在Memory Window中查看 0x2000e300 ,发现还有很多未使用空间
(5)结果排除栈空间不足的问题
(三)怀疑多任务调度的问题。在网上查资料,发现一篇文章,有点启发
貌似是因为TCP/IP 任务的优先级较高,在调用过程中出现了任务调度冲突了,自己尝试改一下 。
按照这个思路修改了mqtt向tcp发送的方法,增加了关闭中断。
在 mqtt_output_send()方法中,修改:
(1)
OS_ENTER_CRITICAL();
err = tcp_write(tpcb, mqtt_ringbuf_get_ptr(rb), send_len, TCP_WRITE_FLAG_COPY | (wrap ? TCP_WRITE_FLAG_MORE : 0));
OS_EXIT_CRITICAL();
(2)
OS_ENTER_CRITICAL();
err = tcp_write(tpcb, mqtt_ringbuf_get_ptr(rb), send_len, TCP_WRITE_FLAG_COPY);
OS_EXIT_CRITICAL();
(3)
OS_ENTER_CRITICAL();
tcp_output(tpcb);
OS_EXIT_CRITICAL();
修改上述三个地方,编译运行。
本以为解决了问题,结果运行了不到几个小时,出现了新问题。虽然对 lwip的调用增加了保护,但是运行过程中出现了主任务挂起的问题,其他任务可以正常被调度,但是在mqtt的任务被挂起,无法进入。
目前尚未找到原因。
简介很久没有更新文章了,今天这篇文章是给电子芯吧客评测一个传感器--AS7341,这款传感器目前已经写成RT-Thread的软件包了。如果你也有这款传感器,可以玩一玩。该软件包的仓库:h...
AtCoder Beginner Contest 161 D.Lunlun Number题目链接Problem StatementA positive integer X is said to be a lunlun number if and only if the following condition is satisfied:In the base ten representati...
表格的插入:
Linux c之信号的基础使用
Linux中yum安装google-chrome-stable时,报错如下,提示公钥安装失败,原因是GPG公钥获取失败,无法连接获取到https://dl-ssl.google.com/linux/linux_signing_key.pub对于这个问题,网络解决方案基本都是如下3种1. 导入GPG keys:# rpm --import /etc/pki/rpm-gpg/RPM-GPG-K...
https://segmentfault.com/q/1010000007185702 vuex.action 只能传递两个参数, 一个state是自动添加的,一个payload,是用户自己传到。 但是! 如果你传了两个参数,你会发现第二个永远都是undefined。正确的操作把多个参数打包为一个对象,放到payload里。...
Big-Endian和Little-Endian的定义如下:1) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。2) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。举一个例子,比如数字0x12 34 56 78在内存中的表示形式为:1)大端模式:低地址 ----------------->
https://www.bilibili.com/video/BV1QU4y1c7uJ?share_source=copy_web
内容简介:Sencha框架是第一个基于HTML 5的移动也能给予框架,可以让Web应用看起来像网络应用。美丽的用户 界面 组件和丰富的数据管理,全部基于最新的HTML 5和CSS 3的Web标准,全部兼容Android和iOS设备。本书从实用开发的角度,详细讲解了Sencha Touch的开发过程及基本组件的使用。全书共分13章,前3章主要讲解如何搭建Sencha Touch...
一 结构体:结构体是一中构造数据类型 结构体的用途是把不同类型的数据组合成一个整体,相当于自定义数据类型1.1 结构体的定义:struct [结构体名称]{ 类型标识符 成员名称; 类型标识符 成员名称; 类型标识符 成员名称; ... ...}1.2 声明和使用:#define _CRT_SECURE_NO_WARNINGS#include<stdio...
一直觉得自己写的不是技术,而是情怀,一个个的教程是自己这一路走来的痕迹。靠专业技能的成功是最具可复制性的,希望我的这条路能让你们少走弯路,希望我能帮你们抹去知识的蒙尘,希望我能帮你们理清知识的脉络,希望未来技术之巅上有你们也有我。Dart的基础法语来自下面的网站学习。学习网站地址1.Dart Flutter教程_Dart Flutter2入门实战视频教程-第15讲以后是Flutter教程-2021年6月更新本人使用Mac电脑学习,视频一:主要学习搭建dart环境,使用VSCode软件开发。在VS
1、官网下载需要的Linux版本后放在/home目录中,当然其它地方也行。2、进入安装目录#cd /home#mv jdk-7u79-linux-x64.tar.gz /usr/local#cd /usr/local3、解压到当前目录#sudo tar -xzvfjdk-7u79-linux-x64.tar.gz4、设置环境变量expor