这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【gd32f527移植Zephyr】2、使用汇编写一个点灯程序

共1条 1/1 1 跳转至

【gd32f527移植Zephyr】2、使用汇编写一个点灯程序

高工
2026-02-17 14:17:30     打赏

【目标】

移植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与开发板的调试接口相连:

image.png

【调试软件】

Ozone

导入hex文件后可以看到系统正常运行:

image.png

【总结】

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




关键词: gd32f527     Zephyr    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]