iar stm32_欲练此功必先自宫之STM32汇编启动,放慢是为了更好的前行

2023-10-21 08:40

本文主要是介绍iar stm32_欲练此功必先自宫之STM32汇编启动,放慢是为了更好的前行,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在上一篇文章《假美猴王之三极管与MOS管,谁是悟空,谁又是六耳猕猴》中我们讲到了真假美猴王之三极管与MOS管的区别。今天来探讨一下武功秘籍的修炼,据说秘籍第一页就写道:欲练此功,必先自宫。意思就是说明一个道理,任何人要想成仙成佛,练就一身超神的本领,那么是要付出的代价并做好准备工作的。

而今天我们的要探讨的主角STM32处理器也不例外,别看它运行起来玉树临风,似乎无所不能,启动初期也要先苦练一番本领才行。那么这一部分都做了哪些工作呢?

STM32这款处理器使用的是的ARM的Cortex-M3内核,Cortex-M3内核有个特点就是在地址0x00000000存放的是全局的栈地址。紧接着从地址0x00000004执行(因为STM32是32位的处理器,一条指令正好对应4个字节),也就是从这个地址取出中断向量表的地址,跳转执行中断处理函数。

b3f6990a32b785204399ac1ed4095d7e.png

M3内核复位后程序执行过程

在前面文章《敢问路在何方,STM32迈出的第一步,却注定了它非凡的一生》中我们有介绍通过BOOT0和BOOT1引脚高低电平的不同组合,对应者三种不同的启动方式,同样也就对应着三种地址的映射: Flash system memory就是将0x00000000映射到了0x08000000;System memory就是将0x00000000映射到了0x1FFF0000;SRAM就是将0x00000000映射到了0x20000000。选择了哪种启动方式就会把0地址映射到对应物理地址。同样该区的物理地址最前面存放的就是栈地址和中断向量表。

        DATA__vector_table        DCD     sfe(CSTACK)        DCD     Reset_Handler             ; Reset Handler        DCD     NMI_Handler               ; NMI Handler        DCD     HardFault_Handler         ; Hard Fault Handler        DCD     0                         ; Reserved        DCD     0                         ; Reserved        DCD     0                         ; Reserved        DCD     0                         ; Reserved        DCD     0                         ; Reserved        DCD     0                         ; Reserved        DCD     0                         ; Reserved        DCD     SVC_Handler               ; SVCall Handler        DCD     DebugMon_Handler          ; Debug Monitor Handler        DCD     0                         ; Reserved        DCD     PendSV_Handler            ; PendSV Handler        DCD     SysTick_Handler           ; SysTick Handler         ; External Interrupts                DCD     WWDG_IRQHandler                ; Window Watchdog                DCD     PVD_IRQHandler                 ; PVD through EXTI Line detect                DCD     RTC_IRQHandler                 ; RTC through EXTI Line                DCD     FLASH_IRQHandler               ; FLASH                DCD     RCC_CRS_IRQHandler             ; RCC_CRS                DCD     EXTI0_1_IRQHandler             ; EXTI Line 0 and 1                DCD     EXTI2_3_IRQHandler             ; EXTI Line 2 and 3                DCD     EXTI4_15_IRQHandler            ; EXTI Line 4 to 15                DCD     TSC_IRQHandler                 ; TSC                DCD     DMA1_Channel1_IRQHandler       ; DMA1 Channel 1                DCD     DMA1_Channel2_3_IRQHandler     ; DMA1 Channel 2 and Channel 3                DCD     DMA1_Channel4_5_6_7_IRQHandler ; DMA1 Channel 4, Channel 5, Channel 6 and Channel 7                DCD     ADC1_COMP_IRQHandler           ; ADC1, COMP1 and COMP2                 DCD     LPTIM1_IRQHandler              ; LPTIM1                DCD     0                              ; Reserved                DCD     TIM2_IRQHandler                ; TIM2                DCD     0                              ; Reserved                DCD     TIM6_DAC_IRQHandler            ; TIM6 and DAC                DCD     0                              ; Reserved                DCD     0                              ; Reserved                DCD     TIM21_IRQHandler                ; TIM21                DCD     0                              ; Reserved                DCD     TIM22_IRQHandler               ; TIM22                DCD     I2C1_IRQHandler                ; I2C1                DCD     I2C2_IRQHandler                ; I2C2                DCD     SPI1_IRQHandler                ; SPI1                DCD     SPI2_IRQHandler                ; SPI2                DCD     USART1_IRQHandler              ; USART1                DCD     USART2_IRQHandler              ; USART2                DCD     RNG_LPUART1_IRQHandler         ; RNG and LPUART1                DCD     LCD_IRQHandler                 ; LCD                DCD     USB_IRQHandler                 ; USB

而中断处理函数的第一个就是复位中断处理函数Reset_Handler:

        THUMB        PUBWEAK Reset_Handler        SECTION .text:CODE:NOROOT:REORDER(2)Reset_Handler        LDR     R0, =SystemInit        BLX     R0        LDR     R0, =__iar_program_start        BX      R0                PUBWEAK NMI_Handler        SECTION .text:CODE:NOROOT:REORDER(1)

我们看下默认的复位中断处理函数里边都做了什么事情,首先将SystemInit函数的首地址存放到R0寄存器里边,然后跳转到R0寄存器的地址,即去执行IAR本身库文件中的SystemInit函数进行相关初始化。然后将__iar_program_start函数的首地址存放到R0寄存器里边,然后跳转到R0寄存器的地址,即去执行__iar_program_start函数。

那么__iar_program_start这个函数在哪里呢?没错,你在整个汇编文件中都没有找到!这个文件在IAR的安装目录里边,具体的路径是C:Program Files (x86)IAR SystemsEmbedded Workbench 7.2armsrclibhumb,我是将IAR装在C:Program Files (x86)目录下的,大家根据自己情况查找。在thumb目录下有个cstartup_M.s文件,文件代码如下:

        MODULE  ?cstartup        PUBLIC  __iar_program_start        EXTERN  __cmain        EXTERN  __vector_table        EXTWEAK __iar_init_core        EXTWEAK __iar_init_vfp        SECTION .text:CODE:REORDER(1)        THUMB__iar_program_start:        FUNCALL __iar_program_start, __iar_init_core        BL      __iar_init_core        FUNCALL __iar_program_start, __iar_init_vfp        BL      __iar_init_vfp        FUNCALL __iar_program_start, __cmain        BL      __cmain        REQUIRE __vector_table        END

__iar_program_start中分别调用了__iar_init_core,__iar_init_vfp和__cmain三个函数。前面两个函数式弱函数,在工程中没有定义,大家可以根据实际情况重写这两个函数。最后一个函数__cmain也在同目录下的cmain.s中定义:

        THUMB__cmain:?main:; Initialize segments.; __segment_init and __low_level_init are assumed to use the same; instruction set and to be reachable by BL from the ICODE segment; (it is safest to link them in segment ICODE).          FUNCALL __cmain, __low_level_init        bl      __low_level_init        cmp     r0,#0        beq     ?l1          FUNCALL __cmain, __iar_data_init3        bl      __iar_data_init3?l1:        REQUIRE ?l3        SECTION .text:CODE:NOROOT(2)        PUBLIC  _main        PUBLIC _call_main        THUMB__iar_init$$done:                 ; Copy initialization is done?l3:_call_main:        MOVS    r0,#0             ;  No parameters          FUNCALL __cmain, __iar_argc_argv        BL      __iar_argc_argv   ; Maybe setup command line          FUNCALL __cmain, main        BL      main_main:          FUNCALL __cmain, exit        BL      exit        END

其实最后就是进行了一个底层的初始化,然后就永久的跳转到main.c文件中的main函数了。至此,汇编部分代码结束,开始执行大家在main中编写的代码。

喜欢就在文末点个“关注”或者 “转发”,这样可以让更多的人学习哦!!!

有问题评论一起交流学习进步! 感谢!

更多优质文章请点击我的头像,选择“文章”标签!

这篇关于iar stm32_欲练此功必先自宫之STM32汇编启动,放慢是为了更好的前行的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/253243

相关文章

SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法

《SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法》本文主要介绍了SpringBoot项目启动错误:找不到或无法加载主类的几种解决方法,具有一定的参考价值,感兴趣的可以了解一下... 目录方法1:更改IDE配置方法2:在Eclipse中清理项目方法3:使用Maven命令行在开发Sprin

Nginx启动失败:端口80被占用问题的解决方案

《Nginx启动失败:端口80被占用问题的解决方案》在Linux服务器上部署Nginx时,可能会遇到Nginx启动失败的情况,尤其是错误提示bind()to0.0.0.0:80failed,这种问题通... 目录引言问题描述问题分析解决方案1. 检查占用端口 80 的进程使用 netstat 命令使用 ss

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干

Windows设置nginx启动端口的方法

《Windows设置nginx启动端口的方法》在服务器配置与开发过程中,nginx作为一款高效的HTTP和反向代理服务器,被广泛应用,而在Windows系统中,合理设置nginx的启动端口,是确保其正... 目录一、为什么要设置 nginx 启动端口二、设置步骤三、常见问题及解决一、为什么要设置 nginx

springboot启动流程过程

《springboot启动流程过程》SpringBoot简化了Spring框架的使用,通过创建`SpringApplication`对象,判断应用类型并设置初始化器和监听器,在`run`方法中,读取配... 目录springboot启动流程springboot程序启动入口1.创建SpringApplicat

树莓派启动python的实现方法

《树莓派启动python的实现方法》本文主要介绍了树莓派启动python的实现方法,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录一、RASPBerry系统设置二、使用sandroidsh连接上开发板Raspberry Pi三、运

SpringBoot项目启动后自动加载系统配置的多种实现方式

《SpringBoot项目启动后自动加载系统配置的多种实现方式》:本文主要介绍SpringBoot项目启动后自动加载系统配置的多种实现方式,并通过代码示例讲解的非常详细,对大家的学习或工作有一定的... 目录1. 使用 CommandLineRunner实现方式:2. 使用 ApplicationRunne

Java汇编源码如何查看环境搭建

《Java汇编源码如何查看环境搭建》:本文主要介绍如何在IntelliJIDEA开发环境中搭建字节码和汇编环境,以便更好地进行代码调优和JVM学习,首先,介绍了如何配置IntelliJIDEA以方... 目录一、简介二、在IDEA开发环境中搭建汇编环境2.1 在IDEA中搭建字节码查看环境2.1.1 搭建步

bat脚本启动git bash窗口,并执行命令方式

《bat脚本启动gitbash窗口,并执行命令方式》本文介绍了如何在Windows服务器上使用cmd启动jar包时出现乱码的问题,并提供了解决方法——使用GitBash窗口启动并设置编码,通过编写s... 目录一、简介二、使用说明2.1 start.BAT脚本2.2 参数说明2.3 效果总结一、简介某些情

MySQL数据库宕机,启动不起来,教你一招搞定!

作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG、Mongodb数据库运维(如安装迁移,性能优化、故障应急处理等)公众号:老苏畅谈运维欢迎关注本人公众号,更多精彩与您分享。 MySQL数据库宕机,数据页损坏问题,启动不起来,该如何排查和解决,本文将为你说明具体的排查过程。 查看MySQL error日志 查看 MySQL error日志,排查哪个表(表空间