首页 > 其他分享 >FLASH不够用——非零等待FLASH搬到RAM运行

FLASH不够用——非零等待FLASH搬到RAM运行

时间:2023-04-20 16:45:22浏览次数:29  
标签:FLASH 代码 RAM 非零 a1 地址 等待

本文主要实现将FLASH中的代码搬运到RAM运行

我们的CH32V2/3系列MCU有几十K,几百K的非零等待FLASH,遇到FLASH不够用的情况实在可惜。主要以V307举例,针对零等待FLASH不够用的情况。

典型应用:

1.IAP占用了几K空间,搬到RAM后,可以让IAP所占零等待FLASH大幅降低,接近忽略

2.切换功能的代码,不会同时使用的分块的代码,切换的时间几十ms级别

实现思路:

1.将要搬到RAM里的代码在编译阶段用RAM地址编译,原因是code运行的时候,地址是绝对地址

LD文件中修改FLASH和RAM起始地址以及长度

此处需要注意的是RAM的起始地址+长度不能超过实际RAM的大小,否则会进Hardfault,因为堆栈是从RAM最后面往前的

这一步的必要条件是,编译的代码需要能在RAM里放的下,否则的话就需要在零等待的FLASH里放一部分

然后生成bin文件,之后要把bin放到非零等待的地址上,再烧到MCU里

2.编写 从FLASH搬到RAM的代码

这部分代码是放在零等待FLASH的,此处仅实现简单的搬运,没有条件判断等操作,所以选择直接修改启动文件里的handle_reset,不涉及C的部分,LD不需要改

handle_reset:
.option push
.option norelax
  la gp, __global_pointer$
.option pop
1:
  la sp, _eusrstack

2:
  /* 把flash里的代码搬到RAM,这里只搬code,跳转到code后,code的代码会自己搬data*/
  la a0, 0x08020000/*flash起始地址128K*/
  la a1, 0x20000000/*RAM起始地址0K*/
  la a2, 0x20005000/*RAM结束地址20K*/
  bgeu a1, a2, 2f
1:
  lw t0, (a0)
  sw t0, (a1)
  addi a0, a0, 4
  addi a1, a1, 4
  bltu a1, a2, 1b

2:
  li t0, 0x1f
  csrw 0xbc0, t0

 

  la a0,0x20000000
  jr 0(a0)/* 跳转到RAM中的起始地址 */

3.烧录

第1步要运行的主体的bin烧录地址是非零等待区0x20000,第2步搬运代码的地址是正常的零等待区地址0x0。合并后一起烧录,即可实现。

总结:

本文实现了最简单的从flash搬运到ram运行,汇编生成的代码大概是120字节,远远小于IAP的几K字节。

如果不用汇编搬运,进入C的世界也是可以的,还可以进行复杂的判断,选择不同功能代码搬运,不过这里要注意的是:进入了C的世界,堆栈会起作用,所以搬运的时候要注意预留搬运时的堆栈的RAM开销。C的世界里跳转  和  IAP跳APP一样,需要用软件中断。

这里的主要思想来源于堆栈的动态内存,利用代码可以在RAM运行,一样可以有动态的代码空间。

当理解了这个过程,地址可以任意的修改,甚至配合零等待FLASH实现更多功能,彻底激活非零等待区域的FLASH空间。

其它注意事项:

1.如果开启了读保护,FLASH前4K自动写保护,所以在用IAP的时候要注意,即使有空间了,也要注意前4KFLASH在读保护使能的情况下是无法擦写的。

标签:FLASH,代码,RAM,非零,a1,地址,等待
From: https://www.cnblogs.com/wchmcu/p/17337337.html

相关文章

  • Centos7 开机时遇到initramfs-xxx.img not found错误导致虚拟机无法开启问题处理
    1、背景一台运行在Esxi上面的VM重启后报initramfs-xxx.imgnotfound错误。按任意键后出现以下错误。之前在运维Centos7的时候解决过Kernelpanic-notsyncing:VFS:Unabletomountrootfsonunknown-block(0.0)错误,以为按照之前的解决方案,重启服务器,按Esc进入选择内......
  • CodeForces - 367B Sereja ans Anagrams (map)
    CodeForces-367BSerejaansAnagramsTimeLimit: 1000MS MemoryLimit: 262144KB 64bitIOFormat: %I64d&%I64uSubmit StatusDescriptionSerejahastwosequences a and b andnumber p.Sequence a consistsof n integers a1, a......
  • Programming: array
      Cintarr[5];bracketsmustfollowtheidentifier,definitionofvariablewitharraytypeneedsanexplicitsizeofaninitializer  ......
  • CH58xFLASH操作
    一、描述读:从FLASH将数据赋值给buff;写:从buff将数据赋值给FLASH;DataFlash特点:擦/ERASE写/READ读/WRITE0.25KB(的倍数)/4KB(的倍数)1Byte/多个Byte/256Byte(的倍数,best)1Byte/多ByteCodeFlash特点:擦/ERASE写/READ读/WRITE4KB(的倍数)4Byte4Byte/256Byte(的倍......
  • GDB frame和backtrace命令:查看栈信息--附gdb完整参考
    当程序因某种异常停止运行时,我们要做的就是找到程序停止的具体位置,分析导致程序停止的原因。对于C、C++程序而言,异常往往出现在某个函数体内,例如main()主函数、调用的系统库函数或者自定义的函数等。要知道,程序中每个被调用的函数在执行时,都会生成一些必要的信息,包括:函数调......
  • 痞子衡嵌入式:恩智浦经典LPC系列MCU内部Flash IAP驱动入门
    大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是恩智浦经典LPC系列MCU内部FlashIAP驱动。LPC系列MCU是恩智浦公司于2003年开始推出的非常具有代表性的产品,距今已经有近20年的生命。按时间线演进来说,其主要分为三代:-元老:基于ARM7/9内核的LPC2000......
  • 关于将常量数组或某一函数单独或一起放在FLASH某一位置
    第一种情况:将数组或某一函数单独放在FLASH某个位置,具体配置如下图。.text1:{.=ALIGN(4);*(.text1)*(.text1.*).=ALIGN(4);}>FLASH1AT>FLASH1__attribute__((section(".text1")))voidCPUDelay(volatileuint32_t......
  • npm : 无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本
    在新建项目时候遇到一个问题如上图,安装cnpm或者node都会报这个错误找了半天发现解决方法如下(操作如上图)1、打开终端2、在终端执行:get-ExecutionPolicy,显示Restricted(表示状态是禁止的)3、在终端执行:set-ExecutionPolicyRemoteSigned4、在终端执行:get-ExecutionPolicy,显示RemoteSig......
  • 视频元数据信息中,视频流的总帧数和音频流的总帧数有什么区别(nb_frames)
    视频流的总帧数指的是视频中所有帧的数量,包括关键帧和非关键帧。而音频流的总帧数指的是音频采样的总数,每帧通常包含数百个采样点。在视频中,每一帧都是由图像编码器编码成的一张静态图片。视频编解码器会根据压缩算法来选择性地对某些帧进行丢弃或者合并,以达到压缩视频大小的目的......
  • Unity框架:JKFrame2.0学习笔记(五)——事件系统(2)
    前言上一篇记录了框架的事件系统的内部构成和实现,这篇记录下事件系统的使用。如何使用新建脚本EventTestusingJKFrame;usingUnityEngine;publicclassEventTest:MonoBehaviour{voidStart(){//添加监听EventSystem.AddEventListener("inp......