我只是在這里迷失了這段代碼,試圖在裸機上配置他們的 devkit 中的硅實驗室 efm32pg22,通過 segger 作業室的內部 J-Link 訪問(很棒的快速 ide) - 我有這樣的例子,在他們的簡單作業室作業的 C 語言中閃爍你好,但是試圖在純匯編程式中輕松實作我在微芯片 pic32 mc00 或 samd21g17d 上所做的相同事情,只有時鐘和啟動通過 mplab x 中的 gui 配置...時鐘配置簡單的方法,或者我還沒有找到它。在硬體級別上,這種皮質野獸的暫存器因制造商而異,在 C/C 中,cmsis 有一些不便宜的統一 - 但我只想知道在時鐘/啟動之后只有作業的原始 GPIO 需要什么最低限度...... Segger 專案是針對特定 efm32pg22 的通用 cortex-m,因此 cortex-M33 具有信任區安全性 - 我可能不知道所有內容都被鎖定或關閉,或者 MCU 處于哪種狀態,如果特權或非特權 - 有 2 組暫存器映射,但沒有任何效果。就我嘗試在 GPIO 配置暫存器(或 SMU regs 也用于查詢某些內容)上“存盤”甚至“加載”而言,它是拋出硬故障例外。全部使用 segger ide 除錯器而不是板載 j-link。請問,我做錯了什么,這里缺少什么?在 GPIO 配置暫存器(或 SMU regs 也可以查詢某些內容)上,它會拋出硬故障例外。全部使用 segger ide 除錯器而不是板載 j-link。請問,我做錯了什么,這里缺少什么?在 GPIO 配置暫存器(或 SMU regs 也可以查詢某些內容)上,它會拋出硬故障例外。全部使用 segger ide 除錯器而不是板載 j-link。請問,我做錯了什么,這里缺少什么?
在 C 中,我只有以下代碼:
extern void blink(void);
int main ( void )
{
blink();
}
在blink.s我有這個:
;@https://github.com/hubmartin/ARM-cortex-M-bare-metal-assembler-examples/blob/master/02 - Bare metal blinking LED/main.S
;@https://sites.google.com/site/hubmartin/arm/arm-cortex-bare-metal-assembly/02---arm-cortex-bare-metal-assembly-blinking-led
;@https://mecrisp-stellaris-folkdoc.sourceforge.io/projects/blink-f0disco-gdbtui/doc/readme.html
;@https://microcontrollerslab.com/use-gpio-pins-tm4c123g-tiva-launchpad/
;@!!! ENABLE GPIO CLOCK SOURCE ON EFM32 !!!
;@https://community.silabs.com/s/share/a5U1M000000knsWUAQ/hello-world-part-2-create-firmware-to-blink-the-led?language=en_US
;@EFM32 GPIO
;@https://www.silabs.com/documents/public/application-notes/an0012-efm32-gpio.pdf
;@ ARM thumb2 ISA
;@https://www.engr.scu.edu/~dlewis/book3/docs/ARM_and_Thumb-2_Instruction_Set.pdf
;@https://sciencezero.4hv.org/index.php?title=ARM:_Cortex-M3_Thumb-2_instruction_set
;@!!! https://stackoverflow.com/questions/48561243/gnu-arm-assembler-changes-orr-into-movw
;@segger assembler
;@https://studio.segger.com/segger/UM20006_Assembler.pdf
;@https://www.segger.com/doc/UM20006_Assembler.html
;@!!! unfortunatelly, we dont know here yet how to include ASM SFR defines, nor for MPLAB ARM (Harmony) !!!
;@#include <xc.h>
;@#include "definitions.h"
.cpu cortex-m33
.thumb
.text
.section .text.startup.main,"ax",%progbits
.balign 2
.p2align 2,,3
.global blink
//.arch armv8-m.base
.arch armv6-m
.syntax unified
.code 16
.thumb_func
.fpu softvfp
.type blink, %function
//!!! here we have manually entered GPIO PORT defines for PIC32CM
.equ SYSCFG_BASE_ADDRESS, 0x50078000
.equ SMU_BASE_ADDRESS, 0x54008000
//.equ SMU_BASE_ADDRESS, 0x5400C000
.equ CMU_BASE_ADDRESS, 0x50008000
.equ GPIO_BASE_ADDRESS, 0x5003C000 // this differs totally from both "special" infineon and microchip "standard?" cortex devices !!!
.equ DELAY, 40000
// Vector table
.word 0x20001000 // Vector #0 - Stack pointer init value (0x20000000 is RAM address and 0x1000 is 4kB size, stack grows "downwards")
.word blink // Vector #1 - Reset vector - where the code begins
// Vector #3..#n - I don't use Systick and another interrupts right now
// so it is not necessary to define them and code can start here
blink:
LDR r0, =(SYSCFG_BASE_ADDRESS 0x200) // SYSCFG SYSCFG_CTRL
LDR r1, =0 // 0 diable address faults exceptions
ldr r1, [r0] // Store R0 value to r1
LDR r0, =(CMU_BASE_ADDRESS) // CMU CMU_SYSCLKCTRL PCLKPRESC CLKSEL
LDR r1, =0b10000000001 // FSRCO 20MHz PCLK = HCLK/2 = 10MHz
STR r1, [r0, 0x70] // Store R0 value to r1
LDR r0, =(CMU_BASE_ADDRESS) // CMU CMU_CLKEN0
LDR r1, [r0, 0x64]
LDR r2, =(1 << 25) // GPIO CLK EN
orrs r1, r2 // !!! HORROR !!! -- orr is not possible in thumb2 ?? only orrs !! (width suffix)
STR r1, [r0, 0x64] // Store R0 value to r1
LDR r1, [r0, 0x68]
LDR r2, =(1 << 14) // SMU CLK EN
orrs r1, r2 // !!! HORROR !!! -- orr is not possible in thumb2 ?? only orrs !! (width suffix)
STR r1, [r0, 0x68] // Store R0 value to r1
//LDR r0, =(SMU_BASE_ADDRESS) // SMU SMU_LOCK
//LDR r1, =11325013 // SMU UNLOCK CODE
//STR r1, [r0, 0x08] //Store R0 value to r1
ldr r0, =(SMU_BASE_ADDRESS) // SMU reading values, detection - AGAIN, HARD FAULTS !!!!!!!
ldr r1, [r0, 0x04]
ldr r1, [r0, 0x20]
ldr r1, [r0, 0x40]
//LDR r0, =(GPIO_BASE_ADDRESS 0x300) // GPIO UNLOCK
//LDR r1, =0xA534
//STR r1, [r0] // Store R0 value to r1
//!! THIS BELOW IS OLD FOR SAMD , WE STILL SIMPLY CANT ENABLE GPIO !!!!
// Enable PORTA pin 4 as output
LDR r0, =(GPIO_BASE_ADDRESS) // DIR PORTA
LDR r1, =0b00000000000001000000000000000000
STR r1, [r0, 0x04] // Store R0 value to r1
LDR R2, =1
loop:
// Write high to pin PA04
LDR r0, =GPIO_BASE_ADDRESS // OUT PORTA
LDR r1, =0b10000 // PORT_PA04
STR r1, [r0, 0x10] // Store R1 value to address pointed by R0
// Dummy counter to slow down my loop
LDR R0, =0
LDR R1, =DELAY
loop0:
ADD R0, R2
cmp R0, R1
bne loop0
// Write low to PA04
LDR r0, =GPIO_BASE_ADDRESS // OUT PORTA
LDR r1, =0b00000
STR r1, [r0, 0x10] // Store R1 value to address pointed by R0
// Dummy counter to slow down my loop
LDR R0, =0
LDR R1, =DELAY
loop1:
ADD R0, R2
cmp R0, R1
bne loop1
b loop
更新:好吧,現在我在 SimplicityStudio 中再次嘗試,在預生成的系統初始化后放置 blink() 呼叫:
extern void blink(void);
int main(void)
{
// Initialize Silicon Labs device, system, service(s) and protocol stack(s).
// Note that if the kernel is present, processing task(s) will be created by
// this call.
sl_system_init();
blink();
}
在blink.s中有這個代碼: - 在這里它以這種方式作業并閃爍......
.cpu cortex-m33
.thumb
.text
.section .text.startup.main,"ax",%progbits
.balign 2
.p2align 2,,3
.global blink
//.arch armv8-m.base
.arch armv6-m
.syntax unified
.code 16
.thumb_func
.fpu softvfp
.type blink, %function
/*
//!!! here we have manually entered GPIO PORT defines for PIC32CM
.equ SYSCFG_BASE_ADDRESS, 0x50078000
.equ SMU_BASE_ADDRESS, 0x54008000
//.equ SMU_BASE_ADDRESS, 0x5400C000
.equ CMU_BASE_ADDRESS, 0x50008000
*/
.equ GPIO_BASE_ADDRESS, 0x5003C000 // this differs totally from both "special" infineon and microchip "standard?" cortex devices !!!
.equ DELAY, 400000
// Vector table
.word 0x20001000 // Vector #0 - Stack pointer init value (0x20000000 is RAM address and 0x1000 is 4kB size, stack grows "downwards")
.word blink // Vector #1 - Reset vector - where the code begins
// Vector #3..#n - I don't use Systick and another interrupts right now
// so it is not necessary to define them and code can start here
blink:
// Enable PORTA pin 4 as output
LDR r0, =(GPIO_BASE_ADDRESS) // DIR PORTA
LDR r1, =0b00000000000001000000000000000000
STR r1, [r0, 0x04]
loop:
// Write high to pin PA04
LDR r0, =GPIO_BASE_ADDRESS // OUT PORTA
LDR r1, =0b10000 // PORT_PA04
STR r1, [r0, 0x10]
// Dummy counter to slow down my loop
LDR R0, =0
LDR R1, =DELAY
loop0:
ADD R0, R2
cmp R0, R1
bne loop0
// Write low to PA04
LDR r0, =GPIO_BASE_ADDRESS // OUT PORTA
LDR r1, =0b00000
STR r1, [r0, 0x10]
// Dummy counter to slow down my loop
LDR R0, =0
LDR R1, =DELAY
loop1:
ADD R0, R2
cmp R0, R1
bne loop1
b loop
...所以現在,我很好奇,純匯編代碼中缺少什么來使 cortex-m33 進入某種“簡單”狀態,只是忽略了信任區,可能類似于說普通的 cortex-m3 使用它?
有人可以幫忙嗎?我正在深入研究這個資料表/參考手冊,但直到現在還沒有運氣...... https://www.silabs.com/documents/public/reference-manuals/efm32pg22-rm.pdf
再次更新:嗯,將嘗試找出...通過遍歷 system_init C-code 它清楚地發生了什么,還有一些芯片勘誤表解決方法,但我在初始化時從未接觸過 DCDC,這可能是罪魁禍首...
void sl_platform_init(void)
{
CHIP_Init();
sl_device_init_nvic();
sl_board_preinit();
sl_device_init_dcdc();
sl_device_init_hfxo();
sl_device_init_lfxo();
sl_device_init_clocks();
sl_device_init_emu();
sl_board_init();
}
uj5u.com熱心網友回復:
好吧,為 MCU 啟動生成特定于制造商的代碼非常重要且有用))......來自不同制造商的此類 MCU 在暫存器級別上確實有很大不同(即使都是基于“cortex-m”內核的),它的如果有足夠的閃存可用,嘗試在匯編中手動配置它們毫無價值,而且主要是。因此,到目前為止,segger/keil/iar“通用”arm/cortex IDE 無法在特定部件上正確執行此操作,因此使用制造商特定 IDE(主要)以圖形方式配置啟動時鐘和外圍設備至關重要,或者至少,它真的是最簡單的方法(我知道,在所有組裝嘗試之后非常昂貴的觀察......))。之后,即使是純匯編“閃爍”helloworld 測驗也很容易,稱為 extern C 函式。您可能會問,如果至少有 CMSIS(在 arm 上)“平臺抽象層”C-headers,為什么我仍在考慮組裝(不,它對抽象沒有幫助,因為設備仍然非常不同,你只有暫存器符號#defines 和 typedefs 和 enums 可以輕松地在 C 中做某事,好吧)。但是我正在嘗試將一些 C 編譯代碼與手寫程式集進行比較,以實作某些特定目的,這需要從頭開始強制優化演算法,并且通常更容易直接在程式集中思考/設計它,以依賴于非常復雜描述的 C 編譯器優化(每個編譯器都有自己的 LONG 檔案,他的優化是如何作業的,在這個級別上,C 仍然過于抽象和移動目標,而且,您嘗試為甚至不同的 MCU 架構撰寫一些東西(想想 ARM cortex-m,PIC32/mips , 和/或什至 PIC16/18 PIC24、AVR、MSP430 ...) - 雖然通用演算法可以在共享偽匯編中描述為盡可能接近硬體,但不知道每個架構 C 編譯器的所有優化怪癖 -通常也有更多不同的 C 編譯器。因此,要將 C 編譯器生成的代碼與手寫程式集進行比較,您可以這樣做,并且我已經在許多非常不同的體系結構上嘗試過這種程式集閃爍,以防我使用所有 GUI 配置和代碼生成到始終可編譯的空 C 專案,當然,使用此類生成的啟動具有非常不同的代碼大小輸出。大多數先進的 MCU 確實非常復雜,主要是時鐘配置和引腳功能配置,然后是不同的外圍設備,當然。在某種程度上,某些相似之處僅在單個制造商級別是可能的,因此顯然單個制造商的MCU通常采用相似的方法。所以最終的解決方案是生成啟動然后立即切換到組裝,這是可行的。當然,在小閃存的情況下,甚至可以進一步優化啟動代碼,但它在最小的 8 位部件上最重要,無論如何啟動都非常容易,或者生成的代碼也很明顯。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/521053.html
