Cortex 您所在的位置:网站首页 gcc库函数 Cortex

Cortex

2024-01-18 15:04| 来源: 网络整理| 查看: 265

本篇文章使用的芯片为 LPC1768, 对于内核为 Cortex-M3 的其他芯片, 也可参考, 不同之处在于外围器件的中断, 使用GCC编译器 GNU Arm Embedded Toolchain

基础语法 符号(Symbol)

形如下面以冒号结尾的符号被称为标签(label), 表示符号出现位置的地址

__StackLimit: .space Stack_Size .size __StackLimit, . - __StackLimit

. 是一个特殊的符号, 表示当前位置的地址

符号的值通常为 32 bits, 全局符号可用于链接器和调试器

汇编指令(Directive)

所有的汇编指令均以 . 开头, 其余部分通常是小写字母

启动代码 建立栈

本节所用到的汇编指令

指令格式描述.equ symbol, expression设置 symbol 的值为 expression.global symbol使得 symbol 对链接器(ld) 可见.space size , fill使用 fill 填充 size 字节的空间, 可以省略 fill(默认为 0)

栈用于函数调用过程中保存局部变量

.section ".stack", "w" .align 3 #ifdef __STACK_SIZE .equ Stack_Size, __STACK_SIZE #else .equ Stack_Size, 0x00000400 #endif .global __StackTop .global __StackLimit __StackLimit: .space Stack_Size .size __StackLimit, . - __StackLimit __StackTop: .size __StackTop, . - __StackTop 建立堆

堆用于 malloc 函数动态分配内存

.section ".heap", "w" .align 3 #ifdef __HEAP_SIZE .equ Heap_Size, __HEAP_SIZE #else .equ Heap_Size, 0x00000C00 #endif .global __HeapBase .global __HeapLimit __HeapBase: .if Heap_Size .space Heap_Size .endif .size __HeapBase, . - __HeapBase __HeapLimit: .size __HeapLimit, . - __HeapLimit 中断向量表

在链接时, 中断向量表需要放在代码区的最前面

.long 指令用于分配 4 字节的内存, 并填充值

.section ".interrupt_vector" .align 2 .global __interrupt_vector .type __interrupt_vector, %object __interrupt_vector: .long __StackTop /* Top of Stack */ .long Reset_Handler /* Reset Handler */ .long NMI_Handler /* NMI Handler */ .long HardFault_Handler /* Hard Fault Handler */ .long MemManage_Handler /* MPU Fault Handler */ .long BusFault_Handler /* Bus Fault Handler */ .long UsageFault_Handler /* Usage Fault Handler */ .long 0 /* Reserved */ .long 0 /* Reserved */ .long 0 /* Reserved */ .long 0 /* Reserved */ .long SVC_Handler /* SVCall Handler */ .long DebugMon_Handler /* Debug Monitor Handler */ .long 0 /* Reserved */ .long PendSV_Handler /* PendSV Handler */ .long SysTick_Handler /* SysTick Handler */ /* External Interrupts */ .long WDT_IRQHandler /* 16: Watchdog Timer */ .long TIMER0_IRQHandler /* 17: Timer0 */ .long TIMER1_IRQHandler /* 18: Timer1 */ .long TIMER2_IRQHandler /* 19: Timer2 */ .long TIMER3_IRQHandler /* 20: Timer3 */ .long UART0_IRQHandler /* 21: UART0 */ .long UART1_IRQHandler /* 22: UART1 */ .long UART2_IRQHandler /* 23: UART2 */ .long UART3_IRQHandler /* 24: UART3 */ .long PWM1_IRQHandler /* 25: PWM1 */ .long I2C0_IRQHandler /* 26: I2C0 */ .long I2C1_IRQHandler /* 27: I2C1 */ .long I2C2_IRQHandler /* 28: I2C2 */ .long SPI_IRQHandler /* 29: SPI */ .long SSP0_IRQHandler /* 30: SSP0 */ .long SSP1_IRQHandler /* 31: SSP1 */ .long PLL0_IRQHandler /* 32: PLL0 Lock (Main PLL) */ .long RTC_IRQHandler /* 33: Real Time Clock */ .long EINT0_IRQHandler /* 34: External Interrupt 0 */ .long EINT1_IRQHandler /* 35: External Interrupt 1 */ .long EINT2_IRQHandler /* 36: External Interrupt 2 */ .long EINT3_IRQHandler /* 37: External Interrupt 3 */ .long ADC_IRQHandler /* 38: A/D Converter */ .long BOD_IRQHandler /* 39: Brown-Out Detect */ .long USB_IRQHandler /* 40: USB */ .long CAN_IRQHandler /* 41: CAN */ .long DMA_IRQHandler /* 42: General Purpose DMA */ .long I2S_IRQHandler /* 43: I2S */ .long ENET_IRQHandler /* 44: Ethernet */ .long RIT_IRQHandler /* 45: Repetitive Interrupt Timer */ .long MCPWM_IRQHandler /* 46: Motor Control PWM */ .long QEI_IRQHandler /* 47: Quadrature Encoder Interface */ .long PLL1_IRQHandler /* 48: PLL1 Lock (USB PLL) */ .size __interrupt_vector, . - __interrupt_vector

所有以 _IRQHandler 结尾的符号在下面的代码中被定义, 表示中断函数的起始地址

.macro 是汇编指令中的宏定义

.macro IRQ handler .align 1 .thumb_func .weak \handler .type \handler, %function \handler: b . .size \handler, . - \handler .endm IRQ NMI_Handler IRQ HardFault_Handler IRQ MemManage_Handler IRQ BusFault_Handler IRQ UsageFault_Handler IRQ SVC_Handler IRQ DebugMon_Handler IRQ PendSV_Handler IRQ SysTick_Handler IRQ WDT_IRQHandler IRQ TIMER0_IRQHandler IRQ TIMER1_IRQHandler IRQ TIMER2_IRQHandler IRQ TIMER3_IRQHandler IRQ UART0_IRQHandler IRQ UART1_IRQHandler IRQ UART2_IRQHandler IRQ UART3_IRQHandler IRQ PWM1_IRQHandler IRQ I2C0_IRQHandler IRQ I2C1_IRQHandler IRQ I2C2_IRQHandler IRQ SPI_IRQHandler IRQ SSP0_IRQHandler IRQ SSP1_IRQHandler IRQ PLL0_IRQHandler IRQ RTC_IRQHandler IRQ EINT0_IRQHandler IRQ EINT1_IRQHandler IRQ EINT2_IRQHandler IRQ EINT3_IRQHandler IRQ ADC_IRQHandler IRQ BOD_IRQHandler IRQ USB_IRQHandler IRQ CAN_IRQHandler IRQ DMA_IRQHandler IRQ I2S_IRQHandler IRQ ENET_IRQHandler IRQ RIT_IRQHandler IRQ MCPWM_IRQHandler IRQ QEI_IRQHandler IRQ PLL1_IRQHandler

这里仅仅是定义了一系列默认的中断函数, 由于使用了 .weak 声明, 可以在 C 代码中定义相同的函数进行覆盖

默认的中断函数被实现为 b ., 即死循环

系统复位

芯片上电后首先执行系统复位(Reset_Handler)

系统复位需要处理全局变量的值, 对于有初始值的全局变量, 需要从 Flash 拷贝初始值到 RAM, 对于没有初始值的全局变量, 需要把值清零

.text .thumb .thumb_func .align 2 .global Reset_Handler .type Reset_Handler, %function Reset_Handler: ldr r1, = __etext ldr r2, = __data_start__ ldr r3, = __data_end__ FLASH2RAM: cmp r2, r3 ittt lt ldrlt r0, [r1], #4 strlt r0, [r2], #4 blt FLASH2RAM ldr r1, = __bss_start__ ldr r2, = __bss_end__ movs r0, 0 CLEAR_BSS: cmp r1, r2 itt lt strlt r0, [r1], #4 blt CLEAR_BSS bl SystemInit bl _start .pool .size Reset_Handler, . - Reset_Handler

__etext, __data_start__, __data_end__ 等符号是在链接脚本中定义的, 因为代码段和数据段的地址是在链接阶段才确定下来

_start 是标准库中的符号, 它会调用 main 函数, 当然也可以像下面这样, 跳过 _start 直接调用 main 函数

bl SystemInit bl main .pool .size Reset_Handler, . - Reset_Handler


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有