设为首页 加入收藏

TOP

HC32L110(四) HC32L110的startup启动文件和ld连接脚本(一)
2023-07-23 13:27:59 】 浏览:44
Tags:HC32L110 startup 文件和 连接脚

目录

以下介绍项目中的startup和ld文件, 以及HC32L110的启动机制

仓库地址: https://github.com/IOsetting/hc32l110-template

如果转载, 请注明出处.

关于

因为是面向 GCC Arm Embedded 工具链的版本, 所以 startup 代码和 ld 连接描述脚本都依据 GCC Arm 工具链的格式.

Startup文件说明

startup_hc32l110.c 文件位于 Libraries/CMSIS

// 为下面的 uint32_t 等类型引入定义
#include <stdint.h>

// 将 ptr_func_t 定义为函数指针
typedef void (*ptr_func_t)();

// 下面这三个 __data 开头的变量是一组, 用于载入变量预先定义的值. 这些地址在连接阶段, 根据区域的实际情况被赋值

// __data_start 是载入的目标起始地址
extern uint32_t __data_start;
// __data_end 是载入的目标结束地址
extern uint32_t __data_end;
// 载入值的来源
extern uint32_t __data_load;

// __bss 开头的变量, 代表启动时需要清零的变量, __bss_start 和 __bss_end 分别代表了内存的起始和结束地址, 也是连接阶段会赋值
extern uint32_t __bss_start;
extern uint32_t __bss_end;

extern uint32_t __heap_start;
extern uint32_t __stacktop;

// 初始化, 在进入main函数之前需要执行的方法列表
extern ptr_func_t __init_array_start[];
extern ptr_func_t __init_array_end[];

// 引入外部定义的 SystemInit 和 main 方法
extern int main(void);
extern void SystemInit(void);

// 弱函数别名, 在对应的函数未定义时, 会调用别名对应的函数
#define WEAK_ALIAS(x) __attribute__ ((weak, alias(#x)))

// 下面这些都是中断函数
/* Cortex M3 core interrupt handlers */
void Reset_Handler(void);
void NMI_Handler(void) WEAK_ALIAS(Dummy_Handler);
void HardFault_Handler(void) WEAK_ALIAS(Dummy_Handler);
void SVC_Handler(void) WEAK_ALIAS(Dummy_Handler);
void PendSV_Handler(void) WEAK_ALIAS(Dummy_Handler);
void SysTick_Handler(void) WEAK_ALIAS(Dummy_Handler);

// 直接用中断号作为函数名, 具体的对应关系在 ddl.h 中, 
// 这些是沿用官方DDL驱动代码, 将来会替换为直接调用实际的中断处理函数
void IRQ000_Handler(void) WEAK_ALIAS(Dummy_Handler);
void IRQ001_Handler(void) WEAK_ALIAS(Dummy_Handler);
void IRQ002_Handler(void) WEAK_ALIAS(Dummy_Handler);
// 中间略
void IRQ031_Handler(void) WEAK_ALIAS(Dummy_Handler);

/* 将 __stacktop 初始地址记录到 __stack_init. 
关于 used 的定义: 即是未被使用, 编译后也需要保留
This attribute, attached to a function, means that code must be emitted 
for the function even if it appears that the function is not referenced. 
This is useful, for example, when the function is referenced only in 
inline assembly.
*/
__attribute__((section(".stack"), used)) uint32_t *__stack_init = &__stacktop;

/* Stack top and vector handler table 
中断向量表, 这些函数, 和前面的定义需要一致. 这些函数的实际逻辑在 ddl.h 和 ddl.c中定义.
*/
__attribute__ ((section(".vectors"), used)) void *vector_table[] = {
    Reset_Handler,
    NMI_Handler,
    HardFault_Handler,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    SVC_Handler,
    0,
    0,
    PendSV_Handler,
    SysTick_Handler,
    IRQ000_Handler,
    IRQ001_Handler,
    IRQ002_Handler,
    IRQ003_Handler,
// 中间略
    IRQ029_Handler,
    IRQ030_Handler,
    IRQ031_Handler};

/*
最重要的, 重启后的初始化方法, 由ld文件中的 ENTRY(Reset_Handler) 指定
*/
__attribute__((used)) void Reset_Handler(void)
{
    uint32_t *src, *dst;

    /* 从 Flash 到 RAM 复制变量值 */
    src = &__data_load;
    dst = &__data_start;
    while (dst < &__data_end) *dst++ = *src++;

    /* 清空 bss section */
    dst = &__bss_start;
    while (dst < &__bss_end) *dst++ = 0;

    // 这里调用前面声明的 SystemInit
    SystemInit();
    // 调用初始化函数列表
    for (const ptr_func_t *f = __init_array_start; f < __init_array_end; f++)
    {
        (*f)();
    }

    // 调用前面声明的main
    main();
}

// 默认的中断处理方法
void Dummy_Handler(void)
{
    while (1);
}
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇电机的反电动势了解及步进电机的.. 下一篇使用STM32控制TMC5160驱动步进电机

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目