【目标】
移植zephyr需要先了解gd32f527的启动,写一个纯汇编的代码,让LED灯先跑起来。
【硬件】
GD32F527I-EVAL开发板
LED灯接到PF7上面
【代码实现】
结合gd32的固件库中的启动文件以及链接文件等。
1、汇编文件
@/****************************************************************************** @ File: main.s @ Brief: LED blinky application for GD32F527 @ @ Uses default IRC16M clock (16MHz internal RC oscillator) @ LED connected to GPIOC pin 13 (LED2 on GD32F527 board) @******************************************************************************/ .syntax unified .cpu cortex-m33 .fpu fpv5-sp-d16 .thumb .global main .global SystemInit @ ============================================================================= @ Register definitions for GD32F527 @ ============================================================================= .equ GPIO_BASE, 0x40020000 .equ GPIOC_BASE, 0x40020800 .equ GPIOD_BASE, 0x40020C00 .equ GPIOE_BASE, 0x40021000 .equ GPIOF_BASE, 0x40021400 .equ GPIOG_BASE, 0x40021800 .equ GPIOH_BASE, 0x40021C00 .equ GPIOI_BASE, 0x40022000 .equ RCU_BASE, 0x40023800 @ GPIO register offsets .equ GPIO_CTL0, 0x00 .equ GPIO_OMODE, 0x04 .equ GPIO_OSPD, 0x08 .equ GPIO_PUD, 0x0C .equ GPIO_ISTAT, 0x10 .equ GPIO_OCTL, 0x14 .equ GPIO_BOP, 0x18 .equ GPIO_BC, 0x28 @ RCU register offsets .equ RCU_CTL, 0x00 .equ RCU_CFG0, 0x08 .equ RCU_AHBEN, 0x30 .equ RCU_APB2EN, 0x18 @ Bit definitions .equ GPIO_PIN7, (1 << 7) .equ RCU_AHBEN_GPIOFEN, (1 << 5) .equ IRC16MEN, (1 << 0) .equ IRC16MSTB, (1 << 1) @ ============================================================================= @ SystemInit - Minimal system initialization (uses default IRC16M) @ ============================================================================= .section .text.SystemInit,"ax",%progbits .global SystemInit .type SystemInit, %function SystemInit: bx lr .size SystemInit, .-SystemInit @ ============================================================================= @ Delay function using simple loop @ ============================================================================= .section .text.delay,"ax",%progbits .global delay @ r0 = delay count (cycles at 16MHz) delay: subs r0, r0, #1 bne delay bx lr @ ============================================================================= @ LED initialization - Configures GPIOC pin 13 as push-pull output @ ============================================================================= .section .text.led_init,"ax",%progbits .global led_init .type led_init, %function led_init: @ Enable GPIOF clock in RCU ldr r0, =RCU_BASE ldr r1, [r0, #RCU_AHBEN] orr r1, r1, #RCU_AHBEN_GPIOFEN str r1, [r0, #RCU_AHBEN] @ Configure PF7 as push-pull output ldr r0, =GPIOF_BASE ldr r1, [r0, #GPIO_CTL0] bic r1, r1, #(0x3 << 14) orr r1, r1, #(0x1 << 14) str r1, [r0, #GPIO_CTL0] @ Set output speed to 50MHz ldr r1, [r0, #GPIO_OSPD] bic r1, r1, #(0x3 << 14) orr r1, r1, #(0x3 << 14) str r1, [r0, #GPIO_OSPD] @ Turn off LED initially (PF7 is active low on most boards) ldr r0, =GPIOF_BASE ldr r1, [r0, #GPIO_OCTL] orr r1, r1, #GPIO_PIN7 str r1, [r0, #GPIO_OCTL] bx lr .size led_init, .-led_init @ ============================================================================= @ LED control functions @ ============================================================================= .section .text.led_ctrl,"ax",%progbits .global led_on .global led_off .type led_on, %function .type led_off, %function @ Turn LED on (active low) led_on: ldr r0, =GPIOF_BASE ldr r1, [r0, #GPIO_OCTL] bic r1, r1, #GPIO_PIN7 str r1, [r0, #GPIO_OCTL] bx lr @ Turn LED off (active low) led_off: ldr r0, =GPIOF_BASE ldr r1, [r0, #GPIO_OCTL] orr r1, r1, #GPIO_PIN7 str r1, [r0, #GPIO_OCTL] bx lr @ ============================================================================= @ Main function @ ============================================================================= .section .text.main,"ax",%progbits .global main .type main, %function main: bl led_init main_loop: bl led_on ldr r0, =8000000 bl delay bl led_off ldr r0, =8000000 bl delay b main_loop .size main, .-main .end
2、链接文件:
/*!
* ============================================================================
* File: linker.ld
* Description: Linker script for GD32F527 LED Assembly Project
*
* This linker script defines the memory layout for GD32F527 chip.
* It specifies the memory regions and their attributes for the linker.
*
* Target: GD32F527xx
* Flash Size: 4096KB (4MB)
* RAM Size: 1024KB (1MB)
* TCMRAM Size: 64KB
*
* Memory Map:
* Flash: 0x08000000 - 0x087FFFFF (4096KB)
* RAM: 0x20000000 - 0x200FFFFF (1024KB)
* TCMRAM: 0x10000000 - 0x1000FFFF (64KB)
*
* ============================================================================
*/
/* Entry point: Reset_Handler */
ENTRY(Reset_Handler)
/* Stack and Heap size definitions */
__stack_size = 2K;
__heap_size = 1K;
/* ============================================================================
* Memory Regions Definition
* ============================================================================
*
* The MEMORY command defines memory regions and their attributes.
* Syntax:
* region_name (attr) : ORIGIN = start_address, LENGTH = size
*
* Attributes:
* r - read-only sections
* w - read-write sections
* x - executable sections
* a - allocated sections
* i - initialized sections
* ============================================================================
*/
MEMORY
{
/* Flash memory: Read-only, contains program code and constant data */
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K
/* RAM: Read-Write, contains .data and .bss sections */
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 1024K
/* TCMRAM: Tightly Coupled Memory RAM, faster than normal RAM */
TCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
}
/* ============================================================================
* Stack and Heap Definition
* ============================================================================
*
* The _estack symbol is the initial stack pointer value.
* It is calculated as the end of RAM minus the stack size.
* ============================================================================
*/
_estack = ORIGIN(RAM) + LENGTH(RAM) - __stack_size;
/* Define heap and stack symbols for C library */
_Min_Heap_Size = __heap_size;
_Min_Stack_Size = __stack_size;
/* ============================================================================
* Section Definitions
* ============================================================================
*
* The SECTIONS command defines how input sections are combined into output
* sections, and where output sections are placed in memory.
* ============================================================================
*/
SECTIONS
{
/*!
* ========================================================================
* 1. Interrupt Vector Table
* ========================================================================
* The vector table must be placed at the beginning of Flash.
* It contains the initial stack pointer and all interrupt handlers.
* =========================================================================
*/
.vectors :
{
. = ALIGN(4);
KEEP(*(.vectors))
. = ALIGN(4);
__Vectors_End = .;
__Vectors_Size = __Vectors_End - .;
} >FLASH
/*!
* ========================================================================
* 2. .text Section - Program Code
* ========================================================================
* Contains executable code (.text.*)
* =========================================================================
*/
.text :
{
. = ALIGN(4);
*(.text)
*(.text*)
*(.glue_7)
*(.glue_7t)
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
/* End of text section */
_etext = .;
} >FLASH
/*!
* ========================================================================
* 3. .rodata Section - Read-Only Data
* ========================================================================
* Contains constant data (strings, const variables, etc.)
* =========================================================================
*/
.rodata :
{
. = ALIGN(4);
*(.rodata)
*(.rodata*)
. = ALIGN(4);
} >FLASH
/*!
* ========================================================================
* 4. ARM Exception Handling Tables
* ========================================================================
* =========================================================================
*/
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} >FLASH
.ARM :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
/* ARM attributes */
.ARM.attributes :
{
*(.ARM.attributes)
} >FLASH
/*!
* ========================================================================
* 5. C++ Constructor/Destructor Tables
* ========================================================================
* =========================================================================
*/
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array*))
KEEP (*(SORT(.fini_array.*)))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
/*!
* ========================================================================
* 6. .data Section - Initialized Global/Static Variables
* ========================================================================
* Contains variables with initial values.
* The initial values are stored in Flash and copied to RAM at startup.
*
* _sidata: .data load address (in Flash)
* _sdata: .data start address (in RAM)
* _edata: .data end address (in RAM)
* =========================================================================
*/
_sidata = LOADADDR(.data);
.data :
{
. = ALIGN(4);
_sdata = .;
*(.data)
*(.data*)
. = ALIGN(4);
_edata = .;
} > RAM AT> FLASH
/*!
* ========================================================================
* 7. .bss Section - Uninitialized Global/Static Variables
* ========================================================================
* Contains variables without initial values (initialized to zero).
*
* _sbss: .bss start address
* _ebss: .bss end address
* =========================================================================
*/
. = ALIGN(4);
.bss :
{
. = ALIGN(4);
_sbss = .;
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
__bss_end__ = _ebss;
} > RAM
/*!
* ========================================================================
* 8. Heap and Stack Space
* ========================================================================
* =========================================================================
*/
.heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );
/* Heap allocation */
. = . + _Min_Heap_Size;
PROVIDE( _heap_end = . );
/* Stack allocation */
. = . + _Min_Stack_Size;
PROVIDE( _sp = . );
. = ALIGN(8);
} > RAM
/*!
* ========================================================================
* 9. TCMRAM Section (Optional)
* ========================================================================
* Tightly Coupled Memory for critical data.
* =========================================================================
*/
_sitcmram = LOADADDR(.tcmram);
.tcmram :
{
. = ALIGN(4);
.stcmram = .;
*(.tcmram)
*(.tcmram*)
. = ALIGN(4);
_etcmram = .;
} > TCMRAM AT> FLASH
/*!
* ========================================================================
* 10. Discarded Sections
* ========================================================================
* Sections that are not referenced are placed here.
* =========================================================================
*/
/DISCARD/ :
{
*(.comment)
}
}
/* ============================================================================
* Input Section Group
* ============================================================================
*
* Specifies libraries to link against.
* These are standard ARM libraries that provide:
* - libgcc.a: GCC runtime library
* - libc.a: C standard library
* - libm.a: Math library
* - libnosys.a: No-sys library (minimal syscalls)
* ============================================================================
*/
GROUP(libgcc.a libc.a libm.a libnosys.a)3、makefile
############################################################################## # File: Makefile # Description: Build script for GD32F527 LED Assembly Project ############################################################################## # Detect OS ifeq ($(OS),Windows_NT) DEL = rmdir /s /q MKDIR = mkdir RM = del /q else DEL = rm -rf MKDIR = mkdir -p RM = rm -f endif # Toolchain prefix AS = arm-none-eabi-as CC = arm-none-eabi-gcc LD = arm-none-eabi-ld OBJCOPY = arm-none-eabi-objcopy OBJDUMP = arm-none-eabi-objdump SIZE = arm-none-eabi-size # Device settings DEVICE = GD32F527xx CPU = cortex-m33 FPU = fpv5-sp-d16 # System clock SYSCLK = 200000000 # Memory settings FLASH_ORIGIN = 0x08000000 FLASH_SIZE = 4096K RAM_ORIGIN = 0x20000000 RAM_SIZE = 1024K # Paths CMSIS_PATH = ../../Firmware/CMSIS/GD/GD32F527/Include # Flags ASFLAGS = -mcpu=$(CPU) -mthumb -mfloat-abi=hard -mfpu=$(FPU) \ -I$(CMSIS_PATH) -Wall LDFLAGS = -mcpu=$(CPU) -mthumb -mfloat-abi=hard -mfpu=$(FPU) \ -T linker.ld --specs=nosys.specs -Wl,--gc-sections \ -Wl,-Map=build/$(PROJECT_NAME).map -nostartfiles # Output BUILD_DIR = build PROJECT_NAME = gd32f527_led_asm SOURCES = startup.s main.s OBJECTS = $(patsubst %.s,$(BUILD_DIR)/%.o,$(SOURCES)) BINARY = $(BUILD_DIR)/$(PROJECT_NAME).elf HEX = $(BUILD_DIR)/$(PROJECT_NAME).hex BIN = $(BUILD_DIR)/$(PROJECT_NAME).bin LST = $(BUILD_DIR)/$(PROJECT_NAME).lst ############################################################################## # Build rules ############################################################################## .PHONY: all clean flash size disasm info all: info $(BINARY) $(HEX) $(BIN) $(LST) @echo "" @echo "Build complete!" @echo "ELF: $(BINARY)" @echo "Hex: $(HEX)" @echo "Bin: $(BIN)" @echo "" $(SIZE) $(BINARY) info: @echo "" @echo "========================================" @echo "GD32F527 LED Assembly Project" @echo "========================================" @echo "Device: $(DEVICE)" @echo "CPU: $(CPU)" @echo "System Clock: $(SYSCLK) Hz" @echo "Flash: $(FLASH_SIZE) @ $(FLASH_ORIGIN)" @echo "RAM: $(RAM_SIZE) @ $(RAM_ORIGIN)" @echo "========================================" @echo "" $(BUILD_DIR): $(MKDIR) $(BUILD_DIR) $(BUILD_DIR)/%.o: %.s | $(BUILD_DIR) @echo " AS $<" $(AS) $(ASFLAGS) -o $@ $< $(BINARY): $(OBJECTS) @echo " LD $@" $(CC) $(OBJECTS) $(LDFLAGS) -o $@ $(HEX): $(BINARY) @echo " HEX $@" $(OBJCOPY) -O ihex $< $@ $(BIN): $(BINARY) @echo " BIN $@" $(OBJCOPY) -O binary $< $@ $(LST): $(BINARY) @echo " LST $@" $(OBJDUMP) -S -D $< > $@ clean: $(DEL) $(BUILD_DIR) 2>nul || exit 0 size: $(BINARY) $(SIZE) -A -d $(BINARY) disasm: $(LST) @echo "Disassembly: $(LST)" flash: $(BIN) @echo "Flashing $(BIN) to $(FLASH_ORIGIN)..." @echo "Please use GD-Link, J-Link or ST-Link to flash" @echo "Or use: openocd -f interface/stlink.cfg -f target/gd32f5x.cfg -c \"program $(BIN) verify reset exit\"" flash-openocd: $(BIN) openocd -f interface/stlink.cfg -f target/gd32f5x.cfg -c "program $(BIN) verify reset exit" help: @echo "" @echo "GD32F527 LED Assembly - Build Targets" @echo "======================================" @echo "" @echo " make - Build project (default)" @echo " make all - Build all targets" @echo " make clean - Clean build files" @echo " make size - Show memory usage" @echo " make disasm - Generate disassembly" @echo " make flash - Flash to device" @echo " make help - Show this help" @echo ""
【调试工具】
jlink Ultra+
使用jlink与开发板的调试接口相连:

【调试软件】
Ozone
导入hex文件后可以看到系统正常运行:

【总结】
移植zephyr需要先了解到GD32F527的启动流程,以及相应寄存器的使用,这样才能更好的移植。这次只是试验的开始。
我要赚赏金
