[AUTOSAR][Fls模块] Flash Driver Module

news2024/9/22 21:24:20

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功能函数作为数据运行(推荐!!!)

  1. 根据MCU新建Flash Driver工程
  2. 编写flash_erase和flash_write两个函数
  3. 编译生成bin文件,通过.map文件查看这两个函数的位置
  4. 在生成的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,
};
  1. 提取数据并存放数组,这些数据不能直接使用,因为无法到达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

LiSun

使用Demo

// 写入
    McuFlashInstall();
    McuFlashWritePage(LS_ADDR, data, len);
    McuFlashUnInstall();
// 擦除
    McuFlashInstall();
    McuFlashErasePage(LS_ADDR);
    McuFlashUnInstall();

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

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

相关文章

23种设计模式介绍(Python示例讲解)

文章目录一、概述二、设计模式七种原则三、设计模式示例讲解1&#xff09;创建型模式1、工厂模式&#xff08;Factory Method&#xff09;【1】简单工厂模式&#xff08;不属于GOF设计模式之一&#xff09;【2】工厂方法模式2、抽象工厂模式&#xff08;AbstractFactory&#x…

Python抽奖系统

#免费源码见文末公众号# 抽奖系统① def choujiang1():def write():with open(d:\\抽奖系统\\抽奖1.1.pickle,rb) as file:lst1pickle.load(file)namevar1.get()if name not in lst1 and name!录入成功&#xff01; and name!录入失败&#xff01; and name!:lst1.append(name)…

基于springboot+vue的便利店库存管理系统

基于springbootvue的便利店库存管理系统 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景…

C++面向对象(上)

文章目录前言1.面向过程和面向对象初步认识2.引入类的概念1.概念与用法2.类的访问限定符及封装3.类的作用域和实例化4.类的大小计算8.this指针3.总结前言 本文将对C面向对象进行初步介绍&#xff0c;引入类和对象的概念。围绕类和对象介绍一些基础知识&#xff0c;为以后深入学…

【数据结构】————栈

文章目录前言栈是什么&#xff0c;栈的特点实现栈的基本操作栈的相关操作声明1.创建栈2.对栈进行初始化3.销毁栈4.判断栈是否为空5.压栈操作6.删除栈顶元素7.取出栈顶元素8.计算栈内存放多少个数据总结前言 本文主要讲述特殊的线性表——栈&#xff1a; 栈是什么&#xff0c;栈…

学生信息管理系统(通讯录)----------通俗易懂、附源码、C语言实现

绪论&#xff1a; 本篇文章使结构体章节后的习题&#xff0c;如果你对C语言有问题&#xff0c;或者结构体有什么问题不妨看看我之前所写的文章&#xff08;章回体&#xff09;,对于文件管理和内存分配问题我将在后面补上&#xff0c;对于这个学生信息管理系统我用了多种方法和…

五【Spring】控制反转(IOC)

目录一 Ioc控制反转1.1 概述1.2 依赖注入二 传统依赖的问题2.1 在传统的项目中三 引入Spring解决3.1 Spring配置文件中Bean属性3.2 Bean的作用域3.3 项目案例四 基于xml的依赖注入&#xff08;注意有参 无参的构建&#xff09;4.1 设置注入4.2 构造注入&#xff08;依赖有参构造…

【Java面试总结】MySQL篇·优化篇

【Java面试总结】MySQL篇SQL优化篇1.该如何优化MySQL的查询&#xff1f;2.怎样插入数据才能更高效&#xff1f;3.表中包含几千万条数据该怎么办&#xff1f;4.MySQL的慢查询优化有了解吗&#xff1f;5.说一说你对explain的了解6.explain你一般关注什么&#xff1f;1.该如何优化…

【Linux】网络编程 - Socket套接字/基于UDP的网络通信

目录 一.套接字 1.什么是套接字/Socket套接字 2.套接字的分类 3.Socket套接字的常见API 二.网络字节序 1.什么是网络字节序 2.网络字节序和主机字节序的转换接口 三.IP地址形式上的转换 四.客户端的套接字不由程序员bind 1.为什么客户端套接字不能由程序员bind 2.OS…

【题外话】如何拯救小米11Pro这款工业垃圾

1 背景媳妇用小米11Pro手机&#xff0c;某日不慎摔落&#xff0c;幸好屏幕未碎&#xff0c;然而WiFi却怎样都无法打开&#xff0c;初以为是系统死机&#xff0c;几天依旧故障无法使用。现在的手机没有WiFi功能&#xff0c;就无法刷抖音、看视频&#xff0c;就是鸡肋了。后抽空去…

全栈之路-前端篇 | 第三讲.基础前置知识【前端标准与研发工具】学习笔记

欢迎关注「全栈工程师修炼指南」公众号点击 &#x1f447; 下方卡片 即可关注我哟!设为「星标⭐」每天带你 基础入门 到 进阶实践 再到 放弃学习&#xff01;涉及 企业运维、网络安全、应用开发、物联网、人工智能、大数据 学习知识“ 花开堪折直须折&#xff0c;莫待无花空折…

【2.19】算法题2:贪心算法、动态规划、分治

题目&#xff1a;给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。子数组 是数组中的一个连续部分。方法一&#xff1a;贪心算法原理&#xff1a;若当前指针所指元素之前的和小…

学生和老师-课后程序(JAVA基础案例教程-黑马程序员编著-第四章-课后作业)

【案例4-4】学生和老师 【案例介绍】 1.案例描述 在班级中上课时&#xff0c;老师在讲台上讲课&#xff0c;偶有提问&#xff0c;会点名学生回答问题。虽然老师和学生都在讲话&#xff0c;但讲话的具体内容却不相同。本案例要求使用抽象类的知识编写一个程序实现老师上课的情…

Allegro如何快速清除多余的规则设置操作指导

Allegro如何快速清除多余的规则设置操作指导 在用Allegro做PCB设计的时候,会给PCB设置一些规则,在PCB设计完成之后,可能会有一些没有使用到的规则,如下图 Physical规则中的45OHM的规则是多余的 单独某个规则可以直接在规则管理器中删除,如果比较多可以用下面方法批量删除…

真实景观渲染技巧【Three.js】

受到一些很棒的 three.js 演示、与 covid 相关的旅行禁令以及可能在 pinterest 上花太多时间看美丽的旅行照片的启发——我开始看看我是否可以使用 three.js 和r3f在浏览器中渲染一个令人信服的风景场景。 推荐&#xff1a;将 NSDT场景编辑器 加入你的3D开发工具链。 在过去一个…

AnLogicFPGA设计的时序约束及时序收敛

本篇博文讲了三个内容&#xff1a;时序约束基本概念、时序约束命令、时序收敛技巧 时序约束基本概念 时序设计的实质就是满足每一个触发器的建立&#xff08;setup&#xff09;时间和保持&#xff08;hold&#xff09;时间。 建立时间(Tsu) 触发器的时钟信号沿到来以前&…

零信任-新华三H3C零信任介绍(12)

​目录 ​新华三零信任是什么&#xff1f; 新华三零信任架构特点 新华三零信任架构 新华三零信任架构适用场景 新华三零信任的未来发展展望 新华三零信任是什么&#xff1f; 建立新边界 全面身份化。新华三贯彻“永不信任&#xff0c;始终验证”的原则&#xff0c;通过对…

JavaWeb7-线程状态(生命周期)及转换过程

目录 1.所有线程状态&#xff08;共6种&#xff09; ①NEW-新建状态 ②RUNNABLE-运行状态 RUNNABLE&#xff08;得到时间片运行中状态&#xff09; READY&#xff08;已经保存了上下文&#xff0c;但还未得到时间片的就绪状态&#xff09;。 ③BLOCKED-阻塞状态 ④WAITI…

使用NutUI创建小程序和H5界面

做开发的时间长了&#xff0c;技术都是通用的&#xff0c;创建小程序和H5界面有很多的UI&#xff0c;本章节演示使用NutUI来创建&#xff0c;官网&#xff0c;NutUI - 移动端 Vue3 小程序组件库 1.使用HBuilder X创建一个uni-app的程序&#xff0c;如图所示 2. 安装UniNutUI …

nvm的使用与坑

1、nvm 介绍 Node Version Manager - 符合 POSIX 标准的 bash 脚本&#xff0c;用于管理多个活动的 node.js 版本 官网为 nvm-windows&#xff0c;点击这里进行下载 2、使用场景 比如有几个项目&#xff0c;这些项目的需求都不太一样&#xff0c;导致了这些个项目需要依赖的…