【IAP】FreeRTOS多线程环境下调用NVIC_SystemReset()系统复位函数出现问题

衔接 上篇 调好写入Flash失败后,又出现新问题:
由BOOT跳APP再跳APP,在升级接受升级文件过程中,突然出现系统复位,而且出现位置和时间都是随机的。
定位问题

  1. 尝试改RTOS空间大小
    本以为是FreeRTOS空间给小了,尝试加大还是无果,最后怀疑应该不是RTOS问题,因为如果任务挂了应该会死机不会出现类似重新上电一样的复位。

  2. 怀疑BOOT和APP存储地址错误
    怀疑可能是写入地址出错,APP和BOOT地址交叉了,但最后比较地址发现APP区域和BOOT区域是隔开的,并没有影响,并且用JLINK读取芯片存储空间也是正常的,BOOT区域并没受影响,所以与地址空间配置无关

  3. 上网查阅资料系统复位需要配置什么,尤其是任务中系统复位
    因为之前由BOOT跳转APP在任务中和不在任务中有不同的配置,好像是要关闭中断,

void jumpToApp(uint32_t appBaseAddr)
{void (*firmwareFunc)(void);uint32_t fwStackVal = *((uint32_t *)(appBaseAddr));     /* the first word is for the stack pointer. */uint32_t fwEntryVal = *((uint32_t *)(appBaseAddr+4U));  /* the second works is for the boot function. */firmwareFunc = (void (*)(void))fwEntryVal;SCB->VTOR = appBaseAddr; /* The stack address is also the start address of vector. */__set_MSP(fwStackVal);__set_PSP(fwStackVal);firmwareFunc();
}
void jumpToAppInTask(uint32_t appBaseAddr)
{void (*firmwareFunc)(void);SysTick->CTRL = 0X00;//禁止SysTickSysTick->LOAD = 0;SysTick->VAL = 0;__disable_irq();uint32_t fwStackVal = *((uint32_t *)(appBaseAddr));     /* the first word is for the stack pointer. */uint32_t fwEntryVal = *((uint32_t *)(appBaseAddr+4U));  /* the second works is for the boot function. */firmwareFunc = (void (*)(void))fwEntryVal;SCB->VTOR = appBaseAddr; /* The stack address is also the start address of vector. */__set_MSP(fwStackVal);__set_PSP(fwStackVal);firmwareFunc();
}

所以怀疑APP跳BOOT可能也要有不同处理, 最后查到这篇
尝试了一下

__disable_irq();  
__set_FAULTMASK(1);	
NVIC_SystemReset();

还是没用, (不是很懂上面具体作用是什么,欢迎大佬赐教)
4. 发现代码漏洞
后面换了板子,升级成功2次后,第三次还是有类似问题,所以升级逻辑应该没问题,可能是跳转影响了,而BOOT程序就一个线程在跑,收发数据然后升级,不存在跳转,只有可能是APP程序影响到了BOOT。
但已经APP已经跳过来BOOT了,怎么还能影响,可能是FREERTOS的一些问题,后面证实确实是,但不知道具体原理是什么。参考了这篇文章

使用NVIC_SystemReset实现APP跳转到UBOOT时,连续多次跳转,容易出现MCU崩溃。

因为通信库的缘故,解析指令是多线程解析,加日志打印发现APP中复位确实存在多任务多次执行NVIC_SystemReset();的情况,所以可能是跳转去BOOT后,升级过程中随机调度起任务执行NVIC_SystemReset();导致,BOOT升级中复位。

最后屏蔽APP中的NVIC_SystemReset();函数,直接BOOT升级,一次成功,定位到问题。

解决问题

  1. 加锁
taskENTER_CRITICAL();
NVIC_SystemReset();
taskEXIT_CRITICAL();

多线程调度NVIC_SystemReset,加锁理论上应该可以解决,最后发现,还是BOOT升级中复位了,以为是复位NVIC_SystemReset();又释放了taskEXIT_CRITICAL();

static __INLINE void NVIC_SystemReset(void)
{__DSB();                                                     /* Ensure all outstanding memory accesses includedbuffered write are completed before reset */SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      |(SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |SCB_AIRCR_SYSRESETREQ_Msk);                   /* Keep priority group unchanged */__DSB();                                                     /* Ensure completion of memory access */while(1);                                                    /* wait until reset */
}

但NVIC_SystemReset里面有个while怎么还会释放呢?我猜想可能是升级中RAM空间不稳定,导致临界区空间被压榨了,锁没了,其他线程又复原了然后进来执行但NVIC_SystemReset。
2. 加标志

	taskENTER_CRITICAL();if(isSystemReset == DRIVER_FALSE){isSystemReset = DRIVER_TRUE;NVIC_SystemReset();}taskEXIT_CRITICAL();

加标志,保证只进来一次?结果还是不行,应该也是APP区域已经被擦除的缘故,变量没有保存,最后还是寄了。
3. 挂起调度器

	taskENTER_CRITICAL();vTaskSuspendAll();if(isSystemReset == DRIVER_FALSE){isSystemReset = DRIVER_TRUE;NVIC_SystemReset();}xTaskResumeAll();taskEXIT_CRITICAL();

如果挂起调度器,不让任务调度,是不是可以避免多线程干扰,最后多次测试,BOOT升级过程中,没有再发生复位情况,与第一条猜想符合,这还不行就只能创线程,指令改标志位,保证串行执行系统复位了。
总之FreeRTOS里面升级还是不安全,上面一些原理欢迎大佬赐教

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/627224.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最简单爱心的解析

首先你需要了解爱心代码在直角坐标系的方程 数学知识&#xff1a;x 属于 -1.5 ~ 1.5 y 属于 -1 ~ 1.5 和 高中所学的线性规划 请看代码 #include <math.h> #include <stdlib.h> #include <Windows.h> #include <stdio.h> int main() { …

MySQL中varchar(100)和Oracle 中varchar2(100)

MySQL中的VARCHAR(100)和Oracle中的VARCHAR2(100)虽然在概念上相似&#xff0c;但是在细节上存在差异&#xff0c;这些差异体现在存储方式、性能优化、字符集处理等方面。 MySQL中VARCHAR(100)和Oracle中的VARCHAR2(100) MySQL中的VARCHAR(100) 在MySQL中&#xff0c;VARCH…

【REST2SQL】10 REST2SQL操作指南

【REST2SQL】01RDB关系型数据库REST初设计 【REST2SQL】02 GO连接Oracle数据库 【REST2SQL】03 GO读取JSON文件 【REST2SQL】04 REST2SQL第一版Oracle版实现 【REST2SQL】05 GO 操作 达梦 数据库 【REST2SQL】06 GO 跨包接口重构代码 【REST2SQL】07 GO 操作 Mysql 数据库 【RE…

谭浩强C语言程序设计习题-循环结构程序设计

最大公约数与最小公倍数 //辗转相除法求公约公倍 #include <stdio.h>int gcd(int a, int b) {return (a % b 0) ? b : gcd(b, a % b); }int main() {int m, n;scanf("%d %d", &m, &n); int ans gcd(m, n);printf("%d %d\n", ans, m * n…

ESP系列入门教程(四)——之MQTT通信实现设备反控【分别附上 ESP32 + ESP8266 的具体代码】

ESP系列入门教程<四> 概要技术名词简介● ESP系列简介● MQTT简介 硬件连接实现&#xff08;同教程2&#xff0c;没有变化&#xff09;代码实现●Demo&#xff1a;通过MQTT进行开关灯反控○ ESP8266代码○ ESP32代码 特别鸣谢 概要 最近在跟着几个大佬的教学视频做项目。…

02--数据定义语言DDL

1、数据定义语言DDL 1.1 操作数据库-DDL 创建数据库 create database 数据库名称; 创建数据库&#xff0c;并指定字符集 create database 数据库名称 character set 字符集名; 查询所有数据库的名称 show databases; 查询某个数据库的字符集:查询某个数据库的创建语句及字…

Raft算法

内容出自 : https://www.bilibili.com/video/BV1eL411578r/?spm_id_from333.337.search-card.all.click raft具备良好的容错能力&#xff0c;能够在系统出现复杂的故障时依旧能够保证数据的一致性 能够继续对外提供服务 在raft协议中&#xff0c;分布式系统的每个节点有三个…

Qemu 之安装(源码安装)

Qemu 之安装 Qemu 有两种安装方式&#xff1a; apt 下载二进制文件&#xff0c;可以直接用&#xff0c;但是换版本、卸载等比较麻烦源码编译安装&#xff0c;需要一定的配置&#xff0c;但是自由度比较高 这里主要介绍源码编译安装的方式&#xff1a; 0、安装依赖 这部分参…

AboutAndroid 多语种适配框架,兼容高版本,适配第三方库语种

语种切换框架 项目地址&#xff1a;Github 可以扫码下载 Demo 进行演示或者测试&#xff0c;如果扫码下载不了的&#xff0c;点击此处可直接下载 集成步骤 如果你的项目 Gradle 配置是在 7.0 以下&#xff0c;需要在 build.gradle 文件中加入 allprojects {repositories {…

微服务介绍

背景 微服务是什么?杜克大学教授DanAriely说过一段非常出名的话&#xff0c;用来表述Big Data的发展现状。我觉得把这句话放到微服务身上也极其贴切。 Micro-services is like teenage sex: Everyone talks about it, nobody really knows how to do it, everyo ne thinks ev…

excel(vab)删除空行

删除第一、二、三列位空的所有行&#xff08;8000)行范围以内 代码如下&#xff1a; Sub Macro1()Dim hang As Integer For hang 8000 To 1 Step -1If Sheet1.Cells(hang, 1) "" And Sheet1.Cells(hang, 2) "" And Sheet1.Cells(hang, 3) "&quo…

系统性学习vue-vue中的ajax

vue中的ajax 配置代理常用发送Ajax请求方式跨域方式一方式二 vue-resource插槽默认插槽具名插槽作用域插槽 配置代理 常用发送Ajax请求方式 xhr new XMLHttpRequest() 在真正开发中不常用&#xff0c;比较麻烦jQuery 封装了xhraxios 封装了xhr 与jQuery相比优势是&#xff1a…

怎样才能找到合适的产品说明书模板 方法献上

制作一份专业而吸引人的产品手册对于企业来说至关重要。然而&#xff0c;对于许多企业和个人而言&#xff0c;制作产品手册可能是一个挑战&#xff0c;因为需要一定的设计和排版能力。为了帮助大家更轻松地制作出优质的产品手册&#xff0c;下面将向大家推荐三款优秀的产品手册…

大物小练-判断题题解

一、判断题 1.检验电荷受到的电场力F方向就是电场强度E的方向。&#xff08; B&#xff09; A对 B错 解释&#xff1a;场强E的切线方向才和受力F的方向相同 2.电容器电容的大小与导体的形状、相对位置、其间的电介质有关&#xff0c;与其所带的电荷量无关。A A对 B错 解释…

Ovtio不同版本下载

关注 M r . m a t e r i a l , \color{Violet} \rm Mr.material\ , Mr.material , 更 \color{red}{更} 更 多 \color{blue}{多} 多 精 \color{orange}{精} 精 彩 \color{green}{彩} 彩&#xff01; 主要专栏内容包括&#xff1a; †《LAMMPS小技巧》&#xff1a; ‾ \textbf…

2024年汉字小达人区级选拔备考——附加题:汉字和国学常识

上海的孩子们已经率先开启了悠长的寒假生活。在寒假期间&#xff0c;除了完成寒假生活、学校安排和要求外&#xff0c;还可以做些什么呢&#xff1f;不妨来为2024年汉字小达人做些准备吧&#xff01;每天花个15分钟左右&#xff0c;背一背、做一做&#xff0c;轻松掌握汉字小达…

翻译: Streamlit从入门到精通 构建一个机器学习应用程序 三

Streamlit从入门到精通 系列&#xff1a; 翻译: Streamlit从入门到精通 基础控件 一翻译: Streamlit从入门到精通 显示图表Graphs 地图Map 主题Themes 二 1. 构建一个机器学习应用程序 在这一部分&#xff0c;我将带你了解我做的一个关于贷款预测的项目。 贷款的主要利润直…

“15个必备的自动化测试工具,助你构建2024年的自动化策略!“

以下为作者观点&#xff1a; 如何选择正确的自动化测试工具&#xff1f;自动化测试工具是旨在通过自动化测试脚本验证功能或非功能软件需求的应用程序&#xff0c;帮助加快发布速度、提高项目质量并强化成果。 自动化测试工具可以帮助开发测试人员轻松创建、运行和维护测试&a…

opencv_模型训练

文件夹 opencv训练文件 xml negdataposdata 说明 negdata目录: 放负样本的目录 posdata目录&#xff1a; 放正样本的目录 xml目录&#xff1a; 新建的一个目录&#xff0c;为之后存放分类器文件使用 neg.txt: 负样本路径列表 pos.txt: 正样本路径列表 pos.vec: 后续自动生成…

PlatformIO中ESP8266使用GxEPD库和U8G2库驱动 2.9寸黑白墨水屏显示中文

Content 0. 前言1. 安装platformIO环境2. 新建工程3. 添加外部库4. 修改U8g2_for_Adafruit_GFX库5. 代码和烧录 0. 前言 墨水屏是黄鱼淘的&#xff0c;效果还不错。 U8G2库一直编译不进去&#xff0c;显示汉字始终不太美观&#xff0c;个人一直不太喜欢汉字取模的方法&#x…