基于TC397的Bootloader开发过程中遇到的问题记录

news2025/1/20 10:58:28

问题1

1 现象:

刷新流程结束之后上位机通过22服务AFFC读取刷新计数时,刷新计数会偶发地置1

2 分析思路

尝试用单步调试的方法复现该现象,程序中涉及到刷新计数的更新有两处,一是在34服务中擦flash前,二是在31服务中擦flash前,由于下载过程不涉及31服务擦flash,着重模拟34服务擦flash。

3 实际操作

在CANoe中多次发送34 00 44 80 10 00 00 00 02 00 00,发现刷新计数可以正常的加1,也就是说每执行一次擦除flash的操作,刷新计数都可以正常的更新。接下来用上位机执行刷新操作,刷新计数也可以加1,但是第二次执行刷新操作时,刷新计数就置为1了。

经过多次尝试,终于稳定复现:在用上位机执行两次刷新操作后,刷新计数会置1,两次刷新操作本身没有太多差异,只能通过debug找问题。代码如下:

boolean UDS_SRV_I_34_Update_AppProgramming_Counter_Flag(void)
{
    uint16 Programming_Cnt = 0;
    boolean ck_status = TRUE;
    /* Check App programming counter */
    Flash_Read_ProgramCounter(&Programming_Cnt);

    if(Programming_Cnt == MAX_APP_PROGRAMMING_COUNTER)
    {
        ck_status = FALSE;
    }
    else
    {
        /* Update number of times programming on NVM */
        ck_status = TRUE;
        if(
             ((Programming_Cnt & 0x00FF) == (FLASH_FILLING_BYTE << 0)) &&
             ((Programming_Cnt & 0xFF00) == (FLASH_FILLING_BYTE << 8))
          )
        {
            Programming_Cnt = 1;
        }
        else
        {
            Programming_Cnt++;
        }
    }
    if(ck_status == TRUE)
    {
        Flash_Write_ProgramCounter(Programming_Cnt);
    }
    return ck_status;
}

将断点打在第6行Flash_Read_ProgramCounter(&Programming_Cnt)处,在上位机第二次刷新执行34服务时会停在这里

点进去,这里主要做的事是从FLASH_DATA_BASE(0x80040000)这块地址读取存好的物流数据到FLASH_RAM_mirror中,然后从FLASH_RAM_mirror中特定位置读取计数

在读取刷新计数之前先瞅一眼FLASH里的状态

看到这里,果然是出了问题,在读flash里的值之前,flash里的值本身已经被修改了,往前找哪个地方涉及到flash的擦写

/* Erase Application Valid Flag */
FlashVal_Status = Flash_Write_ApplicationValidFlag(0x00);

/*Update the programming integrity and compatibility status to 0xFF ---awoys*/
FlashInt_Status = Flash_Write_ProgramIntegrityState(0xFF);

FlashCom_Status = Flash_Write_ProgramCompatibilityState(0xFF);

FlashCount_Status = UDS_SRV_I_34_Update_AppProgramming_Counter_Flag();

任意挑一个函数点进去

boolean Flash_Write_ApplicationValidFlag(uint8 ApplicationValidFlag)
{
    boolean return_code;
    FLASH_RAM_Mirror[RAM_AppValidflag_Base] = ApplicationValidFlag;
    return_code = Flash_Update_Data();
    return return_code;
}

这几个更新标志位的函数实现的逻辑是:更改对应的FLASH_RAM_mirror里存放的标志位,然后将整个数组通过Flash_Update_code()函数写入到FLASH_DATA_BASE中(这就要求在初始化函数中需要对这块ram进行初始化)

看到这里,立马去看FLASH_RAM_mirror这个数组里存放的值,果然全是0,

回头到初始化函数里,果然

void NvM_Flash_ReadAllData(void)
{
    Copy_Bytes_NvM(FLASH_RAM_Mirror,  (uint32)FLASH_DATA_BASE, FLASH_RAM_Mirror_Size);
}

这个初始化函数并没有被调用,所以RAM中全是0

4 复盘分析

问题2

1 现象:

刷新流程结束之后上位机通过31子服务FF01更新兼容码时,程序会卡死

2 分析思路:

31服务通过CANoe测试过没有问题,直接DEBUG看问题出在哪

3 实际操作:

把断点打在31子服务FF01前

然后单步调试

当走到第1691行时,if(*(uint8*)BOOT_HEADER_APP_DEPEND == *(uint8*)APP_HEADER_DEPEND)

程序报错。点进去看,BOOT_HEADER_APP_DEPEND是boot中存放兼容码的flash,地址是0x80000000,再去看这块flash中存放的内容,发现是空的。

所以当程序访问这段地址后报错了。

再看下为什么这段地址是空的,这段地址是用来放boot兼容码及F183的,原本是用#pragma语句定义

#pragma section ".BootHeader" a
const typedef struct
{
    uint8 App_Dependencies;
    uint8 Boot_Software_Number[10];
} BootHeader bootheader = {0xB5, {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}};
#pragma section

后面为了将bootheader声明成extern类型的变量,因此讲变量的定义放到了头文件中,那这个地方犯了一个错误,误以为把类型的声明套上#pragma,就可以将用该类型定义的变量定义到目标flash中

#pragma section ".BootHeader" a
typedef struct
{
    uint8 App_Dependencies;
    uint8 Boot_Software_Number[10];
} BootHeader;
#pragma section

BootHeader bootheader = {0xB5, {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}};

这样的写法无法将bootheader定义到.BootHeader区域中,所以0x80000000开始的这块地址是空的,当程序访问这块地址时,就会报错了。

4 复盘分析:

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

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

相关文章

【数据结构】栈及其经典面试题详解

目录前言一、栈的介绍二、数据类型重定义三、栈的结构四、栈中的常见操作五、测试栈六、栈的常见面试题前言 前面学习的线性表中包含顺序表和链表&#xff0c;这两种数据结构允许在任意位置进行插入和删除&#xff0c;那么有没有一种数据结构是不能在任意位置进行插入删除&…

全面解读MinION纳米孔测序技术及应用

全面解读MinION纳米孔测序技术及应用 link&#xff1a;https://www.seqchina.cn/467.html 【测序中国】 paper&#xff1a;The Oxford Nanopore MinION: delivery of nanopore sequencing to the genomics community https://pubmed.ncbi.nlm.nih.gov/27887629/ 纳米孔测序技术…

知识蒸馏 Knowledge distillation(学习笔记)

知识蒸馏概述 蒸馏&#xff1a;把大的 复杂的东西变成小的纯净的东西 在知识蒸馏中 大的模型为 教师模型&#xff08;teacher&#xff09;臃肿 集成 牛逼 复杂的 小的 为 学生模型&#xff08;student&#xff09;小的精干的 轻量化的 这里有一个知识的迁移 因为落地实…

相关性模型与回归模型(例题代码)

一、相关性模型&#xff08;SPSS&#xff09; 相关性模型涉及到两种最为常用的相关系数&#xff1a; 皮尔逊person相关系数斯皮尔曼spearman等级相关系数 1、皮尔逊相关系数 相关性可视化 总结&#xff1a; 1.如果两个变量本身就是线性的关系&#xff0c;那么皮尔逊相关系…

儿子小伟再婚,新儿媳紧锁眉头,农民歌唱家大衣哥有些过分了

虽然都知道大衣哥儿子小伟结婚&#xff0c;这一天早晚都要到来&#xff0c;但是却没有想到来得那么快&#xff0c;大衣哥儿子小伟的婚礼&#xff0c;在悄无声息中结束了。说起大衣哥儿子小伟&#xff0c;这已经不是第一次结婚了&#xff0c;因为结过婚有经验&#xff0c;这一次…

Linux CFS调度器之pick_next_task函数

文章目录前言一、pick_next_task二、pick_next_task_fair参考资料前言 在内核执行__schedule函数&#xff0c;进程任务切换的时候&#xff0c;__schedule函数函数会调用pick_next_task让调度器从就绪队列中选择最合适的一个进程运行&#xff0c;如下所示&#xff1a; static …

Nerdctl 原生支持 Nydus 加速镜像

文&#xff5c;李楠&#xff08;GitHub ID : loheagn&#xff09; 北京航空航天大学 21 级研究生 云原生底层系统的开发和探索工作。 本文 6369 字 阅读 16 分钟 OSPP 开源之夏是由中科院软件研究所“开源软件供应链点亮计划”发起并长期支持的一项暑期开源活动。旨在鼓励在…

关于whl,你想知道的

一、whl是什么&#xff1f;whl文件时以wheel格式保存的python安装包&#xff0c;Wheel是Python发行版的标准内置包格式。WHL文件包含Python安装的所有文件和元数据&#xff0c;其中还包括所使用的Wheel版本和打包的规范。WHL文件使用Zip压缩进行压缩&#xff0c;实际上也是一种…

二、TCO/IP---Ethernet和IP协议

TCP/ip协议栈 OSI模型TCP/IP协议栈应用层&#xff0c;表示层&#xff0c;会话层应用层传输层主机到主机层&#xff08;传输层&#xff09;网络层网络层数据链路层&#xff0c;物理层网络接入层 Ethernet协议 以太网&#xff0c;实现链路层的数据传输和地址封装&#xff08;MA…

【Qt】Qt中的拖放操作实现——拖放文件以及自定义拖放操作

文章目录Qt的拖放操作使用拖放打开文件自定义拖放操作文章参考《Qt Creator快速入门&#xff08;第三版&#xff09;》。 Qt的拖放操作 拖放操作分为拖动Drag和放下Drop&#xff0c;Qt提供了强大的拖放机制&#xff0c;可在帮助文档中通过Drag and Drop关键字查看。 在Qt中&a…

ArcGIS基础实验操作100例--实验78按栅格分区统计路网

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验78 按栅格分区统计路网 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;…

【数据结构】队列详解

前言 前面我们学习了一种数据结构&#xff1a;栈&#xff0c;栈是一种只允许在一端尽进行插入删除的数据结构&#xff0c;而今天我们将学习另一种数据结构&#xff1a;队列&#xff0c;队列是一种支持在一端进行插入&#xff0c;在另一端进行删除的数据结构。 一、队列的介绍…

PHP反序列化字符串逃逸

PHP反序列化字符串逃逸 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录PHP反序列化字符串逃逸前言一、关于反序列化和序列化二、[0ctf 2016]unserialize二、prize_p5[NSSCTF]前言 例如&#xff1a;最近日常刷题玩…

常用的传输码介绍

文章目录前导知识1.AMI码2.HDB3码3.PST码4.数字双相码5.CMI码6.nBmB码前导知识 在介绍常用的传输码之前&#xff0c;先简单介绍一下直流分量。 信号的直流分量就是信号的平均值&#xff0c;它是一个与时间无关的常数&#xff0c;直流分量的数学公式表示为&#xff1a; 判断有…

基于轻量级YOLOv5+Transformer的汽车车损检测识别分析系统

将传统NLP领域提出来的Transformer技术与yolo目标检测模型融合已经成为一种经典的做法&#xff0c;早在之前的很多论文里面就有这种组合应用的出现了&#xff0c;本文主要是借鉴前文的思路&#xff0c;开发基于yolov5transformer的汽车车损检测识别模型&#xff0c;首先看下效果…

光流相关总结

基于图像亮度恒定假设&#xff0c; 图像亮度&#xff1a;I(x⃗,t)I(\vec x, t)I(x,t), 其中x⃗[x,y]\vec x[x,y]x[x,y]&#xff0c;那么亮度恒定假设&#xff1a; I(x⃗,t)I(x⃗δx⃗,tδt)(1)I(\vec x,t)I(\vec x \delta \vec x, t \delta t) (1)I(x,t)I(xδx,tδt)(1) 对上式…

2022年值得记录的一年,事与愿违的一年

年初带着对生活的不满、怀才不遇的傲慢&#xff1b; 愿即将到来的30岁不留遗憾&#xff1b; 你放下所有去追求向往的样子&#xff1b; 那时所有的空气都是清新的&#xff0c;即使它满是灰尘&#xff1b; 不再年少的你依然充满新奇&#xff1b; 用尽力气把自己钉在那个不属…

前端与后端的技术通性

一、后端的JDK相当于前端的Node.js, 后端的JVM相当于前端的V8引擎【作用示例图&#xff0c;如下所示】 【Nodejs、JDK分别是前后端的运行环境】 二、后端的Maven&#xff08;基于项目对象模型-Project Object Model-POM的项目管理机制&#xff09;相当于前端的npm&#xff08;n…

FlinkCDC

目录1、CDC 简介1.1、什么是CDC1.2、CDC的种类1.3、Flink-CDC2、Flink CDC 网址3、运行原理5、简要安装6、开发案例7、扩展1、CDC 简介 1.1、什么是CDC CDC 是 Change Data Capture&#xff08;变更数据获取&#xff09;的简称。核心思想是&#xff0c;监测并捕获数据库的变动…

js实现网页特效

文章目录一、元素偏移量offest系列&#x1f947;offset与style的区别&#x1f393;案例1&#x1f9b9;&#x1f3fd;‍♂️案例2&#x1f43c;案例3二、元素可视区client系列三、元素滚动scroll系列&#x1f3c2;&#x1f3ff;案例4&#xff1a;&#x1f52d;补充 mouseenter事…