Flash Driver测试实验——LED Driver

Bootloader(二) 与上位机下载端建立可靠的总线通信以获取要更新应用程序:CAN驱动,CAN Driver 模块实现 CAN 报文的收发。 阅读详情
AI摘要

文章讲述了FlashDriver在汽车ECU升级中的作用,以及如何通过Keil5和.sct文件将driver代码从Flash搬入RAM执行,以确保功能安全。作者通过LED闪烁实验演示了代码迁移和内存区域分配的过程。

1、什么是Flash Driver

考虑到汽车ECU升级过程中可能存在外部干扰导致跑飞情况,如果直接将flash擦除有关程序固化到bootloader中,有可能在汽车运行过程中导致单片机flash被擦除或篡改的可能性,严重影响汽车的功能安全,所以一般会将与flash相关的程序单独剥离出bootloader,打包作为flash driver通过上位机下发的方式给到单片机。同时,单片机在接收到完整的flash driver包并通过校验后,会将其放入ram段执行调用;当在IAP升级过程中出现异常掉电或完成升级跳转至app程序中时,在ram段中的flash driver就不复存在了。

2、实验过程

在仔细思考flash driver运行过程后,我发现想要实现功能主要有以下疑问点:①如何将driver部分代码从flash搬入ram段执行;②如何在代码中(这里指整个代码工程)没有driver代码的情况下给driver分配一块区域;③通过什么方式将driver代码写入到规定好的ram段中。

由于仅做实验用途,我选用了最简单的测试代码——LED闪烁,测试环境为AutoChips杰发的AC7840x系列单片机开发板(ARM核 编译器Keil5),将LED闪烁的代码从工程中剔除,再通过按键触发将LED闪烁代码写入ram段,实现这个测试,下面我将根据这三个疑问点分布展开:

2.1 如何将driver部分代码从flash搬入ram段执行

通过Keil5的Linker修改.sct文件实现,操作步骤如下:

2.1.1 修改c代码

在想要放入ram段执行的函数前后分别加入#pragma arm section code = "XXX"和#pragma arm section字段,其中XXX可以自命名。要注意,如果你包含的函数中存在函数的调用,建议将所有相关的函数均包含在section字段中间(初始化函数不用放入),方便我们后面进行实验。

#pragma arm section code = "LED_DRV"
/*!
* @brief  GPIO翻转点亮函数
*
* @param[in] none
* @return none
*/
void LED_DRV_TOGGLE(void)
{
    GPIOC->PIOR = (1<<6);
    GPIOC->PIOR = (1<<7);
}
#pragma arm section

2.1.2 修改.sct文件

1、在勾选Use Memory Layout from Target Dialog的情况下先进行一次编译,编译器会根据你Target页的配置生成一个.sct文件

2、点击options魔术棒,选择linker

3、取消勾选Use Memory Layout from Target Dialog

3、点击Edit,即可弹出.sct文件

4、在单片机ram段处加入代码 *.o (LED_DRV),括号内的名字为前面在c代码中定义的section名称,这里大家根据自己用的单片机调下添加的地址即可,博主用的单片机SRAM起始地址为0x1FFF0000

LR_IROM1 0x00000000 0x00100000  {    ; load region size_region
  ER_IROM1 0x00000000 0x00100000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }
  RW_IRAM1 0x1FFF0000 0x00010000  {  ; RW data
   *.o (LED_DRV)
  }
  RW_IRAM2 0x20000000 0x00010000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

5、编译后查看map文件即可发现,编译器已经将flash的地址搬入ram中了,此时仿真程序也发现pc指针也指向的ram段

Execution Region LED_DRV (Exec base: 0x1fff0000, Load base: 0x00003008, Size: 0x00000018, Max: 0x00000018, ABSOLUTE)

Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object

0x1fff0000   0x00003008   0x00000018   Code   RO          104    LED_DRV             gpio.o

2.2 如何在代码中(这里指整个代码工程)没有driver代码的情况下给driver分配一块区域

我们回到2.1中说到的.sct文件,之前添加的代码将LED_DRV这个section放在了RW_IRAM1下,并且通过map文件我们可以知道,咱们的LED_DRV占用了0x18个大小的字节,知道了以上信息,下面更改一下.sct文件,将LED_DRV从RW_IRAM1里分离出来就可以了。

LR_IROM1 0x00000000 0x00100000  {    ; load region size_region
  ER_IROM1 0x00000000 0x00100000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }
  RW_IRAM1 0x1FFF0000 0x00010000  {  ; RW data
   *.o (LED_DRV)
  }
  RW_IRAM2 0x20000000 0x00010000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

改动完的.sct文件如下:可以看到我们单独定义了一块区域专门用来放0x18大小的LED_DRV section,这样我们就在SRAM开辟了一块区域。

LR_IROM1 0x00000000 0x00100000  {    ; load region size_region
  ER_IROM1 0x00000000 0x00100000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }
  LED_DRV 0x1FFF0000 0x00000018  {	 ; LED_DRV code
   *.o (LED_DRV)
  }
  RW_IRAM1 0x1FFF0018 0x0000FFE8  {  ; RW data
  }
  RW_IRAM2 0x20000000 0x00010000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

有的朋友就要说了,不对啊,光改了sct文件你现在flash里还是存在原来咱们在LED_DRV里添加的函数代码啊。说的没问题,下面我们之间把函数里面的内容删除,就留下一个“空壳”函数不就完成了咱们需要的操作了吗?代码如下:至此咱们完成了两项疑问点的操作,就剩下一项了,把LED_DRV_TOGGLE这个函数里面的代码重新放回到ram里去执行。

#pragma arm section code = "LED_DRV"
/*!
* @brief  GPIO翻转点亮函数
*
* @param[in] none
* @return none
*/
void LED_DRV_TOGGLE(void)
{
	//空函数等待写入
//	GPIOC->PIOR = (1<<6);
//	GPIOC->PIOR = (1<<7);
}
#pragma arm section

2.3 通过什么方式将driver代码写入到规定好的ram段中

首先,既然要写到ram里,我们就需要有东西写进去,可以通过查看hex文件的方式了解到目标写入的内容。在2.1中还没有删除driver部分的代码,从map文件可以看到载入地址为0x00003008。

打开hex文件找到地址所在代码数据,从0x00003008后共查找24个字节,即为咱们要的led driver代码了。

那么,重点到用什么方式写入呢,这里想了一些方法还是决定把led driver代码放到数组里,再传输到ram上即可,至此就完成了搬运的操作了,实验的目的也达成了。下面贴一下主函数给大家参考,在正常上电后LED为熄灭状态,当开关按下后在ram段写入led闪烁的驱动代码,然后就可以看到led以1s的周期闪烁了。

uint8_t function_code[0x18] = {0x40, 0x20, 0x04, 0x49, 0x08, 0x60, 0x80, 0x20, 0x02, 0x49, 0x8C, 0x39, 0xC1, 0xF8, 0x8C, 0x00, 0x70, 0x47, 0x00, 0x00, 0x8C, 0x50, 0x08, 0x40};

int main(void)
{
    uint8_t i;
    SystemClock_Config();	//初始化时钟
    GPIO_LedInit();		//初始化板载LED引脚
    GPIO_KeyInit();		//初始化板载按键引脚
    while (1)
    {
		if(1 == Get_Key4Value())	//按下开关后写入
		{
			for(i = 0; i<0x18; i++)
			{
				*(uint8_t *)(0x1fff0000 + i) = function_code[i];
			}
		}
		LED_DRV_TOGGLE();
		OSIF_TimeDelay(500);
    }
}

3、小结

通过此实验发现了一些问题,这里提出来:1、所有driver相关的函数需要全部放入ram段,不然编译器在编译之后会在map文件中添加一些链接,相当于还有一部分代码还是在flash中,没有达到driver不放在flash中的目的;2、文章只是使用了总工程下的hex文件作为写入ram的代码参考,如何单独制作一个driver工程并使用其hex文件,还存在一些问题。

用KeilMDK实现FlashDriver的制作` 汽车电子,OTA中,flash driver的制作 阅读详情

相关推荐

深入解析MCU Flash/LED Driver模式:从驱动原理到实测验证

在嵌入式系统开发中,GPIO(通用输入输出)是连接微控制器与外部世界的基础接口,其驱动能力直接决定了系统可靠性。推挽输出和开漏输出是两种基本模式,而Flash Driver或LED Driver则是在此基础上针对脉冲负载优化的特化模式。该模式通过增强瞬态驱动能力,能在极短时间内提供更大峰值电流,专门用于驱动LED等容性负载,同时兼顾低功耗设计需求。理解其底层原理对于排查LED点不亮、亮度不足等硬件问题至关重要。通过示波器实测驱动能力、压降和波形,结合STM32等平台进行稳态与瞬态性能对比,开发者可以优化GP

weixin_33727510的博客 467

车载ECU在OTA升级过程中,flash driver单独存在的意义

在ECU OTA 程序升级过程中,需要执行一段比较特殊的代码,这段代码实现对自身flash的擦除与写入,又称flash driver。 在OTA升级过程中,往往需要在发送app可执行文件之前,向底层先发送一段叫"flash driver"的二进制文件,这里简单总结一下这段“flash driver”二进制文件存在的意义。 1、在车载ECU控制器中,为了安全考虑,会尽可能的避免在代码中固化有对f......

xinjitmzy的博客 1万+

FPGA实现SPI Flash读写控制器的硬件设计

SPI Flash作为嵌入式系统中关键的非易失性存储介质,其可靠读写依赖于精确的时序控制与状态管理。FPGA凭借硬件级并行性与确定性时序,天然适合作为SPI Flash控制器的实现平台,相比MCU软件驱动可规避中断抖动、任务调度延迟等不确定性因素。其核心原理在于将SPI协议(Mode 0)、Flash指令集(如WREN、PAGE PROGRAM、RDSR)及状态轮询机制全部映射为同步状态机与计数器协同逻辑,确保每条指令的建立/保持时间、采样边沿和忙等待响应均满足JEDEC规范。该技术广泛应用于FPGA配置备

weixin_34779181的博客 400

【车载开发系列】了解FlashDriver

它是一种用于访问和管理闪存器件的驱动程序。FlashDriver通过与计算机系统进行交互,提供了对闪存器件的读写、擦除、复制等功能。闪存器件是一种非易失性的存储介质,用于它通常作为操作系统或应用程序的一部分,用于处理闪存设备的存储访问请求。

千月星跡 2171

Keil+J-Link配置HC32F460 Flash算法全流程指南

嵌入式开发中,MCU设备支持包(DFP)与调试器Flash算法协同工作是实现可靠固件烧录的基础技术。其原理在于:Keil通过DFP识别芯片架构、内存布局和启动流程,而J-Link依赖定制化Flash算法(.FLM)在目标RAM中执行擦写校验指令;二者通过CMSIS-PACK标准接口联动,缺一则触发‘Flash Algorithm not found’等典型错误。该技术方案具备高工程复用价值,广泛应用于国产MCU量产导入、工业控制固件升级及电机驱动开发场景。本文聚焦华大HC32F460在Keil MDK与J-

weixin_34380948的博客 345

新手避坑指南:用MDK-ARM和官方固件库点亮你的第一颗CW32F030芯片LED

本文详细介绍了如何在MDK-ARM开发环境中搭建CW32F030的开发环境,并通过官方固件库实现LED点亮的完整流程。文章特别针对新手常见的15个坑提供了解决方案,包括开发环境搭建、工程配置、GPIO控制及烧录调试等关键步骤,帮助开发者快速上手CW32F030芯片开发。

weixin_30352191的博客 416

NodeMCU 固件自测套件实战指南:NTest 框架、双 DUT 硬件测试环境与 tap-driver 主机编排

NodeMCU 是一个基于 Lua 的交互式固件(适用于 ESP8266、ESP8285 与 ESP32),为保障软件行为符合预期且不因版本迭代而回归,仓库内置了一套完整的自测体系。本指南以 [tests/README.md](https://link.gitcode.com/i/06e2118c842e9471ace00d94c82a5175) 为核心,系统讲解这套测试套件的组成:基于 [NTe

gitblog_00338的博客 431

STM32F4 Flash烧录失败?Keil Flash算法配置全指南

Flash编程算法是嵌入式开发中实现芯片固件烧录的核心机制,其本质是一段运行于RAM的专用ARM Thumb指令模块,负责控制Flash控制器完成擦除、编程与校验。理解该算法的原理,有助于解决Keil等IDE在STM32F4系列(如F407ZGT6)上常见的‘Cannot Load Flash Programming Algorithm’报错。相比F1系列的线性Flash架构,F4采用双Bank设计、多样化Sector粒度及ART加速器耦合机制,导致官方算法无法自动适配,必须手动注册匹配容量的.FLM文件(

weixin_34025051的博客 403

flash调试-用adb通过sysfs点亮flash

向led:flash_0节点写入亮度值 向led:switch_0节点的bringhtness写1,开启闪光灯。

极创it的博客 1641

ADI BF706 DSP程序烧写实战:手把手教你用Flash Programmer连接仿真器下载.ldr到Flash

本文详细解析了ADI BF706 DSP程序烧写的全流程,包括硬件连接、驱动配置、.ldr文件生成及烧写参数设置。通过实战演示和常见问题排查,帮助开发者高效完成Flash固件下载,特别适合使用CCES和仿真器进行嵌入式开发的工程师。

weixin_30655569的博客 309

TMS470 ARM7开发套件快速入门:从环境搭建到LED闪烁实战

嵌入式系统开发是软硬件协同设计的核心领域,其基础在于理解微控制器架构与工具链的配合。ARM7TDMI作为经典的RISC处理器内核,以其精简指令集和稳定的流水线设计,为实时控制应用提供了可靠的计算平台。在工程实践中,高效的开发环境部署与硬件调试是项目成功的关键,能够显著缩短开发周期并降低入门门槛。以TI的TMS470系列微控制器为例,它广泛应用于汽车电子和工业控制场景,其配套的IAR Embedded Workbench和J-Link调试器构成了完整的开发解决方案。本文聚焦于**TMS470开发套件**的快速

weixin_33829657的博客 376

嵌入式LED驱动开发:从GPIO控制到状态机设计的实践指南

在嵌入式系统开发中,GPIO(通用输入输出)控制是连接软件与硬件的基础操作,它允许微控制器通过引脚直接控制外部设备。其原理是通过配置寄存器来设置引脚的工作模式(输入、输出等)和电平状态,从而实现数字信号的读写。这项技术的核心价值在于提供了最底层的硬件交互能力,是驱动LED、按键、传感器等外设的基石。在工程实践中,为了高效、可靠地实现复杂功能(如LED闪烁),开发者常引入状态机(Finite State Machine)模型。状态机通过定义有限的状态和状态间的转移条件,将时序逻辑清晰化,特别适合处理如定时闪烁

weixin_34277853的博客 407

[AUTOSAR][Fls模块] Flash Driver Module

在汽车ECU软件运行中,软件代码运行安全性是第一,在代码中尽可能的不要固化有flash_erase、flash_write操作存在,主要是防止当出现异常情况时,程序跑飞,误调用erase、write对flash操作,使得原软件受到破坏,以致ECU不能正常工作。Flash访问代码(Access Code)不能存储在被操作的Flash物理块中,例如我要擦除一个Flash中某一个扇区内容,这个擦除动作的代码不能存在这个Flash物理块中(Flash中代码运行时,相当于读操作,此时不能擦写)

嵌入式单片机实验室 2137

STM32学习3--新建工程和LED点亮

打开配套资料并解压解压打开,就可以看到两个文件,新建工程时会用到。第三个文件project是官方提供的工程示例和模版,以后使用库函数的时候可以参考。打开Project文件夹,可以看到两个文件Utilities文件夹是STM32官方评估板的相关例程打开可以看到一个文件,评估板就是官方用STM32做的一个小电路板,用来测评STM32的,这个文件夹里面存的就是这个小电路板的测评程序。

zhixinzcc的博客 1387

claude使用教程

提供了三种模型:claude,codex, gemini,三种模型都共用同一个apikey, 有开发需求使用claude效果较好,知识问答等场景gemini效果会更好些,本文只提供了claude的安装方式,剩下两种按需按照以下参考链接安装下即可,安装有问题参考文档:https://www.aicodemirror.com/dashboard/official-installation/macos-linux (不需要挂梯子,自己手机号注册就好)

lichao19871216的博客 3488

Android8.1系统Led的控制从底层到上层的实现

玩了安卓这么久了,你是否有好奇,它的底层到上层或者上层到底层的标准流程是怎么走的呢?这里通过apk操作一个GPIO控制led的亮灭从而实现从上层到底层的完整调用流程。写得不足之处欢迎有识之士不吝赐教,在此先行谢过,技术无边,欢迎各位大牛来此多多交流。 Android Version:v8.0.1 Linux Version:V4.4 Hardware:mtk6739 1、在kernel层,编写和添...

Android/Linux驱动开发传帮带学习,让驱动入门门槛更低! 4415

LilyPad三色LED共阳极控制:从原理到Arduino编程实战

RGB LED作为可编程光源的核心组件,通过红、绿、蓝三原色的加色混合原理,能够生成丰富的色彩。其内部结构主要分为共阳极和共阴极两种类型,这决定了驱动电路的设计和编程逻辑。在电子织物和可穿戴设备领域,掌握RGB LED的控制技术对于实现动态光效和交互反馈至关重要。本文以LilyPad三色LED为例,深入解析其共阳极特性,并详细演示如何结合Arduino进行PWM编程,从而精准控制颜色与亮度,为智能服装、互动艺术装置等项目提供可靠的照明解决方案。

weixin_30237719的博客 606

ESP8266 RTOS驱动开发实战:从driver_lib工程到模块化项目构建

在嵌入式系统开发中,硬件驱动是连接微控制器与外部设备的桥梁,其稳定性和可复用性直接影响项目的开发效率与可靠性。驱动开发的核心原理在于通过抽象层封装底层硬件操作,提供统一的API接口,从而隔离硬件差异,简化上层应用逻辑。这一技术价值在于提升代码的模块化程度和可维护性,使得开发者能够快速构建复杂的物联网应用。常见的应用场景包括智能家居、工业控制、传感器数据采集等,其中稳定可靠的驱动是保障系统长期稳定运行的基础。本文以ESP8266的driver_lib工程为例,深入探讨了在RTOS环境下进行驱动开发、测试与模块

weixin_34306593的博客 336

Qt6安装保姆级教程:从国内镜像下载到配置避坑指南(附清华/中科大源)

本文提供详细的Qt6安装与配置指南,重点介绍如何利用清华大学、中国科学技术大学等国内镜像源解决下载速度慢的问题。内容涵盖在线安装器获取、组件选择策略、环境变量配置以及常见编译与部署问题的排查方法,旨在帮助国内开发者高效、顺畅地完成Qt6开发环境搭建。

weixin_29281915的博客 633

实验六 存储器实验

只读存储器(ROM)是一种在正常工作时其存储的数据固定不变,其中的数据只能读出,不能写入,即使断电也能够保留数据,要想在只读存储器中存入或改变数据,必须具备特定的条件。当地址为00000101时,会分别在数据位宽为8,16,32的只读寄存器中找到地址为00000101所对应的十进制地址位置,也就是地址为5的数据,并将其分别以8位,16位,32位输出。因此,输出保持为0。因此,当异步清零信号为1时,无论其他输入信号是什么,触发器的输出都会被强制清零,输出为0。1)寄存器输入0011,使能端1,异步清零0。

wenmou1111的博客 3001

使用Flash Tool Kit为CodeWarrior创建自定义Flash编程算法

在嵌入式系统开发中,Flash存储器编程是固件烧录的核心环节。其原理是通过调试接口向目标板发送特定命令序列,控制Flash芯片完成擦除、写入和校验操作。这项技术的价值在于,当开发工具链不支持新型号或冷门Flash芯片时,开发者能够突破限制,自主实现编程算法,从而保障项目硬件选型的灵活性并加速开发进程。Flash Tool Kit(FTK)正是恩智浦(NXP)为此提供的官方框架,它允许开发者基于芯片数据手册,编写运行在目标板RAM中的小程序(Applet),充当IDE编程器与物理芯片间的“翻译官”。本文以Co

weixin_30851867的博客 324

【IxNetwork】史上最全IxNetwork测试仪使用精讲(一),图文教程超赞超详细!!!

IXIA使用的是Server-client模式,Server端在测试仪表的主机上,在开机后会随着主机内的操作系统的启动而自动启动,一般情况下不需要人为的手工启动。因此在通常不需要为主机配置专用的显示器和键盘。client端包括两个测试软件: Ixia Explorer和ScriptMate。这两个软件一般安装在测试用计算机上,在仪表自带的主机中也有这两个软件。根据测试项目的不同来选择使用不同的软件。Ixia Explorer主要提供数据流的测试,针对设备的功能进行测试;

风云说通信 2056

Zephyr应用: 17-Driver

本课系统讲解Zephyr驱动开发核心,基于已掌握的内核基础,深入理解Device Model与Driver Framework。通过DEVICE_DEFINE()与DEVICE_DT_DEFINE()对比,掌握驱动注册、设备树绑定、驱动生命周期管理及API设计。结合最小驱动模板,实现从硬件抽象到应用调用的完整链路,最终独立编写可编译运行的完整驱动,打通软硬件交互通路。

cxicc的专栏 139

PHM 2010数据集解读

PHM数据挑战赛是一项面向所有潜在与会者的竞赛。今年的挑战集中在使用测力仪、加速度计和声发射数据估计高速数控铣床刀具的RUL上。 博客对PHM 2010数据集的组成和信号进行了可视化。

cnjs1994的博客 7648

16、二阶差分功耗分析(DPA)的再审视

本文深入探讨了二阶差分功耗分析(DPA)中的关键问题,包括不同组合函数的性能、信息论分析以及在有轮廓和无轮廓攻击场景下的实验结果。通过对掩码AES和DES的模拟和实际攻击实验,研究了归一化乘积、求和和绝对差值等组合函数在不同噪声水平下的效率,并强调了信息论分析在评估侧信道对抗措施中的重要性。

leaf8的博客 118
上一篇: 基于Cbrother脚本通过excel生成c代码
下一篇: TC38x Overlay配置及使用
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

您猜我猜不猜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值