ARM Cortex-M33(EFM32PG22)纯汇编操作GPIO触发硬故障求助
解决EFM32PG22(Cortex-M33)纯汇编裸机GPIO操作硬故障的必要初始化步骤
当你在纯汇编裸机代码中直接操作GPIO触发硬故障,而Simplicity Studio初始化后能正常运行,本质是缺少了TrustZone状态切换、时钟使能、寄存器解锁等关键系统初始化步骤。以下是必须手动实现的核心操作:
1. 切换到非安全状态(绕过TrustZone限制)
EFM32PG22的Cortex-M33复位后默认处于安全状态,而多数外设(包括GPIO)默认映射到非安全地址空间,安全状态下直接访问会触发权限故障。需要通过AIRCR寄存器切换到非安全模式:
; 切换到非安全状态(AIRCR寄存器地址:0xE000ED0C) LDR R0, =0xE000ED0C LDR R1, =0x5FA00001 ; 0x5FA是AIRCR解锁密钥,0x01置位NSPE位 STR R1, [R0]
同时需设置非安全模式的主堆栈指针(MSP_NS),避免堆栈操作异常:
; 设置非安全主堆栈指针(需在链接脚本中定义__STACK_TOP_NS地址) LDR R0, =__STACK_TOP_NS MSR MSP_NS, R0
2. 使能GPIO及外设时钟
Silicon Labs MCU的外设默认处于断电状态,未使能时钟时访问寄存器会触发硬故障。以GPIOA为例,需通过CMU时钟模块开启对应端口的时钟:
; 使能GPIOA时钟(CMU基地址:0x400C0000,HFPERCLKEN0寄存器偏移0x30) LDR R0, =0x400C0000 LDR R1, [R0, #0x30] ORR R1, R1, #0x01 ; 置位GPIOA时钟使能位(bit0) STR R1, [R0, #0x30]
注:需根据LED实际连接的GPIO端口修改对应位,同时确保HFCLK系统时钟已正常启动(默认内部RC时钟通常已启用,若需外部晶振需额外配置)。
3. 解锁GPIO寄存器(若需)
部分EFM32型号的GPIO寄存器默认处于写保护状态,需先解锁才能修改配置:
; 解锁GPIOA寄存器(GPIOA基地址:0x40000000,LOCK寄存器偏移0x200) LDR R0, =0x40000000 LDR R1, =0x00000001 ; 解锁码以 datasheet 为准,此为示例值 STR R1, [R0, #0x200]
4. 禁用MPU(或配置MPU权限)
若MPU默认启用且限制了外设地址访问,会触发内存访问故障。裸机调试时直接禁用MPU更简便:
; 禁用MPU(MPU_CTRL寄存器地址:0xE000ED90) LDR R0, =0xE000ED90 LDR R1, [R0] BIC R1, R1, #0x01 ; 清除ENABLE位 STR R1, [R0]
完成以上步骤后,再执行你的LED闪烁汇编代码,即可像普通Cortex-M3一样操作GPIO而不触发硬故障。
内容的提问来源于stack exchange,提问作者falken
相关产品推荐
相关产品推荐

