[AUTOSAR][Fls模块] Flash Driver Module
Flash Driver Module--jianqiang.xue
- 一、 简介
- 二、 措施
- 方式一:将FLASH操作程序作为Bootloader组件的一部分固化在存储器中
- 方式二:通过通讯口将该部分代码从上位机下载到指定的RAM
- 方式三:将Flash功能函数作为数据运行(推荐!!!)
- 使用Demo
一、 简介
在汽车ECU软件运行中,软件代码运行安全性是第一,在代码中尽可能的不要固化有flash_erase、flash_write操作存在,主要是防止当出现异常情况时,程序跑飞,误调用erase、write对flash操作,使得原软件受到破坏,以致ECU不能正常工作。
Flash访问代码(Access Code)不能存储在被操作的Flash物理块中,例如我要擦除一个Flash中某一个扇区内容,这个擦除动作的代码不能存在这个Flash物理块中(Flash中代码运行时,相当于读操作,此时不能擦写)
PFlash的访问代码在Fls_17_Dmu_ac.c文件中,而该文件的代码又被烧写进PFlash中,所以,PFlash不能直接进行Write/Erase操作
解决方案就是PFlash进行Write/Erase操作前,将Write/Erase访问代码存储到RAM中,函数实际上是在RAM中执行
在AUTOSAR的负责范围内,DF0_EEPROM不会存放任何访问代码。
二、 措施
方式一:将FLASH操作程序作为Bootloader组件的一部分固化在存储器中
为了实现在线更新功能,Bootloader程序需要对flash进行操作。一般情况下,我们将FLASH操作程序作为Bootloader组件的一部分固化在存储器中,在需要执行flash擦除或烧写操作时,先将该部分代码复制到RAM中,再做调用。操作代码的复制工作也可以在Bootloader启动阶段完成。
方式二:通过通讯口将该部分代码从上位机下载到指定的RAM
两级Bootloader方案,没有在flash存储器中固化flash擦写代码,而是通过通讯口将该部分代码从上位机下载到指定的RAM出,在需要指出flash擦除或烧写操作时,再调用RAM中的该代码。
jianqiang.xue
方式三:将Flash功能函数作为数据运行(推荐!!!)
- 根据MCU新建Flash Driver工程
- 编写flash_erase和flash_write两个函数
- 编译生成bin文件,通过.map文件查看这两个函数的位置
- 在生成的bin文件中提取出这两个函数信息,注意地址是偶数。
func_addr = (map_addr-1)
func_size = (map_size+4)
const uint8_t McuFlashErasePageBuf[] = {0xB0, 0xB5, 0x11, 0x4A, 0x30, 0x21, 0x11, 0x70, 0x14, 0x1F, 0x00, 0x23, 0x23, 0x70, 0x0A, 0x25,0x15, 0x71, 0x05, 0x0C, 0xD5, 0x70, 0x01, 0x25, 0x25, 0x70, 0xFC, 0x24, 0x04, 0x40, 0xD4, 0x70,0x00, 0x0A, 0x10, 0x71, 0x85, 0xF3, 0x10, 0x88, 0x80, 0x20, 0x10, 0x70, 0x10, 0x78, 0x40, 0xB2,0x00, 0x28, 0xFB, 0xD5, 0x10, 0x78, 0x00, 0x07, 0xFC, 0xD4, 0x12, 0x78, 0x83, 0xF3, 0x10, 0x88,0x0A, 0x40, 0x50, 0x42, 0x50, 0x41, 0xB0, 0xBD, 0x05, 0x00, 0x02, 0x40, 0x10, 0xB5, 0x8C, 0xB0,
};const uint8_t McuFlashWritePageBuf[] = {0xF8, 0xB5, 0x14, 0x46, 0x04, 0x43, 0x01, 0x23, 0xA4, 0x07, 0x4D, 0xD1, 0x00, 0x29, 0x4B, 0xD0,0x00, 0x2A, 0x49, 0xD0, 0x00, 0x23, 0x25, 0x4C, 0x00, 0x93, 0x30, 0x26, 0x26, 0x71, 0x00, 0x9D,0x25, 0x70, 0x06, 0x25, 0x25, 0x72, 0x05, 0x0C, 0xE5, 0x71, 0x01, 0x27, 0x27, 0x70, 0x05, 0x0A,0x25, 0x72, 0xFC, 0x25, 0x05, 0x40, 0xE5, 0x71, 0x02, 0x25, 0x25, 0x70, 0x4D, 0x78, 0x25, 0x72,0x0D, 0x78, 0xE5, 0x71, 0x03, 0x25, 0x25, 0x70, 0xCD, 0x78, 0x25, 0x72, 0x8D, 0x78, 0xE5, 0x71,0x1D, 0x1D, 0x95, 0x42, 0x0F, 0xD2, 0x04, 0x25, 0x25, 0x70, 0x4D, 0x79, 0x25, 0x72, 0x0D, 0x79,0xE5, 0x71, 0x05, 0x25, 0x25, 0x70, 0xCD, 0x79, 0x25, 0x72, 0x8D, 0x79, 0xE5, 0x71, 0x08, 0x30,0x08, 0x33, 0x08, 0x31, 0x02, 0xE0, 0x00, 0x1D, 0x09, 0x1D, 0x2B, 0x46, 0x87, 0xF3, 0x10, 0x88,0x80, 0x25, 0x25, 0x71, 0x04, 0x25, 0x65, 0x57, 0x00, 0x2D, 0xFB, 0xD5, 0x25, 0x79, 0x2D, 0x07,0xFC, 0xD4, 0x27, 0x79, 0x00, 0x25, 0x85, 0xF3, 0x10, 0x88, 0x37, 0x40, 0x93, 0x42, 0x01, 0xD2,0x00, 0x2F, 0xBA, 0xD0, 0x7B, 0x42, 0x7B, 0x41, 0x18, 0x46, 0xF8, 0xBD, 0x01, 0x00, 0x02, 0x40,
};
- 提取数据并存放数组,这些数据不能直接使用,因为无法到达AUTOSAR初衷。
处理数据:
(1) 数组数据全部取反,这样程序炮灰也不会误触发。
(2) 使用flash_erase和flash_write时,需要取反数据,再使用,使用结束后,再清除数据。
// 这里的数据全部取反才是真正函数,防止指针跑飞误执行。
#pragma pack (4)
const uint8_t gc_McuFlashErasePageBuf[] = {0x73, 0x4f, 0xfe, 0x57, 0x00, 0x08, 0xa6, 0x00, 0xfb, 0x67,0xf3, 0xb6, 0x77, 0xbd, 0xee, 0x2c, 0xea, 0xb3, 0xfd, 0xde,0x9e, 0xa9, 0xff, 0xd6, 0x04, 0x2a, 0xf7, 0xb6, 0x00, 0x08,0xe4, 0x00, 0xbe, 0xe1, 0xc0, 0xdf, 0xf7, 0xbf, 0xdf, 0x8f,0xde, 0x87, 0xb6, 0x4d, 0xff, 0xd6, 0x05, 0x2a, 0xf3, 0x4f,0xef, 0x42, 0xfc, 0x5f, 0xf7, 0x5e, 0xd6, 0xdd, 0xff, 0x0f,0x41, 0x07, 0xbf, 0xbd, 0xf0, 0xff, 0x9c, 0x93, 0x94, 0xd1,0x99, 0x8d, 0x8e, 0xa0, 0x9d, 0x8a, 0x8c, 0xdf, 0xc1, 0x4f
};
const uint8_t gc_McuFlashWritePageBuf[] = {0x07, 0x4a, 0xeb, 0xb9, 0xfb, 0xbc, 0xfe, 0xdc, 0x5b, 0xf8,0xb2, 0x2e, 0xff, 0xd6, 0xb4, 0x2f, 0xff, 0xd5, 0xb6, 0x2f,0xff, 0xdc, 0xda, 0xb3, 0xff, 0x6c, 0xcf, 0xd9, 0xd9, 0x8e,0xff, 0x62, 0xda, 0x8f, 0xf9, 0xda, 0xda, 0x8d, 0xfa, 0xf3,0x1a, 0x8e, 0xfe, 0xd8, 0xd8, 0x8f, 0xfa, 0xf5, 0xda, 0x8d,0x03, 0xda, 0xfa, 0xbf, 0x1a, 0x8e, 0xfd, 0xda, 0xda, 0x8f,0xb2, 0x87, 0xda, 0x8d, 0xf2, 0x87, 0x1a, 0x8e, 0xfc, 0xda,0xda, 0x8f, 0x32, 0x87, 0xda, 0x8d, 0x72, 0x87, 0x1a, 0x8e,0xe2, 0xe2, 0x6a, 0xbd, 0xf0, 0x2d, 0xfb, 0xda, 0xda, 0x8f,0xb2, 0x86, 0xda, 0x8d, 0xf2, 0x86, 0x1a, 0x8e, 0xfa, 0xda,0xda, 0x8f, 0x32, 0x86, 0xda, 0x8d, 0x72, 0x86, 0x1a, 0x8e,0xf7, 0xcf, 0xf7, 0xcc, 0xf7, 0xce, 0xfd, 0x1f, 0xff, 0xe2,0xf6, 0xe2, 0xd4, 0xb9, 0x78, 0x0c, 0xef, 0x77, 0x7f, 0xda,0xda, 0x8e, 0xfb, 0xda, 0x9a, 0xa8, 0xff, 0xd2, 0x04, 0x2a,0xda, 0x86, 0xd2, 0xf8, 0x03, 0x2b, 0xd8, 0x86, 0xff, 0xda,0x7a, 0x0c, 0xef, 0x77, 0xc8, 0xbf, 0x6c, 0xbd, 0xfe, 0x2d,0xff, 0xd0, 0x45, 0x2f, 0x84, 0xbd, 0x84, 0xbe, 0xe7, 0xb9,0x07, 0x42, 0xfe, 0xff, 0xfd, 0xbf
};uint8_t McuFlashErasePageBuf[80] = {0};
uint8_t McuFlashWritePageBuf[176] = {0};
#pragma pack ()
/****************************变量定义******************************/
typedef uint8_t (*McuFlashWritePageHandler)(uint32_t addr, uint8_t* buff, uint32_t len);
typedef uint8_t (*McuFlashErasePageHandler)(uint32_t addr);
/****************************常量定义******************************/
/****************************函数原型******************************/
static void Retrieval(uint8_t *s_buf, uint8_t *l_buf, uint32_t size) {for(uint32_t i = 0; i < size; i++) {l_buf[i] = ~s_buf[i];}
}
void McuFlashInstall(void) {// 装载FlashDriver驱动函数Retrieval((uint8_t *)gc_McuFlashErasePageBuf, McuFlashErasePageBuf, 80);Retrieval((uint8_t *)gc_McuFlashWritePageBuf, McuFlashWritePageBuf, 176);
}void McuFlashUnInstall(void) {// 卸载FlashDriver驱动函数memset(McuFlashErasePageBuf, 0, 80);memset(McuFlashWritePageBuf, 0, 176);
}/******************************************************************* 函数名称:McuFlashWritePage* 入口参数:addr 写地址;buff 数据缓存;len 数据长度* 出口参数:0 指令操作失败,1 指令操作成功* 函数说明:向指定地址写入一定长度的数据* 地址必须4字节对齐且在有效操作范围内;buff本身不能低于len* 设置的长度;len必须为4的整数倍;写入的空间必须已经擦除******************************************************************/
McuFlashWritePageHandler McuFlashWritePage = (McuFlashWritePageHandler)(McuFlashWritePageBuf + 1);/******************************************************************* 函数名称:McuFlashErasePage* 入口参数:addr 页所在地址* 出口参数:0 指令操作失败,1 指令操作成功* 函数说明:擦除页所在地址的一页内容******************************************************************/
McuFlashErasePageHandler McuFlashErasePage = (McuFlashErasePageHandler)(McuFlashErasePageBuf + 1);/******************************变量声明*****************************/
typedef uint8_t (*McuFlashWritePageHandler)(uint32_t addr, uint8_t* buff, uint32_t len);
typedef uint8_t (*McuFlashErasePageHandler)(uint32_t addr);// 未安装flash驱动,调用下面函数会直接跑飞
extern McuFlashWritePageHandler McuFlashWritePage;
extern McuFlashErasePageHandler McuFlashErasePage;
LiSun–xuejianqiang
使用Demo
// 写入McuFlashInstall();McuFlashWritePage(LS_ADDR, data, len);McuFlashUnInstall();
// 擦除McuFlashInstall();McuFlashErasePage(LS_ADDR);McuFlashUnInstall();
相关文章:

[AUTOSAR][Fls模块] Flash Driver Module
Flash Driver Module--jianqiang.xue一、 简介二、 措施方式一:将FLASH操作程序作为Bootloader组件的一部分固化在存储器中方式二:通过通讯口将该部分代码从上位机下载到指定的RAM方式三:将Flash功能函数作为数据运行(推荐!&#…...

如何正确选择好用的投票平台微信公众平台投票链接链接投票平台
“年度人物楷模”网络评选投票_免费链接投票_作品投票通道_扫码投票怎样进行现在来说,公司、企业、学校更多的想借助短视频推广自己。通过微信投票小程序,网友们就可以通过手机拍视频上传视频参加活动,而短视频微信投票评选活动既可以给用户发…...

gocd部署应用
产品需要在多个环境部署测试,为了提高部署测试效率,故计划使用CD工具,jenkins确实足够强大,但是使用部署功能是需要安装插件的,再说自己本身只用部署功能,故决定找一个小巧的CD工具,经过一番查找…...

P2P视频聊天技术分析
整个P2P视频过程需要知道双方的媒体类型、流和候选者,所以这里就会用到一下技术: 信令服务器socket.io 状态机 ICE服务器 WebRTC框架 媒体协商 信令服务器Socket.io 信令服务器说白了作用就是发消息的中转站,A把msg发到…...

MyBatis 的一级、二级缓存机制
目录标题缓存什么是缓存为什么使用缓存什么样的数据能使用缓存,什么样的数据不能使用适用于缓存不适用于缓存MyBatis 一级缓存、二级缓存关系1. 一级缓存1.1 什么是一级缓存mybatis1.2 一级缓存配置1.3 什么情况下会命中一级缓存mybatis清除一级缓存的几种方法1.4 内…...
剑指 Offer 65. 不用加减乘除做加法
摘要 剑指 Offer 65. 不用加减乘除做加法 一、位运算 有符号整数通常用补码来表示和存储,补码具有如下特征: 正整数的补码与原码相同;负整数的补码为其原码除符号位外的所有位取反后加 11。可以将减法运算转化为补码的加法运算来实现。符…...
5年软件测试年薪30w+,我的坎坷之路谁又知道
在深圳做了五年软件测试工作,从之前的一脸懵的点点点,到现在会自动化测试,说一点点非计算机专业人员从事软件测试的心得体会,仅供参考交流。 大部分测试在公司没啥地位,当然如果你懂技术就还行,单纯点点点…...

【Opencv--自适应图像二值化】cv2.adaptiveThreshold()
【Opencv–adaptiveThreshold】自适应阈值图像二值化 文章目录【Opencv--adaptiveThreshold】自适应阈值图像二值化1. 介绍2. adaptiveThreshold函数2.1 函数调用2.2 补充说明3. 代码示例4. 效果4.1 原图(ori.img)4.2 处理后5. 参考1. 介绍 在这里 cv2.…...

洛谷P8601[蓝桥杯][2013年第四届真题]剪格子
题目描述如图 11 所示,33 的格子中填写了一些整数。我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是 60。本题的要求就是请你编程判定:对给定的 mn 的格子中的整数,是否可以分割为两个部分,使…...
配置alias实现快速生成.gitignore文件
git工具:版本控制开发工具。 cscope工具:用于浏览C源码的工具,类似于ctags。在代码根目录下执行cscope -Rbq,然后产生三个索引文件(cscope.out、cscope.in.out和cscope.po.out三个文件)。 在Linux下使用vi…...

MySQL数据库调优————GROUP BY及DISTINCT优化
GROUP BY 三种处理GROUP BY的方式 松散索引扫描(Loose Index Scan)紧凑索引扫描(Tight Index Scan)临时表(Temporary table) 三种方式的性能一次递减 松散索引扫描 无需扫描满足条件的所有索引键即可返…...
LRU缓存算法
双向链表哈希表(非线程安全) https://leetcode.cn/problems/lru-cache/solutions/259678/lruhuan-cun-ji-zhi-by-leetcode-solution/ /*** LRU算法: 哈希表双向链表实现* 1. 双向链表按照被使用的顺序来存储, 靠近头部的节点是最近使用的, 靠近尾部的节…...
@Configuration注解
Configuration注解介绍 Configuration注解,用于标注一个类是一个spring的配置类(同时,也是一个bean),配置类中可以使用ComponentScan、Import、ImportResource 和 Bean等注解的方式定义beanDefinition。 Target(Elem…...

基于springboot+vue的食疗系统
基于springbootvue的食疗系统 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一、项目背景介绍&…...

sklearn学习-朴素贝叶斯
文章目录一、概述1、真正的概率分类器2、sklearn中的朴素贝叶斯二、不同分布下的贝叶斯1、高斯朴素贝叶斯GaussianNB2、探索贝叶斯:高斯朴素贝叶斯擅长的数据集3、探索贝叶斯:高斯朴素贝叶斯的拟合效果与运算速度总结一、概述 1、真正的概率分类器 算法…...

分享112个HTML艺术时尚模板,总有一款适合您
分享112个HTML艺术时尚模板,总有一款适合您 112个HTML艺术时尚模板下载链接:https://pan.baidu.com/s/1D3-mfPOud-f3vy9yLl-bmw?pwdfph2 提取码:fph2 Python采集代码下载链接:采集代码.zip - 蓝奏云 时尚平面模特网站模板 潮…...
用GDB远程调试运行于QEMU的程序
1. 前言 限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。 2. 测试环境 本文使用 Ubuntu 16.04.4 LTS QEMU 环境进行调试。 3. 用 GDB 调试 QEMU 内程序 3.1 编写用来调试的程序 我们用 ARM32 来进行调试…...

20 堆排序
文章目录1 堆排序的概念2 堆排序基本思想3 堆排序步骤图解说明4 堆排序的代码实现1 堆排序的概念 1) 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为 O(nlogn)…...

2023最新文件快递柜系统网站源码 | 匿名口令分享 | 临时文件分享
内容目录一、详细介绍二、效果展示1.部分代码2.效果图展示三、学习资料下载一、详细介绍 2023最新文件快递柜系统网站源码 | 匿名口令分享 | 临时文件分享 很多时候,我们都想将一些文件或文本传送给别人,或者跨端传递一些信息,但是我们又不…...
分片策略(二)
分片策略 基本概念 分片键 用于分片的字段,是将数据库或表拆分的字段,比如,我可以使用user_id作为分片键将用户数据分到不同的表中,这里的user_id就是分片键,除了这种单字段分片,ShardingSphere还支持多…...

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...