STM32MP135平台基于HAL库创建Bare Metal裸机工程并从SD卡启动

这篇具有很好参考价值的文章主要介绍了STM32MP135平台基于HAL库创建Bare Metal裸机工程并从SD卡启动。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

STM32MP135平台基于HAL库创建Bare Metal裸机工程并从SD卡启动

1.引言

首先引用ST官方的介绍:

STM32MP135微处理器 (MPU) 基于单Arm® Cortex®-A7内核,运行频率可达1GHz。STM32MP13 MPU专门面向入门级Linux、裸机或RTOS系统设计,并已预先集成Microsoft Azure RTOS。”

STM32MP135处理器(以下简称MP135)本是一块MPU,主频可达1GHz(我看到的手册及时钟配置下最高实际为900MHz),本该运行Linux内核,这次官方支持了Bare Metal,也就是裸机HAL库,可以实现利用MPU丰富外设资源及实际需求的同时,进一步提升程序运行的实时性,当作一块资源丰富的大单片机用。

这次使用手上的ST官方的MP135DK开发板,使用最新的V1.0.0 HAL库,创建基于MP135的裸机工程,并将程序烧录至SD卡运行。

本文参考:【STM32MP13x直播回顾】 直播答疑汇总 (stmicroelectronics.cn)
stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

2.提前了解
  • MP135启动开关决定了上电时的启动方式

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • MP135是一块标准的MPU,没有内部Flash,只有内部的SYSRAM(128KB)

  • 前面两项共同决定了MP135的启动流程与运行流程,实际情况如下

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 综上所述,总结一下MP135的裸机玩法:

    • 调试时直接在CubeIDE中进入调试模式,程序会自动被写进内部的SYSRAM中运行,并且可以单步调试。如果程序大小超过了SYSRAM的128KB,则需要先在SYSRAM中运行DDR初始化程序,并在用户程序调试时,将程序加载进DDR中,实现用户程序的调试运行,同样支持单步调试。
    • 以上是调试模式的方法,但实际情况通常为从外部Flash或SD卡加载程序运行,这里以SD卡为例,结合上图可知:上电时MP135拨码为外部SD卡启动->加载ROM Code->从SD卡加载第一段程序FSBLA->复制用户程序到DDR->跳转至DDR运行用户程序。
  • 最后,明确我们接下来要做的工作:

    • 使用CubeIDE或CubeMX建立基于Bare Metal的MP135工程
    • 编写代码并调试用户程序
    • 在DDR中运行并调试用户程序
    • 烧写程序至SD卡,并从SD加载用户程序运行
3.使用CubeIDE或CubeMX建立基于Bare Metal的MP135工程
  • 确保已安装或更新CubeIDE至最新,目前最新版本为1.14.1

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 按照常规方法新建STM32工程

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 找到正确的MPU型号

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 为工程命名并指定保存位置,注意工程类型要选择BareMetal裸机工程,点击Finish完成创建

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 至此,完成了使用CubeIDE或CubeMX建立基于Bare Metal的MP135工程

4.编写代码并调试用户程序

stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 按照常规方法配置时钟树(System Core -> RCC),在这里配置为外部晶振,也可忽略不配置

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 按照常规方法配置调试引脚为SWD(Trace and Debug -> DEBUG)

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 这里以点亮板载的一颗蓝色LED为例,实现LED闪烁,作为用户程序的功能,由电路图可知引脚为PA14

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 完成后生成代码,工程结构如下

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 作者在图形配置界面为PA14创建了别名"LED",但在生成的代码中并没有看到相关的#define,因此暂时手动控制led闪烁

  • 在main.c中手动完善GPIO初始化代码

    /**
     * @brief GPIO Initialization Function
     * @param None
     * @retval None
     */
    static void MX_GPIO_Init(void) {
    	/* USER CODE BEGIN MX_GPIO_Init_1 */
    	GPIO_InitTypeDef gpio_init_structure;
    	/* USER CODE END MX_GPIO_Init_1 */
    
    	/* GPIO Ports Clock Enable */
    	__HAL_RCC_GPIOH_CLK_ENABLE();
    
    	/* USER CODE BEGIN MX_GPIO_Init_2 */
    	__HAL_RCC_GPIOA_CLK_ENABLE();
    	gpio_init_structure.Pin = GPIO_PIN_14;
    	gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;
    	gpio_init_structure.Pull = GPIO_PULLUP;
    	gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    	HAL_GPIO_Init(GPIOA, &gpio_init_structure);
    	/* USER CODE END MX_GPIO_Init_2 */
    }
    
  • 完善main函数中的led闪烁代码

    /**
     * @brief  The application entry point.
     * @retval int
     */
    int main(void) {
    	/* USER CODE BEGIN 1 */
    
    	/* USER CODE END 1 */
    
    	/* MCU Configuration--------------------------------------------------------*/
    
    	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    	HAL_Init();
    
    	/* USER CODE BEGIN Init */
    
    	/* USER CODE END Init */
    
    	/* Configure the system clock */
    	SystemClock_Config();
    
    	/* USER CODE BEGIN SysInit */
    
    	/* USER CODE END SysInit */
    
    	/* Initialize all configured peripherals */
    	MX_GPIO_Init();
    	/* USER CODE BEGIN 2 */
    
    	/* USER CODE END 2 */
    
    	/* Infinite loop */
    	/* USER CODE BEGIN WHILE */
    	while (1) {
    		HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_14);
    		HAL_Delay(500);
    		/* USER CODE END WHILE */
    
    		/* USER CODE BEGIN 3 */
    	}
    	/* USER CODE END 3 */
    }
    
  • 此时编译工程,出现一个警告,暂忽略。将板子拨码开关拨至stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机状态,连接至计算机

  • 点击调试按钮,确认待调试的elf程序及调试器接口,点击OK进入调试模式

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 此时进入单步调试模式,程序运行在SYSRAM中

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 点击全速运行,观察LED效果

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 至此,完成了基于STM32MP135裸机代码的编写并在SYSRAM中调试用户程序

5.在DDR中运行并调试用户程序
  • 刚才我们实现了在SYSRAM中运行并调试用户程序,若程序超过了SYSRAM的128KB大小,就需要将程序运行在DDR中,这就需要在我们的用户程序之前先实现DDR的初始化,再将用户程序运行在DDR中

  • 导入HAL库中的实例工程"DDR_Init"

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 编译"DDR_Init"工程并进入调试,点击全速运行后,板载蓝色LED开始闪烁,说明DDR初始化完成。

  • 此时退出调试模式,程序终止,蓝色LED停止闪烁,DDR仍然正常

  • 保持板子不断电,继续完成接下来的操作

  • 在完成DDR的初始化操作之后,我们要将刚才的用户程序运行在DDR上,需要对原工程进行一些修改:

    • 去掉不必要的初始化,如系统时钟初始化,用户程序内如果对系统时钟初始化将会导致DDR功能异常,这里ST的诸多示例工程中用一个宏定义"USE_DDR"决定是否在用户程序中执行系统时钟初始化操作

      /**
       * @brief System Clock Configuration
       * @retval None
       */
      void SystemClock_Config(void) {
      #ifndef USE_DDR
      	RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };
      
      	if (HAL_RCC_DeInit() != HAL_OK) {
      		Error_Handler();
      	}
      
      	/** Initializes the RCC Oscillators according to the specified parameters
      	 * in the RCC_OscInitTypeDef structure.
      	 */
      	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
      	RCC_OscInitStruct.HSIState = RCC_HSI_ON;
      	RCC_OscInitStruct.HSICalibrationValue = 16;
      	RCC_OscInitStruct.HSIDivValue = RCC_HSI_DIV1;
      	RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
      	RCC_OscInitStruct.PLL2.PLLState = RCC_PLL_NONE;
      	RCC_OscInitStruct.PLL3.PLLState = RCC_PLL_NONE;
      	RCC_OscInitStruct.PLL4.PLLState = RCC_PLL_NONE;
      	if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
      		Error_Handler();
      	}
      #endif
      }
      
    • 在工程属性中配置传递给编译器的宏定义"USE_DDR"

      stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

    • 工程属性中修改链接文件为stm32mp13xx_a7_ddr.ld,该文件可从其他示例工程中获取,并拷贝至自建工程下,与原链接文件同目录,实现调试时程序加载至DDR中运行。

      stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

    • 确保stm32mp13xx_a7_ddr.ld中的REGION_ALIAS定义到DDR区域

      stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

    • 修改Debug配置,删掉调试目标程序Startup中的monitor reset,防止DDR跟着复位
      stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 重新编译程序

  • 进入调试模式,此时发现用户程序的断点停留在0xc000开头的DDR处

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 点击全速运行,发现用户程序在DDR中可以正常运行

  • 至此,完成在DDR中运行并调试用户程序

6.烧写程序至SD卡,并从SD加载用户程序运行
  • 根据前面的介绍,若要实现用户程序从SD卡加载至MP135上运行,我们需要准备以下两个程序,并将其写入SD卡中:

    • 初级初始化程序FSBL,被芯片的Rom Code加载,实现DDR的初始化与用户程序的拷贝与加载
    • 用户程序,被初始化程序FSB拷贝至DDR并加载
  • 除此之外还需准备为烧录工具引导使用的两个文件,HAL库中已提供:

    STM32PRGFW_UTIL_MP13xx_CP_Serial_Boot.stm32

    SD_Ext_Loader.bin

  • 还有烧录工具使用到的分区表文件

    FlashLayout_OpenBL_ExtLoaderSDMMC_SerialBoot.tsv

  • FSBLA程序和用户程序需要添加header信息。FSBLA工程选项中在编译后已默认调用post脚本添加了header信息,这里保持默认,准备好编译后生成的FSBLA_Sdmmc1_A7_Signed.bin

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 用户程序的工程选项中,同样地在Build Step中添加编译后执行的命令,其中需要引用需要的postbuild_STM32MP13.sh,根据实际位置完善好以下命令:

    “(path_to_STM32CubeMP13 Package)/Utilities/ImageHeader/postbuild_STM32MP13.sh"
    g n u t o o l s f o r s t m 3 2 c o m p i l e r p a t h " " {gnu_tools_for_stm32_compiler_path}" " gnutoolsforstm32compilerpath""{BuildArtifactFileBaseName}”

    作者的实际命令为:

    “C:\Users\Administrator\STM32Cube\Repository\STM32Cube_FW_MP13_V1.0.0\Utilities\ImageHeader\postbuild_STM32MP13.sh” “ g n u t o o l s f o r s t m 3 2 c o m p i l e r p a t h " " {gnu_tools_for_stm32_compiler_path}" " gnutoolsforstm32compilerpath""{BuildArtifactFileBaseName}”

​ 如图:

stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 重新编译用户程序,可以看到在编译后生成bin文件后执行了脚本文件,添加了header,生成了stm32文件,一会烧写时使用

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 准备好SD_Ext_Loader.bin和SD_Ext_Loader.bin,HAL库中有提供,使用Everything可以快速搜索到

  • 准备好分区表文件FlashLayout_OpenBL_ExtLoaderSDMMC_SerialBoot.tsv,HAL库中同样有提供

  • 准备好的文件如下:

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 修改分区表文件tsv,使用文本编辑工具打开,根据实际情况修改用户程序文件名

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 启动拨码开关拨至stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机
    ,从USB启动,重新连接至计算机

  • 启动CubeProgrammer,使用串口连接目标设备,在弹出的Open File对话框中选择分区表文件stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 选择好固件所在路径,点击Download烧写固件到SD卡

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 等待烧写完成

    stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机

  • 拨码开关拨至stm32mp135 hal开发,ARM,GCC,嵌入式Linux,stm32,嵌入式硬件,单片机
    ,从SD卡加载,按下复位按键或重新上电,观察运行效果

  • 至此,完成烧写程序至SD卡,并实现从SD加载用户程序运行文章来源地址https://www.toymoban.com/news/detail-827967.html

到了这里,关于STM32MP135平台基于HAL库创建Bare Metal裸机工程并从SD卡启动的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【云原生技术】云计算与网络:裸金属服务器(Bare Metal Server,简称BMS)简介

    【云原生技术】云计算与网络:裸金属服务器(Bare Metal Server,简称BMS)简介 裸金属服务器(Bare Metal Server,简称BMS)是云计算领域的一种服务,提供给客户独占使用的物理服务器。与传统的虚拟化云服务器不同,裸金属服务器为用户提供了对整个物理服务器的直接访问,无

    2024年01月18日
    浏览(45)
  • STM32 HAL库+ESP8266+华为云物联网平台

    文章内容:     STM32 HAL库通过串口发送AT指令完成与ESP8266的控制实现接入华为云物联网平台,并完成基本通信与控制,包括设备属性上报和命令下发解析与响应。     文末获取 “STM32 HAL库+ESP8266+华为云物联网平台keil工程 ”下载的链接。 一、华为云物联网平台 创建 产品

    2024年02月14日
    浏览(60)
  • 正点原子STM32(基于HAL库)5

    STM32F103ZET6 自带了64K 字节的RAM,对一般应用来说,已经足够了,不过在一些对内存要求高的场合,比如做华丽效果的GUI,处理大量数据的应用等,STM32 自带的这些内存就可能不太够用了。好在嵌入式方案提供了扩展芯片RAM 的方法,本章将介绍我们开发板上使用的RAM 拓展方案

    2024年02月08日
    浏览(79)
  • 正点原子STM32(基于HAL库)1

    正点原子B站视频地址:https://www.bilibili.com/video/BV1bv4y1R7dp?p=1vd_source=cc0e43b449de7e8663ca1f89dd5fea7d STM32芯片分类 ST中文社区网:https://www.stmcu.org.cn/ ST官网:https://www.st.com/content/st_com/en.html 了解了STM32 的系列和命名以后,我们再进行STM32 选型就会比较容易了,这里我们只要遵循:由高

    2023年04月23日
    浏览(83)
  • stm32 ADC 精讲(基于HAL库)

    首先ADC是将模拟量信号转化为数字信号,简单来说就是把一些连续信号转化为 010101。 典型的ADC叫做逐次逼近型ADC,接下来我们来分模块讲解上述电路图 上图所示,是一个 电压比较器,将待测电压Vin输入到比较器的正端上去,当正端电压大于负端电压时,在输出端输出1,反之

    2024年02月14日
    浏览(62)
  • STM32 hal库使用笔记之FreeRTOS—任务创建、删除,任务挂起、恢复,任务中断管理

    一、简介 1.FreeRTOS简介     RTOS全称为:Real Time OS,就是实时操作系统,强调的是:实时性。而Free显而易见体现的是其免费性。总的来说这是一个免费的嵌入式实时操作系统。     其特点是:免费开源、可剪裁(独立性强,适应范围广)、简单、优先级/任务不限(但是受到不

    2024年02月04日
    浏览(51)
  • 【STM32】基于HAL库的中断详细学习

    1.中断概述 1.1中断相关概念 1.2 STM32中断系统 2 .HAL库的中断处理 2.1 HAL 库的中断封装 2.2 外部中断处理流程 3.外部中断的HAL库定义 3.1. 外部中断的数据类型 3.2. 外部中断的接口函数 在计算机系统中,处理器常常需要与外部设备进行数据传输。常见的数据传输方式有以下四种:

    2024年02月02日
    浏览(81)
  • 基于STM32CUBEMX,HAL库蓝牙通信

    1.准备工作 蓝牙模块HC-05模块 安卓APP软件 HC-05蓝牙模块支持AT指令。要进入AT指令模式,需要先按住蓝牙模块上的按键,接通电源,当模块上的LED灯进入慢闪后再松开按键,此时已经进入AT指令模式,可以进行AT指令设置1。 常用的AT指令包括: AT+VERSION? 返回HC-05的软件版本号

    2024年02月08日
    浏览(77)
  • 【stm32开发笔记】基于HAL库的STM32F4添加DSP库

    本文分两种方法添加DSP库:1.CubeMX直接配置ioc添加; 2.KEIL内添加; 简述:补齐全部lib库-添加DSP包-使能DSP勾选-添加头文件及魔术棒配置-测试 1.补齐lib库。( 如果使用直接默认添加的库,是不支持FPU的,所以需要补齐后找到所需的lib文件进行替换,在MX的工程管理栏,选择复制所

    2024年02月16日
    浏览(58)
  • STM32基于HAL库和STM32CubeMX的实时操作系统FreeRtOS开发

    1、FreeRTOS RTOS是一类操作系统,µC/OS,FreeRTOS,RTX,RT-Thread 等这些都是RTOS 类的操作系统 FreeRTOS 是众多RTOS 类操作系统中的一种,FreeRTOS 十分的小巧,可以在资源有限的微控制器中运行,FreeRTOS 也不仅仅局限于在微控制器中使用。就单从文件数量上来看FreeRTOS 要比µC/OS 少得多

    2024年02月21日
    浏览(64)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包