Cache技术在星辰处理器中的应用

news2024/11/27 2:19:10

Cache技术在星辰处理器中的应用-修复MicroPython在MM32F5上启动慢的问题

文章目录

  • Cache技术在星辰处理器中的应用-修复MicroPython在MM32F5上启动慢的问题
    • 引言
    • Cache的工作原理
    • 需要关闭DCache的情况
    • 鱼和熊掌都想要
      • 使用内存保护单元MPU
      • 使用内存隔离/同步指令
    • 总结
    • 参考文献

引言

目前,灵动微控制器产品体系中,适配了MicroPython的,有MM32F3(MM32F3273G9P,Arm Cortex-M3)和MM32F5(MM32F5277E9P,ArmChina STAR-MC1),从官方数据来看,使用星辰处理器(STAR-MC1)的MM32F5对指令的处理效率要高于使用Cortex-M3处理器的MM32F3。如图x所示。
在这里插入图片描述

图x 星辰处理器同其他Arm处理器内核对比

然而,同一份MicroPython的启动过程,在使用同样主频(120MHz)的情况下,在MM32F5平台上运行,总是莫名其妙地慢好多。。。昨天跟同事Hao聊SDK的样例工程对Cache问题的处理策略时,偶然意识到,早期为MM32F5适配MicroPython的时候没有考虑过Cache,随即赶紧翻出来MicroPython的代码,果然没开。好吧,更新MicroPython项目下MM32F5平台的启动代码,替换来自于SDK中的system_mm32f5277e.csystem_mm32f5277e.h文件。

/*
 * Copyright 2022 MindMotion Microelectronics Co., Ltd.
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */


#include "hal_device_registers.h"

#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
  extern uint32_t __VECTOR_TABLE;
#endif

void SystemInit(void)
{

#if defined (__FPU_PRESENT ) && (__FPU_PRESENT == 1U)
  #if defined(__FPU_USED) && (__FPU_USED == 1u)
    SCB->CPACR |= (SCB_CPACR_CP10_MASK | SCB_CPACR_CP11_MASK); /* set CP10, CP11 Full Access */
  #endif
#endif /* __FPU_PRESENT */

#if defined (__ICACHE_PRESENT )&& (__ICACHE_PRESENT == 1U)
#ifndef ICACHE_DISABLED
  if (SCB->CLIDR & SCB_CLIDR_IC_Msk)
  {
    SCB_EnableICache();
  }
#endif /* DCACHE_DISABLED */

#endif /* __ICACHE_PRESENT */
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
#ifndef DCACHE_DISABLED
  if (SCB->CLIDR & SCB_CLIDR_IC_Msk)
  {
    SCB_EnableDCache();
  }
#endif /* DCACHE_DISABLED */
#endif /* __DCACHE_PRESENT */
}

/* EOF. */

其中,如果没有调用SCB_EnableICache()SCB_EnableDCache()函数,默认关闭ICache和DCache,配置宏__ICACHE_PRESENT__DCACHE_PRESENT来自于MM32F5270的芯片头文件mm32f5277e.h

#define __STAR_REV                0x0100U   /* Core revision r1p0 */
#define __SAUREGION_PRESENT       0U        /* SAU regions present */
#define __MPU_PRESENT             1U        /* MPU present */
#define __VTOR_PRESENT            1U        /* VTOR present */
#define __NVIC_PRIO_BITS          3U        /* Number of Bits used for Priority Levels */
#define __Vendor_SysTickConfig    0U        /* Set to 1 if different SysTick Config is used */
#define __FPU_PRESENT             1U        /* FPU present */
#define __DSP_PRESENT             1U        /* DSP extension present */
#define __ICACHE_PRESENT          1U        /* Define if an ICACHE is present or not */
#define __DCACHE_PRESENT          1U        /* Define if an DCACHE is present or not */

编译,验证。找来两块之前下载了MicroPython固件的MM32F5开发板,向其中一块板子下载启用ICache和DCache之后的新固件。运行程序后,同使用之前版本固件的程序相比,果然有明显的提升。如图x所示。

在这里插入图片描述

图x 启用Cache前后的MicroPython启动过程对比实物

图中板子运行程序启动MicroPython启动流程后,执行文件系统中Python源文件,闪烁小灯。图中下方的板子使用了启用Cache的程序,明显先完成MicroPython启动过程,先开始执行闪烁小灯的程序。

提交更新到代码仓库。Bingo!

commit 46372ed15d5769b25775a209c56d62c4cfc3ac5d (HEAD -> master, origin/master, origin/HEAD)
Author: Andrew SU <suyong_yq@126.com>
Date:   Wed Jun 14 11:02:06 2023 +0800

    update the startup code to enable the icache for mm32f5.

    - this fix would accelerate the speed of running the instruction
      sequence on mm32f5, which has the icache and dcache integrated.

    Signed-off-by: Andrew SU <suyong_yq@126.com>

启用Cache后,之前在MM32F5微控制器平台上运行MicroPython小概率会出现hardfault的问题也得到的缓解,颇有“治好了某人多年老寒腿”的赶脚。v

Cache的工作原理

Cache主要解决高速的CPU访问低速的存储器均衡速度差的问题,Cache通过预取数据/命令的机制,低速但整块地从低速存储器中取数据块,然后快速但串行地向CPU送数据流。高速的处理器大多使用哈佛结构,即使用指令总线和数据总线分别取指令和数据,对应有ICache和DCache。

Cache能够有效工作基于几个基本前提:

  • 空间局部性:在最近的未来,使用到的信息和当前使用的信息在空间上会是邻近的。这个因为数据大部分都是连续存储的。所以主存当中的数据都是成块传输到Cache当中。
  • 时间局部性:在最近的未来,使用到的信息可能是当前正在使用的信息。由于CPU本质上一个死循环,里面还有很多小循环的运行和操作,所以当前使用到的数据很可能会在循环当中,这样当前的数据有可能会在将来在再被调用一次。

另外,关于Cache还有其余部分需要了解:

  • Cache与主存的映射方式:解决主存内数据块和Cache当中数据块的对应关系。
  • 替换算法:Cache小,主存大。如果Cache中数据存满了之后,如何操作。
  • Cache写策略:如果CPU修改了Cache中的副本,如何确保Cache中的数据和主存中的母本数据保持一致。

关于Cache的工作原理,以及设计机制,可参考计算机专业考研四大专业课之《计算机体系结构》,以及参考文献中的《一文搞懂Cache基本原理》。

需要关闭DCache的情况

在微控制器系统中,有时会需要直接使用内存里的数据同外设交互,而不进入CPU,例如使用DMA(另一个总线主机AHB Master,但不需要Cache功能)相关,这种场景下,使用Cache的意义就不大了,甚至可能会出现数据不一致的风险,此时,就需要关闭Cache才能让系统正常工作。具体来说,ICache可以继续启用,毕竟指令都是送到CPU中执行,但DCache需要关掉,否则通过CPU写入到内存的数据未能及时同步物理内存时(基于Cache的写策略),启动DMA时搬运的数据不一定是实际需要传送的数据。另外,所有使用到“内嵌”DMA的外设模块的工程中,也需要小心谨慎地使用DCache,例如一些USB外设、ENET外设、显示加速器、以数据块为操作单元的加速计算模块等。

关ICache的情况虽然不多,但也存在,例如在涉及IAP应用中,从存放指令的介质中擦除指令、写入新指令后,再读指令,实际的新指令可能尚未替换到ICache中存放的旧指令,导致程序执行错误。

鱼和熊掌都想要

关闭DCache之后,CPU读数据的速度会明显慢很多,例如本文一开始展现的情况。怎样才能提升访问访问速度的同时,又能确保数据一致性呢?总不会人为频繁地开关Cache吧(很多微控制器对启动Cache的时机也有特别要求,需要在运行应用程序的一开始就要开启)。这里有两种可能的思路,供大家参考:

  • 使用内存保护单元MPU
  • 使用内存隔离/同步指令

这两种方法,分别是在空间上和时间上对数据进行隔离,控制仅在必要的空间上或时间上启用和关闭Cache。

使用内存保护单元MPU

MPU(Memory Protection Unit)内存保护单元在ARMv7-M架构下被引入。在 ARMv7-M架构下,Cortex-M3和Cortex-M4处理器对 MPU 都是选配的,不是必须的。ARMv8-M架构下继续沿用了MPU,星辰处理器STAR-MC1就使用了ARMv8-M。

MPU是一个可以编程的设备模块,可用来定义内存空间的属性,比如特权指令和非特权指令,以及Cache是否可访问。ARMv7-M通常支持8个region,每个region 代表一段连续的区域。

关于MPU的用法,可参见参考文献中的《ARM-MPU内存保护单元详解》和《Armv8-M Architecture Reference Manual》。

使用内存隔离/同步指令

ARM的指令集中,有内存隔离指令DMB(Data Memory Barrier)、DSB(Data Synchronization Barrier)和ISB(Instruction Synchronization Barrier):

  • 数据存储器隔离。DMB 指令保证: 仅当所有在它前面的存储器访问操作都执行完毕后,才提交(commit)在它后面的存储器访问操作。
  • 数据同步隔离。比 DMB 严格: 仅当所有在它前面的存储器访问操作都执行完毕后,才执行在它后面的指令(亦即任何指令都要等待存储器访问操作——译者注)。
  • 指令同步隔离。最严格:它会清洗流水线,以保证所有它前面的指令都执行完毕之后,才执行它后面的指令。

在一些ARM程序代码中,会用到__DSB() 指令,特别是在一些中断处理函数中。例如:

//中断定时器PIT中断处理函数
void PIT_LED_HANDLER(void)
{
    /* Clear interrupt flag.*/
    PIT_ClearStatusFlags(PIT, kPIT_Chnl_0, kPIT_TimerFlag);
    pitIsrFlag = true;
    __DSB();
}

程序通过中断信号进入中断处理函数时,首先应当清除相应的中断标志位,但有些CPU的时钟太快,快于中断使用的时钟,就会出现清除中断标志的动作还未完成,CPU就又一次重新进入同一个中断处理函数,导致死循环,__DSB() 指令的作用就是避免上述情况的发生。

总结

本文从修复MicroPython启动程序在MM32F5微控制器上比较慢的问题,体验了星辰处理器中Cache的作用。简单介绍了Cache的工作原理和机制,重点介绍了使用Cache可能存在的风险,并进一步探讨了如何能用到Cache高速存取的同时避免数据不一致的情况。

参考文献

  • 《using-stm32-cache-to-optimize-performance-and-power-efficiency》,https://www.st.com/resource/en/application_note/an5212-using-stm32-cache-to-optimize-performance-and-power-efficiency-stmicroelectronics.pdf
  • 《一文搞懂Cache基本原理》,https://zhuanlan.zhihu.com/p/581834020
  • 《ARM-MPU内存保护单元详解》,https://blog.csdn.net/lt6210925/article/details/120387536
  • 《Armv8-M Architecture Reference Manual》,https://developer.arm.com/documentation/ddi0553/bo
  • 《__DSB()指令的作用》,https://blog.csdn.net/missiler/article/details/107796862
  • 《ARM指令:ISB DSB,解决指令执行不同步的问题》,https://blog.csdn.net/wangbotao1990/article/details/88428405

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

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

相关文章

catkin cmake官方教程解读以及资料补充

这里写目录标题 cmakei下载cmake 官方教程教程1step1最低版本 报错报错2 vscode 路径没有配置好setting.json通过该方式打开的似乎是一个全局的文件&#xff0c;可以为本工作文件夹下设置一个本地的吗 报错3配置cmake工具链准确的流程报错4 cpp中main函数返回值问题结果 官方教…

虚拟机centos7无法正常启动:Generating“/run/initramfs/rdsosreport.txt“

一、问题描述 1.出现问题的原因 Centos 7 断电导致 &#xff0c;最近电脑老是自己蓝屏&#xff0c;然后重启电脑&#xff0c;一个月里断断续续可能有个3次左右&#xff0c;突然发现启动就这个问题&#xff0c;估计是虚拟机异常物理断电导致的系统磁盘出错了 2.具体的报错信息…

打开冒险岛提示丢失vcruntime140.dll的解决方法

今天准备打开冒险岛软件的时候&#xff0c;当打开我自己的冒险岛软件后&#xff0c;弹出了一个对话框&#xff0c;内容是&#xff1a;由于找不到vcruntime140_1.dll&#xff0c;无法继续执行代码。重新安装程序可能会解决此问题。 我很纳闷&#xff0c;前几天还好好着呢。于是…

【ARIMA-WOA-LSTM】合差分自回归移动平均方法-鲸鱼优化-长短期记忆神经网络研究(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

vue新手入门实践教程

介绍vue运行环境的搭建、vue项目的初步构建与运行、使用element-ui组件构建页面内容、使用页面模块与路由设置等。基于此教程&#xff0c;可以初步实现一个静态网页&#xff0c;并对vue项目由一定理解。 1、基本环境安装 vue项目的编译运行依赖nodejs环境&#xff0c;故需要下…

使用rasterio计算tif文件中两点之间的物理实际距离

假设有一张含有地理坐标信息的tif格式的图片及其对应的jpg或者png格式的普通图片 如下图所示&#xff1a; 其中第一张为tif格式的地理信息图&#xff0c;第二张为按照一定比例下采样之后转换得到的普通jpg图片 如何计算jpg图片中任意两点之间的实际距离呢&#xff1f; 比如&a…

终于等到你:期待已久的CAD .NET 15 Crack

期待已久的CAD .NET 15 现已推出&#xff01;新包包括一个.NET 6 框架构建。目前&#xff0c;它仅与 Windows 兼容&#xff0c;但我们计划在未来的版本中添加对 Linux 的支持。 我们还进行了一系列更改以增强库的稳定性并改进其导入和导出功能。他们来了&#xff1a; 改进了 DW…

Scala--03

第6章 面向对象 Scala 的面向对象思想和Java 的面向对象思想和概念是一致的。 Scala 中语法和 Java 不同&#xff0c;补充了更多的功能。 6.1类和对象详解 6.1.1组成结构 构造函数: 在创建对象的时候给属性赋值 成员变量: 成员方法(函数) 局部变量 代码块 6.1.2构造器…

详解c++---map的介绍

目录标题 map容器的介绍pair的介绍map的构造函数insert函数make_pair函数find函数map的[ ]重载multimap map容器的介绍 通过之前的学习想必大家对set容器的理解应该非常的深刻了&#xff0c;我们知道他的底层是一个k结构的搜索二叉树&#xff0c;可以对数据进行去重并排序&…

Redis实现分布式锁详解

Redis实现分布式锁详解 一 分布式锁简介二 Redis实现分布式锁核心思路三 Redis实现分布式锁实践3.1 锁的基本接口3.2 加锁解锁逻辑3.3 修改业务逻辑3.4 单元测试观察结果 四 Redis分布式锁误删情况4.1.Redis分布式锁误删情况逻辑说明&#xff1a;4.2 解决Redis分布式锁误删问题…

当心健身跑步应用悄悄泄露用户住址

据BleepingComputer 6月11日消息&#xff0c;美国北卡罗来纳州立大学罗利分校的研究人员发现 Strava 应用程序的热图功能存在隐私风险&#xff0c;可能导致攻击者识别出用户的家庭住址。 Strava 是一款流行的跑步伴侣和健身追踪应用程序&#xff0c;在全球拥有超过 1 亿用户&a…

2个月“我“从功能测试进阶到自动化测试,offer收到麻了...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 自动化测试是将人…

C++【STL】之vector模拟实现

C vector类模拟实现 上一篇讲解了vector的使用&#xff0c;这一篇接着介绍vector的模拟实现&#xff0c;这里依然是讲解常用接口的模拟实现&#xff0c;话不多说&#xff0c;正文开始&#xff01; 文章目录&#xff1a; C vector类模拟实现1. 成员变量2. 默认成员函数2.1 构造…

使用lcov生成覆盖率报告

使用lcov生成覆盖率报告 1- 需要准备的东西1.1 工具lcov1.2 需要用到中间脚本 gcno gcda1.3 源文件 2- 生成覆盖率报告2.1 step1: 编译阶段2.2 step2: 数据收集与提取阶段2.3 step3: 报告形成阶段2.4 step4: lcov生成覆盖率报告结果info文件2.5 step5: genhtml 命令生成网页版的…

给定一个字符串比如“abcdef”,要求写个函数变成“defabc”,位数是可变的。

首先可以使用字符串切片的方法来实现这个需求。 具体做法是&#xff1a;① 定义一个整数变量 n 表示要切割的位置&#xff0c;本实例中为 3 。 ② 将字符串按照 n 分割成两个字串&#xff0c;即 “abc” 和 “def”。 ③ 将两个字符串颠倒顺序&#xff0c;即 “cba” 和 “fed…

数据结构 栈和队列

栈和队列基本概念 栈&#xff08;Stack&#xff09;和队列&#xff08;Queue&#xff09;都是常见的数据结构&#xff0c;用于存储和操作一组元素。它们在结构和操作方式上有所不同。 栈的基本概念&#xff1a; 栈是一种线性数据结构&#xff0c;具有后进先出&#xff08;L…

CentOS GCC 离线升级 编译安装 8.3.0

从系统自带的 gcc-4.8.5 版本升级至 gcc-8.3.0 版本 目录 下载源代码&#xff1a; 下载依赖&#xff1a; 编译&#xff08;约一个小时&#xff09; 重开控制台确认是否生效 下载源代码&#xff1a; https://ftp.gnu.org/gnu/gcc/gcc-8.3.0/gcc-8.3.0.tar.gzhttps://ftp.gn…

Nacos和Feign

Nacos配置管理 统一配置管理实现 1.引入Nacos的配置管理客户端依赖 <!--nacos的配置管理依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency…

国产开源中文大语言模型再添重磅玩家:清华大学NLP实验室发布100亿参数规模的开源可商用大语言模型CPM-Bee

5月27日&#xff0c;OpenBMB发布了一个最高有100亿参数规模的开源大语言模型CPM-BEE&#xff0c;OpenBMB是清华大学NLP实验室联合智源研究院成立的一个开源组织。该模型针对高质量中文数据集做了训练优化&#xff0c;支持中英文。根据官方的测试结果&#xff0c;其英文测试水平…

Python零基础入门(二)——IDE介绍以及Python+PyCharm的安装

系列文章目录 个人简介&#xff1a;机电专业在读研究生&#xff0c;CSDN内容合伙人&#xff0c;博主个人首页 Python入门专栏&#xff1a;《Python入门》欢迎阅读&#xff0c;一起进步&#xff01;&#x1f31f;&#x1f31f;&#x1f31f; 码字不易&#xff0c;如果觉得文章不…