[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还支持多…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
