微软|嵌入式开发:加速基于flash的嵌入式应用程序

【微软|嵌入式开发:加速基于flash的嵌入式应用程序】微软|嵌入式开发:加速基于flash的嵌入式应用程序

文章图片


大多数现代嵌入式软件应用程序都是从闪存存储和执行的 。 闪存为基于微控制器的应用程序提供了一种廉价且快速的存储介质 。 但这些应用程序通常是实时应用程序 , 其中执行时间和确定性行为至关重要 。 虽然闪存速度很快 , 但不如从RAM执行代码快 。 为了加快基于flash的应用程序的执行时间 , 嵌入式开发人员可以有选择地选择关键功能并从RAM中执行它们 , 以获得额外的速度提升 。
为了从RAM执行功能 , 开发人员通常需要遵循三个步骤 。 这些措施包括:1.在链接器中为函数创建RAM区域;2.指定哪些函数应存储在RAM中;3.启动时将功能复制到RAM中 。
让我们详细检查这个过程 。
步骤1–在链接器中为函数创建RAM区域
每个编译器都有不同的语法来定义微控制器中的内存区域 。 对于今天的示例 , 我将使用基于GCC的CodeComposer Studio和Texas仪器C2000系列使用的语法 , 因为我认为它提供了一个很好的示例 。
当我们修改链接器文件以包含将从RAM执行的函数时 , 我们需要创建一个内存部分 , 该部分将指定函数从何处加载到RAM中 , 以及该函数从何处加载到RAM中 。 链接器文件将包含指定重要程序分配的区域 , 例如:
cinit
text
codestart
stack
constants
···
嵌入式开发人员需要为其RAM功能创建一个区域 。 这可以通过以下方法实现:
ramfuncs: LOAD = FLASHA
RUN =RAML0
LOAD_START (_RamfuncsLoadStart)
LOAD_END (_RamfuncsLoadEnd)
RUN_START (_RamfuncsRunStart)
LOAD_SIZE (_RamfuncsLoadSize)
PAGE =0
如你所见 , 这是在RAM中创建一个名为ramfuncs的区域 。 RAM区域是从存储在闪存A扇区中的函数加载的 。 它被指定在RAM区域RAML0中运行 。 然后有一些定义用于指定RAM函数的开始和结束位置以及它们的大小 。 这些值在步骤#3中很重要 。

步骤2–指定哪些函数应存储在RAM中
一旦我们在链接器中创建了一个RAM部分来存储我们的函数 , 我们就需要向链接器指定哪些函数应该驻留在那里 。 最常用的方法是使用#pragma 。 一般来说 , 我们应该尽量避免在代码中使用#pragma , 因为这些功能依赖于编译器 。 这意味着 , 如果编译器发生更改 , 嵌入式开发人员很可能不得不修改#pragma行 。 就我们今天的目的而言 , 这没有问题 , 因为我们无论如何都必须修改一个新的链接器文件 , 并且我们需要找出正确的语法来指定如何在内存区域中放置函数 。
通常从RAM执行的一组常见功能是与访问和控制闪存有关的功能 。 原因是当我们想要写入或擦除闪存时 , 大多数微控制器不允许你同时从闪存执行代码!所以 , 我们无论如何都需要把这些函数放到RAM中 。 我们可以使用类似于以下代码的代码将诸如Flash_Init之类的函数放入RAM区域:
#pragmaCODE_SECTION(Flash_Init “ramfuncs”);
从该语句中可以看出 , 我们正在使用自定义编译器指定代码_部分来指定函数Flash_Init应放置在链接器的ramfuncs区域中 。 此语句通常直接放在函数定义的上方 , 以提醒任何处理函数的开发人员它将被放入RAM中 。 (这也使得我们更容易找到是否应该决定函数不需要放在RAM中) 。
步骤3–启动时将功能复制到RAM中
该过程的最后一步是确保在微控制器启动期间 , 我们想要在RAM中执行的功能实际上被复制到RAM中 。 最简单的方法是使用memcpy 。 我通常在配置系统时钟和中断向量表后不久 , 但在初始化板载外围设备和应用程序代码之前 , 执行此复制 。 我在步骤1中提到 , 我们定义了几个变量 , 这些变量稍后会派上用场 。 这些是RamfuncsRunStart、RamfuncsLoadStart和RamfuncsLoadSize 。 我们将使用以下语句将这些函数与memcpy一起复制到RAM中: