使用clion向STM32H7外置flash下载代码

简介

根据安福莱的STM32H7教程,H7单片机的QSPI外设是直接连到芯片内核上的,地址是0X90000000;那么就可以通过QSPI外设,将外置flash内存映射,并由此执行代码。

STM3H7单片机矩阵架构
相关操作在keil5上比较简单,配置点东西就行;可以参考安福莱教程。

这里要介绍的是在linux环境下没有keil5 IDE的情况下,如何使用clion+openocd实现

  • 将大体积代码下载到外置flash并执行
  • 对外置flash执行的代码进行仿真

代码配置

修改系统配置文件

STM32的代码都是有起始地址的,每一句代码,编译为相关机器码执行时,都有对应地址的;对于一般情况的代码,起始地址都是0X8000000;

工程FLASH配置文件
该文件中详细的配置了单片机所使用的flash大小,ram大小,地址等信息。

由于采用外置flash启动,我们需要将flash地址配置为QSPI地址,并修改LENGTH为我们的flash芯片大小。

MEMORY
{FLASH (rx)     : ORIGIN = 0x90000000, LENGTH = 8192KDTCMRAM (xrw)  : ORIGIN = 0x20000000, LENGTH = 128KRAM_D1 (xrw)   : ORIGIN = 0x24000000, LENGTH = 512KRAM_D2 (xrw)   : ORIGIN = 0x30000000, LENGTH = 288KRAM_D3 (xrw)   : ORIGIN = 0x38000000, LENGTH = 64KITCMRAM (xrw)  : ORIGIN = 0x00000000, LENGTH = 64K
}

修改系统初始化函数

STM32单片机启动时会先执行汇编启动文件,先定义中断向量表,再执行复位,设置栈顶指针,再执行系统初始化函数,再跳转main函数。

其中系统初始化函数中需要修改SCB->VTOR的值。
==SCB->VTOR为Cortex内核的中断向量表的基地址,一般为程序执行的初始地址。 #12AA9C==
关于该变量理解,参考链接

这里需要修改为我们程序启动的地址0X90000000。
SCB->VTOR地址修改

编译

点击编译,即可制作一个运行在外部flash的代码,下载到外置flash中,引导运行即可。

那么现在出现两个问题:

  • 如何下载到外置flash
  • 如何从外置flash中启动

代码下载

使用CubeProgramer工具下载

使用ST提供的下载工具下载;
需要:

  • 对应板子的下载算法文件
  • 烧录器
  • 能够运行在外置flash的代码

刚才已经成功编译了外置执行代码,烧录器咱也有,而烧录算法呢,推荐看安福莱的相关教程。
相关教程

使用Clion下载

这个是我主要想讲的,在一个编辑器里完成编译、下载、调试,嘿嘿

先解决下载问题。

我们知道,STM32下载代码时会先执行一个配置程序,该程序运行在RAM中,会初始化部分关于下载代码的外设。

使用keil5时,我们会使用一个.flm文件下载代码,该文件就是下载引导程序,其制作流程安福莱里讲的有。

反客的keil5下载教程

同样,在正常下载的时候也会有一个keil5官方提供的.flm文件,这些文件就储存在官方目录里。

对于CubeMX而言,也有相应的文件,

所以,我们使用的openocd工具也是有的,在我们的工程目录里,有一些配置文件,都具有各自相应的功能。

clion工程目录
在stm32h750b-disco.cfg文件中,初始化了芯片时钟,和部分必要的下载外设;

在19行、23行:跳转到了其他配置文件中,执行具体的操作

# enable stmqspi
if {![info exists QUADSPI]} {set QUADSPI 1
}source [find target/stm32h7x.cfg]reset_config srst_onlysource [find board/stm32h7x_dual_qspi.cfg]

在这里,代码定义了QUADSPI为1,即会在stm32h7x_dual_qspi.cfg中执行该外设的初始化;

但是,这里该外设的初始化是以STM32官方出的板子的引脚定义的,不一定适合我们,而且实操下来,该文件改来改去效果不大,而且我觉得不建议跳到人家官方配置文件里修修改改,这里我们直接在该配置语句下面执行我们板子的配置代码;

# ART_Pi qspi.# QUADSPI initialization
proc qspi_init {  } {global ammw 0x580244E0 0x000007FF 0             ;# RCC_AHB4ENR |= GPIOAEN-GPIOKEN (enable clocks)mmw 0x580244D4 0x00004000 0             ;# RCC_AHB3ENR |= QSPIEN (enable clock)sleep 1                                 ;# Wait for clock startup# PF10:AF09:H, PF09:AF10:H, PF08:AF10:H, PF07:AF09:H, PF06:AF09:H, PG06:AF10:H# Port F: PF10:AF09:H, PF09:AF10:H, PF08:AF10:H, PF07:AF09:H, PF06:AF09:Hmmw 0x58021400 0x002AA000 0x00155000    ;# MODERmmw 0x58021408 0x002AA000 0x00155000    ;# OSPEEDRmmw 0x5802140C 0x00000000 0x003FF000    ;# PUPDRmmw 0x58021420 0x99000000 0x66000000    ;# AFRLmmw 0x58021424 0x000009AA 0x00000655    ;# AFRH# Port G: PG06:AF10:Hmmw 0x58021800 0x00002000 0x00001000    ;# MODERmmw 0x58021808 0x00002000 0x00001000    ;# OSPEEDRmmw 0x5802180C 0x00000000 0x00003000    ;# PUPDRmmw 0x58021820 0x0A000000 0x05000000    ;# AFRL# correct FSIZE is 0x16, however, this causes trouble when# reading the last bytes at end of bank in *memory mapped* mode# for single flash mode w25q64jv;# 010101010000000000000 0 011000mww 0x52005000 0x05500018               ;# QUADSPI_CR: PRESCALER=5, APMS=1, FTHRES=1, FSEL=0, DFM=0, SSHIFT=1, TCEN=1mww 0x52005004 0x00160500               ;# QUADSPI_DCR: FSIZE=0x16, CSHT=0x05, CKMODE=0;# FSIZE flash的大小。mww 0x52005030 0x00001000               ;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full;# 11010000000000 10 010100000011mww 0x52005014 0x0D002503               ;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1mmw 0x52005000 0x00000001 0             ;# QUADSPI_CR: EN=1# Exit QPI mode#mmw 0x52005000 0x00000002 0            ;# QUADSPI_CR: ABORT=1#mww 0x52005014 0x000003F5              ;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=Exit QPIsleep 1# reset flashmmw 0x52005000 0x00000002 0             ;# QUADSPI_CR: ABORT=1mww 0x52005014 0x00000166               ;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=0x66mww 0x52005014 0x00000199               ;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=0x99# memory-mapped read mode with 3-byte addressesmmw 0x52005000 0x00000002 0             ;# QUADSPI_CR: ABORT=1;# 11 11 0 00100 00 11 10 11 01 11101011mww 0x52005014 0x0F10EDEB               ;# QUADSPI_CCR: FMODE=0x3, DMODE=0x3, DCYC=0x4, ADSIZE=0x2, ADMODE=0x3, IMODE=0x1, INSTR=READ;mww 0x52005014 0x0D002503
}$_CHIPNAME.cpu0 configure -event reset-init {global QUADSPImmw 0x52002000 0x00000004 0x0000000B    ;# FLASH_ACR: 4 WS for 192 MHZ HCLKmmw 0x58024400 0x00000001 0x00000018    ;# RCC_CR: HSIDIV=1, HSI onmmw 0x58024410 0x10000000 0xEE000007    ;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clockmww 0x58024418 0x00000040               ;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1mww 0x5802441C 0x00000440               ;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2mww 0x58024420 0x00000040               ;# RCC_D3CFGR: D3PPRE=2mww 0x58024428 0x00000040               ;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSImmw 0x5802442C 0x0001000C 0x00000002    ;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=widemww 0x58024430 0x01070217               ;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24mmw 0x58024400 0x01000000 0             ;# RCC_CR: PLL1ON=1sleep 1mmw 0x58024410 0x00000003 0             ;# RCC_CFGR: PLL1 as system clocksleep 1adapter speed 24000if { $QUADSPI } {qspi_init}
}

改代码中主要就初始化了QSPI外设的GPIO,并配置了QSPI外设,使用的板子是ART-Pi;

使用的GPIO是: PF10,PF09,PF08,PF07,PF06,PG06.

相关外设初始化主要时钟匹配自己的芯片速度。

这里主要参考链接:

在CLion上实现STM32H750VBT6的Bootloader

使用openOCD擦写ART_Pi外部qspi_flash

两个教程都很全面,并且将代码文件、配置文件都开源了,去点星星咯。

大家可以根据自己的板子的引脚定义进行修改相关寄存器即可。

到这里,基本完成了配置,可以实现在clion中通过openocd实现向单片机外置flash下载代码,并进行仿真调试了。

从外置flash中启动代码

不管上面如何下载代码,都需要从外置flash启动,前面也简略提到了——我们需要在单片机的内置flash中下载一个bootloader代码,用于从外置flash启动。

这个代码比较简单,就初始化一点点外设,主要还是QSPI,然后关闭Cache、MPU,对外置flash进行内存映射,并启动。具体内容可以参考安福莱教程。

硬汉嵌入式的bootloader教程

我的是修改的反客科技的bootloader代码,将其QSPI外设的引脚改成我的板子的就可以用了。是之前用keil5写的,也可以自己用cubemx生成一个,添加应用代码即可。比较简单。

适配ART-Pi的下载算法和bootloader

另外,从外置flash引导的代码,受flash限制,运行速度并不快,不如芯片内部的flash,对此,我们参考安福莱教程,使用MPU配置外置flash内存,用Cache预存取指令,提高代码运行速度。相关配置:
Cubemx配置

  MPU_Region_InitTypeDef MPU_InitStruct = {0};/* Disables the MPU */HAL_MPU_Disable();/** Initializes and configures the Region and the memory to be protected*/MPU_InitStruct.Enable = MPU_REGION_ENABLE;MPU_InitStruct.Number = MPU_REGION_NUMBER0;MPU_InitStruct.BaseAddress = 0x90000000;MPU_InitStruct.Size = MPU_REGION_SIZE_8MB;MPU_InitStruct.SubRegionDisable = 0x0;MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;HAL_MPU_ConfigRegion(&MPU_InitStruct);/* Enables the MPU */HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);

MPU配置代码。

相关教程:

理论学习,详细好理解

硬汉哥的MPU教程

硬汉哥的实战教程,超级好用

添加

在clion使用openocd仿真的话,为了查看各个寄存器的值,需要添加寄存器配置文件,一般keil5安装目录里有,我把我的上传到Github上了,欢迎下载。

SVD文件

仿真视图

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows和Ubuntu网络文件共享

Windows11访问Ubuntu22.04共享文件夹 ubuntu配置右键选中需要共享的文件夹,选择属性->本地网络共享;选中共享此目录、允许其他人创建和删除这个文件夹里的文件、允许匿名登陆;并设置共享名配置好之后,点击修改共享。如果没有安装过samba服务,则会提升安装samba相关依赖…

Linux下使用clion+cubemx+openocd开发stm32

简述 后面需要在linux下学习驱动开发,然后不想玩虚拟机,就直接安装了双系统。用kde桌面玩的蛮开心的,就索性把win下的开发内容都搬过来吧 在Linux下开发STM32,使用Clion和Cubemx开发,openocd调试,关于芯片下载,编译器选项,代码起始内容都需要自行通过工程的配置文件修改…

银行视频监控智能分析

视频监控智能分析银行系统通过安装在银行的营业厅、取款机处或者银行柜台以及银行门口等区域的各大品牌的终端监控摄像头,视频监控智能分析在系统后台软件上的视频画面内设置智能分析区域,通过上面的操作实现对银行的7*24小时的智能视频监控分析报警,对进出人员行为进行智能…

智慧港口视频智能分析系统解决方案

港口视频监控智能分析系统是对港口各处的监控回传的视频流利用视频监控智能分析技术进行智能分析处理,视频监控智能分析系统将处理结果然后传送到中心管理服务器或者流媒体服务器进行有效管理。监控中心设立在港口控制中心,主要用于相关工作人员进行远程监控和管理。港口监控…

电力视频监控系统

电力视频监控系统通过对电力工程建设领域利用电力视频监控系统进行违规违章操作检测及其他安全区域监测,电力视频监控系统可以降低或减少安全事故造成的人员伤害和设备损害,提升公司社会形象,杜绝违规行为的发生。视频智能分析系统可以进一步强化安全管理,能够降低电力安全…

2024 最新上海市提取公积金缴纳房租 All In One

2024 最新上海市提取公积金缴纳房租 All In One 提取公积金 图解教程2024 最新上海市提取公积金缴纳房租 All In One最新版(亲测可用 ✅)随申办市民云 Apphttps://apps.apple.com/cn/app/随申办市民云/id732618720 提取公积金 图解教程步骤 图解 备注1. 打开随申办 App / 小程序…

Windows上使用VTune分析PyTorchExtension调用的Cpp程序

概述 最近在实现一个通过PyTorch Extension扩展PyTorch算子的C++算法,需要分析代码的运行瓶颈进行针对性优化。Intel VTune就是一个能从汇编级和源码级分析CPU运行瓶颈的工具。由于不明原因我没在服务器上跑通命令行版的VTune,所以把程序搬到Windows下分析了,因此记录一下Wi…

[LeetCode] 80. Remove Duplicates from Sorted Array II

原来leetcode使用Count也不需要import collections class Solution:def removeDuplicates(self, nums: List[int]) -> int:# len =0if len(nums) == 0:return 0# elsecountList = Counter(nums)countModify = {key:min(value,2) for key,value in countList.items()}ret = […

个人标语

从来不觉得自己比任何人差,讨厌懒惰,骄傲自满与妄自菲薄。

IDER如何生成数据库的ER图?

1.打开 IDEA,并连接到 MySQL数据库这里连接到你的数据库 2.在菜单栏中选择"View"->"Tool windows"->"Database" 3.在"Database" 工具窗口中,展开你想要査看的数据库,并选择"ER Diagrams"。 4.右键单击"ER Dia…

服务器系统瘫痪系统损坏数据恢复

故障服务器数据恢复环境: 一台故障服务器;共有4块146G SAS硬盘组成的RAID5;故障服务器分析检测: 服务器在运行过程中系统瘫痪,重装系统后系统损坏。系统中有数据库、网站程序与网页。 服务器数据恢复过程: 1、对全盘reiserfs树节点之间的关联确定原来的reiserfs分区位置镜…

服务器瘫痪,里面存有mysql数据库表结构

最上层,大多数基于网络服务器的工具或服务都有类似架构。 第二层,大多数MySQL的核心服务,包括查询解析、分析、优化、缓存以及所有的内置函数,所有跨存储引擎的功能都在这一层实现:存储过程、触发器、视图等。 第三层,存储引擎负责MySQL中数据的存储和提取。服务器通过AP…

误操作还原VMware虚拟机数据恢复

故障服务器数据恢复环境: 一台故障物理服务器上迁移到ESXI上的虚拟机。故障服务器检测与分析: 虚拟机的数据恢复迁移的状态,数据全部丢失。还原快照操作与删除数据,将该设备上所有虚拟机关机或迁移到其他ESXI上。 恢复数据之前需要先了解vmfs文件系统的底层结构。vmfs文件系…

存储中NAS卷数据丢失数据恢复

故障服务器数据恢复环境: 一台故障存储,支持SAN和NAS存储协议。服务器故障检测与分析: 存储一个NAS卷中的数据丢失,卷大小为2T,经过检查发现丢失数据的类型为office文档、PDF文件、图片文件(JPG、JPEG、PNG等)。 服务器数据恢复过程: 1、准备好备份服务器,将备份服务器…

系统误操作删除数据恢复

故障服务器环境故障: 一台有文件系统的故障服务器,误操作删了服务器上的数据。服务器数据恢复过程: 1、对故障服务器所有硬盘进行扇区级镜像备份。 2、根据文件系统结构和元信息分析文件系统盘序、使用盘数和校验盘个数等信息。 3、全盘扫描节点入口。 4、扫描所有硬盘的底层…

服务器意外断电导致linux数据目录项数据丢失数据恢复

故障服务器数据恢复环境:​ 一台故障列服务器;做的是linux操作系统。服务器故障检测与分析:​ 因机房在运行中,意外断电导致服务器文件丢失。 服务器数据恢复过程:​ 1、将linux服务器连接到数据恢复服务器,以只读模式进行服务器数据备份,所有的数据恢复操作都在备份上进…

IBM服务器硬盘离线数据恢复

服务器数据恢复故障描述: IBM X3850服务器,服务器挂载了5块73G SAS硬盘组成raid5磁盘阵列。2块硬盘离线,RAID崩溃。 服务器存储有oracle数据库,数据恢复+操作系统复原。服务器磁盘阵列数据恢复流程: 1、关闭服务器做数据恢复,服务器关闭状态保护故障服务器原始状态。 2、…

关于家居强电电路模拟程序3和4总结

前言:对于家居强电电路的3和4总结来说,考察了正则表达式,类的运用,程序与设计的基础使用,ArristList 类的使用等等知识点。相对于家居强电电路3来说,4的难度大得多。在3的基础上,加上了引脚的输出电压,对于输出通过引脚的对应电压。那么要判断更多的东西(比如说引脚是…

我的第三次oop

阅读目录 前言 第四次PTA 第五次PTA 第六次PTA 总结 前言 一:对于java的进一步认识 Java是一种强大、跨平台的编程语言,它以面向对象为核心,拥有自动内存管理、丰富的API和广泛的社区支持。Java的广泛应用领域包括Web开发、移动应用开发、企业级应用以及大数据处理等,其易用…

第三次oop

阅读目录 前言 第四次PTA 第五次PTA 第六次PTA 总结 前言 一:对于java的进一步认识 Java是一种强大、跨平台的编程语言,它以面向对象为核心,拥有自动内存管理、丰富的API和广泛的社区支持。Java的广泛应用领域包括Web开发、移动应用开发、企业级应用以及大数据处理等,其易用…