基于MDK-Keil环境如何把STM32程序直接下载到SRAM运行

news2024/11/18 15:33:27

1. 前言

对于 Cortex-M 内核的微控制器,它们都可以支持在 RAM 中执行程序,有些非 ARM 的微控制器是不支持的。

在内部 SRAM 执行程序,有基于以下几方面的原因:

  • 1、所使用的设备可能具有OTP(One-time Programmable,一次性可编程)ROM区域,还没有确定最终代码之前,还不会把程序编程到芯片中;
  • 2、有些MCU内部内部可能没有Flash,可能会使用到外部的存储器。但是在软件开发阶段可以下载到SRAM进行开发测试;
  • 3、对于特定的测试场合,Flash已经烧录了程序,但是不想擦除。这时可以把测试程序下载到SRAM运行;
  • 4、对于有些Flash被锁定的芯片,可以把代码下载到SRAM,然后进行解锁;
  • 5、Flash写入需要先擦除,所以SRAM的写入速度要比Flash快很多,如果程序很大的话,在开发阶段直接在SRAM运行可以提高效率。

对于程序下载到内部SRAM运行,有多种方法:

  • 1、配置boot引脚,然后下载代码到SRAM,使程序从SRAM启动
  • 2、不修改boot引脚启动模式,借助仿真器,进入仿真模式,然后强制更改 PC SP 指针,从SRAM位置取值开始运行
  • 3、程序下载到内部Flash或者外部的SD卡、SPI Flash等存储设备,然后上电之后把代码搬运到SRAM运行(类似代码的重定位)

下面只介绍前面两种方式。

首先在修改程序在SRAM运行之前,要先准备好一份可以正常在Flash运行的程序。

2. 修改散列文件

散列文件,就是链接脚本,指导链接器如何对程序进行链接的。

我们要让代码在SRAM运行,首先就要修改散列文件,让程序链接地址修改在内部SRAM空间。

在这里插入图片描述

我们打开Keil的配置界面,然后使用我们自己修改的散列文件。

修改后的散列文件内容如下:

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

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

我使用的MCU型号是 STM32F407ZG ,IARM1 的 SRAM 大小有 0x20000 ,即 128KB。我这里分配的代码区域(ER_IROM1)大小是 0x10000(64KB),然后可读可写的数据区域大小是0x10000(64KB),也就是把他们平均分了。

在实际的项目开发中,可根据实际情况改写分配。

3. 修改中断向量表基地址

默认的中断向量表基地址是指向 0x08000000 的地址处的,现在我们已经更改了链接地址,把程序链接到内部SRAM 0x20000000 区域了。

如果发生中断,CPU还是跳到0x08000000开始的地址处执行中断服务函数的话,那么肯定是程序崩溃,因为现在0x08000000处的地址已经没有代码了。

要想正常使用中断的话,就必须修改中断向量表的基地址指向0x20000000地址处。

修改中断向量表基地址,只要修改 SCB->VTOR 寄存器的值就行。

具体代码,在 system_stm3f4xx.c 的 SystemInit 函数就有。如下:

void SystemInit(void)
{
	/* 部分代码省略 ........ */

    /* Configure the Vector Table location add offset address */
    #ifdef VECT_TAB_SRAM
    SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
    #else
    SCB->VTOR = FMC_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
    #endif
}

我们只要定义这个 VECT_TAB_SRAM 宏,就可以修改中断向量表的基地址指向 0x20000000 的地址处了。

这个宏可以直接在Keil的配置界面 C/C++ 选项里面的宏定义那里填写,当然直接在 system_stm3f4xx.c 这个文件前面自己手动写一下也可以。

4. 修改下载算法的配置

为了把代码下载到SRAM中,还需要修改Jlink的下载算法配置,只要其实就是更改下载的地址改为 SRAM 的地址。

在这里插入图片描述

对于上面的配置简单解释如下:

  • 1、由于是下载到SRAM,SRAM写入是不需要擦除的,所以勾选 DO not Erase 即可
  • 2、“Programming Algorithm”一栏的配置,由于没有内置的SRAM下载算法,所以下载算法选择的还是原来的Flash下载算法。但是下面的起始地址和大小需要更改,就改为我们在散列文件定义代码区域的起始地址和大小。
  • 2、“RAM for Algorithm”一栏是指“编程算法”(Programming Algorithm)可使用的 RAM 空间,下载程序到 FLASH 时运行的编程算法需要使用 RAM 空间,在默认配置中它的首地址为 0x20000000,即内部 SRAM 的首地址。但是现在我们修改了0x20000000开始处存放的是代码,所以这里的起始地址要修改了散列文件设置的 RW 区域的起始地址,即 0x20010000 。然后大小默认不用改。

5. 修改boot启动模式

配置到这里,其实我们这时如果更改Boot的启动引脚,配置为内部SRAM启动,然后点击下载按钮,程序就可以正常跑了的。

在这里插入图片描述

但是如果不修改boot启动模式,然后从SRAM启动的话,也可以借助仿真器配置,进入仿真调试模式,然后通过仿真器配置强制 PC SP 指针从 0x20000000 开始处取值,这样也能让程序正常从SRAM运行。

6. 通过仿真器配置修改 PC SP 的值

修改boot模式的目的,其实就是让MCU上电之后,可以从正确的地址处获取到 PC SP 指针的初始值,这样代码才可以正常开始运行。

让 PC SP 获取到正确的值,有两种方式:

  • 修改Boot启动模式,让程序从内部SRAM启动
  • 不修改启动模式,然后通过仿真器配置,进入仿真模式,强制修改 PC SP 的值。

下面介绍下怎么通过仿真器配置,让代码在SRAM运行。

首先我们自己编写一份 .ini 的调试配置文件,强制 PC SP 指针的地址值。内容如下:

/***********************************************************/
/* Debug_RAM.ini: Initialization File for Debugging from Internal RAM */
/******************************************************/
/* This file is part of the uVision/ARM development tools. */
/* Copyright (c) 2005-2014 Keil Software. All rights reserved.*/
/* This software may only be used under the terms of a valid, current */
/* end user licence from KEIL for a compatible version of KEIL software */
/*development tools. Nothing else gives you the right to use this software ?*/
/***************************************************/

 FUNC void Setup (void) {
 SP = _RDWORD(0x20000000); // 设置栈指针 SP,把 0x20000000 地址中的内容赋值到 SP。
 PC = _RDWORD(0x20000004); // 设置程序指针 PC,把 0x20000004 地址中的内容赋值到 PC。
 // XPSR = 0x01000000; // 设置状态寄存器指针 xPSR
 _WDWORD(0xE000ED08, 0x20000000); // Setup Vector Table Offset Register
 }

 LOAD %L INCREMENTAL // 下载 axf 文件到 RAM
 Setup(); //调用上面定义的 setup 函数设置运行环境

 g, main //跳转到 main 函数

然后配置Keil的选项,如下:

在这里插入图片描述

这样,通过这种方式,不需要修改boot引脚的启动模式,点击 debug 调式按钮,也一样可以正常在SRAM运行。

缺点就是下载程序必须是点击进入调试界面,不能通过下载程序的按钮下载程序。因为这种方式是通过仿真器的配置强制设置 PC SP 指向正确的地址的。

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

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

相关文章

《CPU设计实战》第四章lab3记录找bug

修bug之路 1. debug_wb_pc 一个信号一个信号找下去&#xff0c;发现ID_stage.v中load_op未赋值 assign load_op inst_lw; 代码解释 module decoder_5_32(input [ 4:0] in,output [31:0] out ); //这个循环被命名为 gen_for_dec_5_32。 genvar i; generate for (i0; i<…

c++中的动态内存管理

目录 1.内存分布 2.c语言动态内存管理 3.c动态内存管理 4.operator new 与operator delete 函数 5.定位new 6.malloc/free 与 new/delete 的区别 1.内存分布 首先我们需要了解一下数据在内存中的分布&#xff0c;请看以下代码&#xff1a; int globalVar 1; static in…

Day 04 python学习笔记

Python数据容器 元组 元组的声明 变量名称&#xff08;元素1&#xff0c;元素2&#xff0c;元素3&#xff0c;元素4…….&#xff09; &#xff08;元素类型可以不同&#xff09; eg: tuple_01 ("hello", 1, 2,-20,[11,22,33]) print(type(tuple_01))结果&#x…

基于Java的4S店汽车商城系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

C++17中头文件filesystem的使用

C17引入了std::filesystem库(文件系统库, filesystem library)&#xff0c;相关类及函数的声明在头文件filesystem中&#xff0c;命名空间为std::filesystem。 1.path类&#xff1a;文件路径相关操作&#xff0c;如指定的路径是否存在等&#xff0c;其介绍参见&#xff1a;http…

STM32复习笔记(四):看门狗

目录 &#xff08;一&#xff09;简介 &#xff08;二&#xff09;IWDG IWDG的CUBEMX工程配置 IWDG相关函数&#xff08;非常少&#xff0c;所以直接贴上来&#xff09;&#xff1a; &#xff08;三&#xff09;WWDG &#xff08;一&#xff09;简介 看门狗分为独立看门…

【Java】微服务——Nacos注册中心

目录 1.Nacos快速入门1.1.服务注册到nacos1&#xff09;引入依赖2&#xff09;配置nacos地址3&#xff09;重启 2.服务分级存储模型2.1.给user-service配置集群2.2.同集群优先的负载均衡 3.权重配置4.环境隔离4.1.创建namespace4.2.给微服务配置namespace 5.Nacos与Eureka的区别…

[C++随想录] 优先级队列的模拟实现

优先级队列的模拟实现 底层结构初始化向下调整 && 向上调整push && poptop && empty && size源码 底层结构 namespace muyu {template <class T, class Continer std::vector<T>, class Compare less<T> >class priority_…

C#停车场管理系统

目录 一、绪论1.1内容简介及意义1.2开发工具及技术介绍 二、总体设计2.1系统总体架构2.2登录模块总体设计2.3主界面模块总体设计2.4停车证管理模块总体设计2.5停车位管理模块总体设计2.6员工管理模块总体设计2.7其他模块总体设计 三、详细设计3.1登录模块设计3.2主界面模块设计…

力扣:119. 杨辉三角 II(Python3)

题目&#xff1a; 给定一个非负索引 rowIndex&#xff0c;返回「杨辉三角」的第 rowIndex 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;力扣&#xff08;LeetCode&#xff09…

【Linux】ping命令详解

目录 一、ping概述 二、Ping用法 三、ping参数详解 四、使用 五、Wireshark抓取ICMP请求应答消息 一、ping概述 ping 命令用于测试与目标主机之间的连接。它向目标主机发送一个ICMP&#xff08;Internet Control Message Protocol&#xff09;Internet控制报文协议回显请求…

fetch前后端通信

fetch 前后端通信&#xff1a;ajax。 4步走&#xff1a; let xhrnew XMLHttpRequest() xhr.open(get,http://xxx) xhr.onreadystatechange xhr.send() 常用库&#xff1a; jQuery -> 回调地狱 axios fetch&#xff1a;网络获取资源 与Ajax的不同&#xff1a; 网络故障或请求…

激光雷达中实现F-P标准具高热稳定性的帕尔贴精密温控解决方案

摘要&#xff1a;法布里-珀罗标准具作为一种具有高温度敏感性的精密干涉分光器件&#xff0c;在具体应用中对热稳定性具有很高的要求&#xff0c;如温度波动不能超过0.01℃&#xff0c;为此本文提出了相应的高精度恒温控制解决方案。解决方案具体针对温度控制精度和温度均匀性控…

指针笔试题(带解析版)

题目2&#xff1a; struct MyStruct {int num;char* pcname;short sdate;char cha[2];short sba[4]; }*p; //结构体大小为32字节 //p0x100000 int main() {p 0x100000;printf("%p\n", p 0x1);//p&#xff1a;结构体指针&#xff0c;1下一个结构体指针&#xff0c;…

JVM-满老师

JVM 前言程序计数器&#xff0c;栈&#xff0c;虚拟机栈&#xff1a;本地方法栈&#xff1a;堆&#xff0c;方法区&#xff1a;堆内存溢出方法区运行时常量池 前言 JVM 可以理解的代码就叫做字节码&#xff08;即扩展名为 .class 的文件&#xff09;&#xff0c;它不面向任何特…

最新AI创作系统/AI绘画系统/ChatGPT系统+H5源码+微信公众号版+支持Prompt应用

一、AI创作系统 SparkAi创作系统是基于国外很火的ChatGPT进行开发的AI智能问答系统和AI绘画系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图…

Easyx图形库趣味编程note3,颜色模型

EasyX的文档中&#xff0c;不只有用大写字母的形式可绘制出的颜色&#xff0c;它支持更加缤纷多彩的颜色供我们使用。 RGB颜色模型 相信大家都知道三原色&#xff0c;小时候我们趴在电视机前&#xff0c;就可以很明显的发现电视上的色彩是由红绿蓝三种色彩构成&#xff0c;有这…

javascript: Sorting Algorithms

// Sorting Algorithms int JavaScript https://www.geeksforgeeks.org/sorting-algorithms/ /** * file Sort.js * 1. Bubble Sort冒泡排序法 * param arry * param nszie */ function BubbleSort(arry, nszie) {var i, j, temp;var swapped;for (i 0; i < nszie - 1; i)…

云原生微服务 第六章 Spring Cloud Netflix Eureka集成OpenFeign组件,实现微服务的远程调用、负载均衡

系列文章目录 第一章 Java线程池技术应用 第二章 CountDownLatch和Semaphone的应用 第三章 Spring Cloud 简介 第四章 Spring Cloud Netflix 之 Eureka 第五章 Spring Cloud Netflix 之 Ribbon 第六章 Spring Cloud 之 OpenFeign 文章目录 系列文章目录前言1、OpenFeign的实现…

httpserver 下载服务器demo 以及libevent版本的 httpserver

实现效果如下&#xff1a; 图片可以直接显示 cpp h 这些可以直接显示 其他的 则是提示是否要下载 单线程 还有bug 代码如下 先放上来 #include "httpserver.h" #include "stdio.h" #include <stdlib.h> #include <arpa/inet.h> #include…