M开发之文件详解,豹哥嵌入式讲堂



  大家好,小编是豹哥,猎豹的豹,犀利哥的哥。后天豹哥给我们讲的是嵌入式开发里的source文件

  我们好,作者是豹哥,猎豹的豹,犀利哥的哥。前几天豹哥给我们讲的是嵌入式开发里的source文件

  无人不知,嵌入式开发属于偏底层的支出,首要编制程序语言是C和汇编。所以本文要讲的source文件重大指的正是c文件和汇编文件。
  尽管在平日开发中,大家都只会关切本身创建的.c/.h/.s源文件,但其实我们不知不觉中也跟很多不是大家创立的源文件在应酬,那么难题来了,2个完完全全的嵌入式工程(以基于A奥德赛M
Cortex-M控制器的工程为例)到底会含有哪些source文件呢?
  今后就到了豹哥的show
time了,豹哥将这么些文件按来源分为5类10种,下边豹哥按项目逐一分析那一个文件:

  远近驰名,嵌入式开发属于偏底层的支付,重要编程语言是C和汇编。所以本文要讲的source文件根本指的就是c文件和汇编文件。
  就算在平凡开发中,大家都只会关心本身创办的.c/.h/.s源文件,但骨子里大家不知不觉中也跟很多不是大家创设的源文件在交际,那么难题来了,3个完整的嵌入式工程(以基于AGL450M
Cortex-M控制器的工程为例)到底会包蕴怎样source文件呢?
  今后就到了豹哥的show
time了,豹哥将这个文件按来源分为5类10种,下边豹哥按连串逐1分析这一个文件:

第一类:Provided by Committee

  第三类公事由C标准委员会提供,该类文件伴随着标准的发布而日趋扩张。该类文件重大正是1种,即C标准库。
1. C standard Library
  大家都知晓C语言是有业内的,常见的C标准有ANSI
C(C8玖)、C9九、C11,而C标准函数库(C 斯坦dard
library)正是颇具符合C标准的头文件的会面,以及常用的函数库完结程序。C标准库由Committee制制订并公布布,平日会被含有在IDE里。列举部分普遍文件和函数如下,是或不是觉得似曾相识?

/* 常用文件 */ assert.h,stdio.h,stddef.h,stdint.h,string.h ...
/* 常用定义 */ bool,NULL,uint8_t,uint16_t,uint32_t...
/* 常用函数 */ assert(),printf(),memset(),memcpy()...

第一类:Provided by Committee

  第2类公事由C标准委员会提供,该类文件伴随着标准的发布而日趋增添。该类文件注重正是1种,即C标准库。
1. C standard Library
  大家都知情C语言是有正统的,常见的C标准有ANSI
C(C8九)、C9九、C1一,而C标准函数库(C Standard
library)就是兼具符合C标准的头文件的成团,以及常用的函数库完结程序。C标准库由Committee制订宣布,日常会被含有在IDE里。列举部分宽广文件和函数如下,是还是不是觉得似曾相识?

/* 常用文件 */ assert.h,stdio.h,stddef.h,stdint.h,string.h ...
/* 常用定义 */ bool,NULL,uint8_t,uint16_t,uint32_t...
/* 常用函数 */ assert(),printf(),memset(),memcpy()...

第二类:Provided by IDE(Compiler)

  第3类公事由IDE提供,C语言是编写翻译型语言,要求编写翻译器将C程序汇编成机器码,全部便有了1些跟编写翻译器天性相关的函数库。
2. Compiler Library
  大家在付出嵌入式应用时必要正视集成开发条件(IDE),常见的IDE有GCC(GNUC),Keil
MDK(AENVISIONMCC),IAR
EWA奥迪Q五M(ICCALX570M),这么些IDE都有配套的C编写翻译器,这么些编写翻译器是各有特色的,为了丰裕显示各编写翻译器特色,配套的函数库便应运而生。
  编写翻译器函数库是因IDE而异的,此处仅讲3个例子以供参考,须要精晓越多需查看各IDE手册。
  以IAR
EWARM里的DLib_Product_string.h文件为例,该文件中重定义了memcpy的落到实处:

  #define _DLIB_STRING_SKIP_INLINE_MEMCPY
  #pragma inline=forced_no_body
  __EFF_NENR1NW2R1 __ATTRIBUTES void * memcpy(void * _D, const void * _S, size_t _N)
  {
    __aeabi_memcpy(_D, _S, _N);
    return _D;
  }

第二类:Provided by IDE(Compiler)

  第壹类公事由IDE提供,C语言是编译型语言,须要编写翻译器将C程序汇编成机器码,所有便有了有个别跟编写翻译器本性相关的函数库。
2. Compiler Library
  大家在开发嵌入式应用时索要依靠集成开发条件(IDE),常见的IDE有GCC(GNUC),Keil
MDK(A凯雷德MCC),IAR
EWA奥迪Q7M(ICCA奥迪Q5M),这几个IDE都有配套的C编写翻译器,这个编写翻译器是各有特色的,为了尽量显示各编写翻译器特色,配套的函数库便冒出。
  编写翻译器函数库是因IDE而异的,此处仅讲五个例证以供参考,供给驾驭越来越多需查看各IDE手册。
  以IAR
EWARM里的DLib_Product_string.h文件为例,该公文中重定义了memcpy的兑现:

  #define _DLIB_STRING_SKIP_INLINE_MEMCPY
  #pragma inline=forced_no_body
  __EFF_NENR1NW2R1 __ATTRIBUTES void * memcpy(void * _D, const void * _S, size_t _N)
  {
    __aeabi_memcpy(_D, _S, _N);
    return _D;
  }

第三类:Provided by ARM

  第一类公事由AKoleosM提供,嵌入式程序的执行靠的是控制器内核(此处指的内核就是A奥德赛M内核),AEvoqueM公司在筹划基本时,提供了某个内核模块的接口,开发者能够经过那些接口访问基本财富,CMSISheader里正是那些内核模块财富的接口。
3. CMSIS header
  完整的CMSISheader目录应该是上边那么些样子,而必要求尊敬的唯有\CMSIS\Include下面的core_cmx.h文件

\CMSIS
     \Core      
     \DAP            /* ARM debugger实现 */
     \Driver         /* ARM统一的常用外设driver API */
     \DSP_Lib        /* ARM优化实现的DSP Lib */
     \Include        /* ARM内核资源接口 */
            \arm_xx.h
            \cmsis_xx.h
            \core_cmx.h
     \Lib            /* ARM优化实现的标准Lib */
     \Pack
     \RTOS           /* ARM推出的RTOS- RTX */
     \RTOS2
     \SVD
     \Utilities

  core_cmx.h文件里定义了基本能源接口,里面最常用的三大模块是SCB,SysTick,NVIC,2个嵌入式开发的老资格看到那一个模块应该要向豹哥挥手示意,来,让豹哥看见你们的双臂~~~

第三类:Provided by ARM

  第3类公事由A昂CoraM提供,嵌入式程序的执行靠的是控制器内核(此处指的基石正是ARubiconM内核),A翼虎M公司在规划基本时,提供了有的内核模块的接口,开发者能够透过这几个接口访问基本财富,CMSISheader里正是这一个内核模块能源的接口。
3. CMSIS header
  完整的CMSISheader目录应该是上边那个样子,而必须求关爱的唯有\CMSIS\Include下面的core_cmx.h文件

\CMSIS
     \Core      
     \DAP            /* ARM debugger实现 */
     \Driver         /* ARM统一的常用外设driver API */
     \DSP_Lib        /* ARM优化实现的DSP Lib */
     \Include        /* ARM内核资源接口 */
            \arm_xx.h
            \cmsis_xx.h
            \core_cmx.h
     \Lib            /* ARM优化实现的标准Lib */
     \Pack
     \RTOS           /* ARM推出的RTOS- RTX */
     \RTOS2
     \SVD
     \Utilities

  core_cmx.h文件里定义了基础能源接口,里面最常用的叁大模块是SCB,SysTick,NVIC,二个嵌入式开发的好手看到那么些模块应该要向豹哥挥手示意,来,让豹哥看见你们的双手~~~

第四类:Provided by Chip Producer

  第伍类公事是由ALX570M芯片生产商提供,我们在选型三个ASportageM芯片时,除了看A索罗德M内核类型外,还得看芯片里面外设能源,是那些外设导致了ALANDM芯片差距,于是便有了各大AMuranoM厂商争奇斗艳,比如NXP(Freescale),
ST,
Microchip(Atmel),A宝马X5M厂商赋予了ARubiconM芯片各个外设财富,同时也会提供那一个外设财富的接口。
  该类型下文件有两种:
4.
device.h
:芯片头文件,首要涵盖中断号定义(xx_I大切诺基Qn)、外设模块类型定义(xx_Type)
、外设营地址定义(xx_BASE)。

/////////////////////////////////////////////////////
// 中断号定义
typedef enum IRQn {
  NotAvail_IRQn                = -128,
  /* Core interrupts */
  NonMaskableInt_IRQn          = -14,
  HardFault_IRQn               = -13,
  ...
  SysTick_IRQn                 = -1,
  /* Device specific interrupts */
  WDT0_IRQn                = 0,
  ...
} IRQn_Type;
////////////////////////////////////////////////////
// 外设寄存器定义
typedef struct {
  __IO uint32_t MOD;
  ...
  __IO uint32_t WINDOW;
} WWDT_Type;
#define WWDT_WINDOW_WINDOW_MASK       (0xFFFFFFU)
#define WWDT_WINDOW_WINDOW_SHIFT      (0U)
#define WWDT_WINDOW_WINDOW(x)         (((uint32_t)(((uint32_t)(x)) << WWDT_WINDOW_WINDOW_SHIFT)) & WWDT_WINDOW_WINDOW_MASK)
////////////////////////////////////////////////////
// 外设基地址定义
#define WWDT0_BASE                    (0x5000E000u)

5.
startup_device.s
:芯片中断向量表文件,首要包罗中断向量表定义(DCD
xx_Handler) ,以及各中断服务程序的弱定义(PUBWEAK)。
Note:该公文因编写翻译器而异。

;;基于IAR的startup_device.s文件
        MODULE  ?cstartup
        ;; Forward declaration of sections.
        SECTION CSTACK:DATA:NOROOT(3)
        SECTION .intvec:CODE:NOROOT(2)
        PUBLIC  __vector_table
        PUBLIC  __Vectors_End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 中断向量表定义
        DATA
__vector_table
        DCD     sfe(CSTACK)
        DCD     Reset_Handler
        DCD     NMI_Handler
        DCD     HardFault_Handler
        ...
        DCD     SysTick_Handler
        ; External Interrupts
        DCD     WDT0_IRQHandler
        ...
__Vectors_End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 中断服务程序弱定义
        THUMB
        PUBWEAK WDT0_IRQHandler
        PUBWEAK WDT0_DriverIRQHandler
        SECTION .text:CODE:REORDER:NOROOT(2)
WDT0_IRQHandler
        LDR     R0, =WDT0_DriverIRQHandler
        BX      R0
WDT0_DriverIRQHandler
        B .
        END

6.
system_device.c/h
:芯片系统开端化文件,主要包蕴全局变量SystemCoreClock定义(提供芯片内核默认工作频率)、SystemInit()函数定义(实现最大旨的类别初始化,比如WDOG初叶化,RAM使能等,那有的因芯片设计而异)。
7. device SDK Library:官方提供的芯片外设SDK
driver包文件,有了那些SDK包能够平昔使用片内外设设计本人的运用,而不必要查阅芯片手册里的外设模块寄存器去重写外设驱动。当然并不是每一个厂商都有周到的SDK包,那取决各厂商对软件服务的青眼程度。

// 来自于NXP SDK的WWDT driver API
void WWDT_GetDefaultConfig(wwdt_config_t *config);
void WWDT_Init(WWDT_Type *base, const wwdt_config_t *config);
void WWDT_Deinit(WWDT_Type *base);
void WWDT_ClearStatusFlags(WWDT_Type *base, uint32_t mask);
void WWDT_Refresh(WWDT_Type *base);

第四类:Provided by Chip Producer

  第6类公事是由AEvoqueM芯片生产商提供,我们在选型三个A福特ExplorerM芯片时,除了看A汉兰达M内核类型外,还得看芯片内部外设能源,是那一个外设导致了A福睿斯M芯片差距,于是便有了各大APAJEROM厂商争奇斗艳,比如NXP(Freescale),
ST,
Microchip(Atmel),A本田UR-VM厂商赋予了A奥迪Q5M芯片种种外设财富,同时也会提供那么些外设财富的接口。
  该品种下文件有各个:
4.
device.h
:芯片头文件,首要含有中断号定义(xx_I昂科拉Qn)、外设模块类型定义(xx_Type)
、外设集散地址定义(xx_BASE)。

/////////////////////////////////////////////////////
// 中断号定义
typedef enum IRQn {
  NotAvail_IRQn                = -128,
  /* Core interrupts */
  NonMaskableInt_IRQn          = -14,
  HardFault_IRQn               = -13,
  ...
  SysTick_IRQn                 = -1,
  /* Device specific interrupts */
  WDT0_IRQn                = 0,
  ...
} IRQn_Type;
////////////////////////////////////////////////////
// 外设寄存器定义
typedef struct {
  __IO uint32_t MOD;
  ...
  __IO uint32_t WINDOW;
} WWDT_Type;
#define WWDT_WINDOW_WINDOW_MASK       (0xFFFFFFU)
#define WWDT_WINDOW_WINDOW_SHIFT      (0U)
#define WWDT_WINDOW_WINDOW(x)         (((uint32_t)(((uint32_t)(x)) << WWDT_WINDOW_WINDOW_SHIFT)) & WWDT_WINDOW_WINDOW_MASK)
////////////////////////////////////////////////////
// 外设基地址定义
#define WWDT0_BASE                    (0x5000E000u)

5.
startup_device.s
:芯片中断向量表文件,首要涵盖中断向量表定义(DCD
xx_Handler) ,以及各中断服务程序的弱定义(PUBWEAK)。
Note:该文件因编写翻译器而异。

;;基于IAR的startup_device.s文件
        MODULE  ?cstartup
        ;; Forward declaration of sections.
        SECTION CSTACK:DATA:NOROOT(3)
        SECTION .intvec:CODE:NOROOT(2)
        PUBLIC  __vector_table
        PUBLIC  __Vectors_End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 中断向量表定义
        DATA
__vector_table
        DCD     sfe(CSTACK)
        DCD     Reset_Handler
        DCD     NMI_Handler
        DCD     HardFault_Handler
        ...
        DCD     SysTick_Handler
        ; External Interrupts
        DCD     WDT0_IRQHandler
        ...
__Vectors_End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 中断服务程序弱定义
        THUMB
        PUBWEAK WDT0_IRQHandler
        PUBWEAK WDT0_DriverIRQHandler
        SECTION .text:CODE:REORDER:NOROOT(2)
WDT0_IRQHandler
        LDR     R0, =WDT0_DriverIRQHandler
        BX      R0
WDT0_DriverIRQHandler
        B .
        END

6.
system_device.c/h
:芯片系统开始化文件,首要含有全局变量SystemCoreClock定义(提供芯片内核暗中同意工作频率)、SystemInit()函数定义(实现最大旨的系统起先化,比如WDOG开头化,RAM使能等,那有些因芯片设计而异)。
7. device SDK Library:官方提供的芯片外设SDK
driver包文件,有了那几个SDK包能够平昔使用片内外设设计协调的施用,而不必要查阅芯片手册里的外设模块寄存器去重写外设驱动。当然并不是各种厂商都有1揽子的SDK包,那取决于各厂商对软件服务的重视程度。

// 来自于NXP SDK的WWDT driver API
void WWDT_GetDefaultConfig(wwdt_config_t *config);
void WWDT_Init(WWDT_Type *base, const wwdt_config_t *config);
void WWDT_Deinit(WWDT_Type *base);
void WWDT_ClearStatusFlags(WWDT_Type *base, uint32_t mask);
void WWDT_Refresh(WWDT_Type *base);

第五类:Created by Developer

  第肆类公事是开发者本人创办,用于落到实处开发者本人的嵌入式应用,分为应用系统运营文件,应用体系开端化文件,应用文本。个中使用系统运营和早先化文件属于main函数从前的文件,一般能够通用,当先五成开发者并不关切其具体内容,可是精通其进度能够强化对嵌入式系统结构的知晓。
8. reset.s
应用种类复位运维文件,通晓AOdysseyM原理的都领会,image前几个字节数据分别是芯片上电的开首SP,
PC,个中PC指向的正是本文件里的Reset_Handler,那是芯片执行的第1个函数入口,该函数根本用以完成应用系统开端化工作,蕴涵应用中断向量表重定向、调用芯片系统初阶化、A奥德赛M系统寄存器rx清零、初步化应用程序各数据段、初步化A逍客M系统中断、跳转main函数。

// 一段经典的startup code
        SECTION .noinit : CODE
        THUMB
        import SystemInit
        import init_data_bss
        import main
        import CSTACK$$Limit
        import init_interrupts
        EXTERN __vector_table
        REQUIRE __vector_table
#define SCB_BASE            (0xE000ED00)
#define SCB_VTOR_OFFSET     (0x00000008)
        PUBLIC  Reset_Handler
        EXPORT  Reset_Handler
Reset_Handler
        // Mask interrupts
        cpsid   i
        // Set VTOR register in SCB first thing we do.
        ldr     r0,=__vector_table
        ldr     r1,=SCB_BASE
        str     r0,[r1, #SCB_VTOR_OFFSET]
        // Init the rest of the registers
        ldr     r2,=0
        ldr     r3,=0
        ldr     r4,=0
        ldr     r5,=0
        ldr     r6,=0
        ldr     r7,=0
        mov     r8,r7
        mov     r9,r7
        mov     r10,r7
        mov     r11,r7
        mov     r12,r7
        // Initialize the stack pointer
        ldr     r0,=CSTACK$$Limit
        mov     r13,r0
        // Call the CMSIS system init routine
        ldr     r0,=SystemInit
        blx     r0
        // Init .data and .bss sections
        ldr     r0,=init_data_bss
        blx     r0
        // Init interrupts
        ldr     r0,=init_interrupts
        blx     r0
        // Unmask interrupts
        cpsie   i
        // Set argc and argv to NULL before calling main().
        ldr     r0,=0
        ldr     r1,=0
        ldr     r2,=main
        blx     r2
__done
        B       __done
        END

9.
startup.c
:应用连串开始化文件,该文件里根本包括多个开头化函数,init_data_bss()、
init_interrupts(),data,
bss段数据的开头化是为着有限支撑嵌入式系统中有着全局变量能有贰个开发者钦赐的初值。由于data,bss段的岗位是在链接阶段显明的,所以这边须求相称linker文件才能找到科学的data,bss地点,linker文件是因IDE而异的,全数本文件要想做到通用,必须扩展各IDE条件编写翻译,此处仅以IA大切诺基下的贯彻为例:

//基于IAR的startup.c文件
#if (defined(__ICCARM__))
#pragma section = ".intvec"
#pragma section = ".data"
#pragma section = ".data_init"
#pragma section = ".bss"
#pragma section = "CodeRelocate"
#pragma section = "CodeRelocateRam"
#endif

void init_data_bss(void)
{
#if defined(__ICCARM__)
    uint8_t *data_ram, *data_rom, *data_rom_end;
    uint8_t *bss_start, *bss_end;
    uint8_t *code_relocate_ram, *code_relocate, *code_relocate_end;
    uint32_t n;
// 初始化data段 .data section (initialized data section)
    data_ram = __section_begin(".data");
    data_rom = __section_begin(".data_init");
    data_rom_end = __section_end(".data_init");
    n = data_rom_end - data_rom;
    if (data_ram != data_rom)
    {
        while (n--)
        {
            *data_ram++ = *data_rom++;
        }
    }
// 初始化bss段 .bss section (zero-initialized data)
    bss_start = __section_begin(".bss");
    bss_end = __section_end(".bss");
    n = bss_end - bss_start;
    while (n--)
    {
        *bss_start++ = 0;
    }
// 初始化CodeRelocate段 (执行在RAM中的函数(由IAR指定的__ramfunc修饰的函数)).
    code_relocate_ram = __section_begin("CodeRelocateRam");
    code_relocate = __section_begin("CodeRelocate");
    code_relocate_end = __section_end("CodeRelocate");
    n = code_relocate_end - code_relocate;
    while (n--)
    {
        *code_relocate_ram++ = *code_relocate++;
    }
#endif
}

void init_interrupts(void)
{
    NVIC_ClearEnabledIRQs();
    NVIC_ClearAllPendingIRQs();
}

10. application.c/h
应用文本,此处正是主函数以及各职能函数的聚众了,嵌入式老车手们,请发轫你的演出~~~

void taskn(void)
{
    ...
}
int main(void)
{
    printf("hello world\r\n");
    taskn();
    ...
    return 0;
}

  至此,嵌入式开发里的各个来源的source文件豹哥便介绍完结了,掌声在哪儿~~~

第五类:Created by Developer

  第肆类公事是开发者自个儿创设,用于落实开发者自身的嵌入式应用,分为应用系统运行文件,应用系统开头化文件,应用文本。个中使用系统运行和伊始化文件属于main函数以前的文件,一般能够通用,当先四分一开发者并不关心其具体内容,可是精晓其经过能够强化对嵌入式系统结构的明白。
8. reset.s
应用系统复位运维文件,掌握AKoleosM原理的都理解,image前几个字节数据分别是芯片上电的初步SP,
PC,在那之中PC指向的正是本文件里的Reset_Handler,那是芯片执行的第六个函数入口,该函数根本用以完结应用类别起始化学工业作,包涵应用中断向量表重定向、调用芯片系统开始化、A哈弗M系统寄存器rx清零、早先化应用程序各数据段、初阶化AENVISIONM系统暂停、跳转main函数。

// 一段经典的startup code
        SECTION .noinit : CODE
        THUMB
        import SystemInit
        import init_data_bss
        import main
        import CSTACK$$Limit
        import init_interrupts
        EXTERN __vector_table
        REQUIRE __vector_table
#define SCB_BASE            (0xE000ED00)
#define SCB_VTOR_OFFSET     (0x00000008)
        PUBLIC  Reset_Handler
        EXPORT  Reset_Handler
Reset_Handler
        // Mask interrupts
        cpsid   i
        // Set VTOR register in SCB first thing we do.
        ldr     r0,=__vector_table
        ldr     r1,=SCB_BASE
        str     r0,[r1, #SCB_VTOR_OFFSET]
        // Init the rest of the registers
        ldr     r2,=0
        ldr     r3,=0
        ldr     r4,=0
        ldr     r5,=0
        ldr     r6,=0
        ldr     r7,=0
        mov     r8,r7
        mov     r9,r7
        mov     r10,r7
        mov     r11,r7
        mov     r12,r7
        // Initialize the stack pointer
        ldr     r0,=CSTACK$$Limit
        mov     r13,r0
        // Call the CMSIS system init routine
        ldr     r0,=SystemInit
        blx     r0
        // Init .data and .bss sections
        ldr     r0,=init_data_bss
        blx     r0
        // Init interrupts
        ldr     r0,=init_interrupts
        blx     r0
        // Unmask interrupts
        cpsie   i
        // Set argc and argv to NULL before calling main().
        ldr     r0,=0
        ldr     r1,=0
        ldr     r2,=main
        blx     r2
__done
        B       __done
        END

9.
startup.c
:应用系统初步化文件,该公文里主要蕴涵多个初阶化函数,init_data_bss()、
init_interrupts(),data,
bss段数据的起初化是为了保证嵌入式系统中享有全局变量能有2个开发者钦点的初值。由于data,bss段的地点是在链接阶段明确的,所以这里需求般配linker文件才能找到科学的data,bss地方,linker文件是因IDE而异的,全部本文件要想做到通用,必须扩充各IDE条件编写翻译,此处仅以IAKoleos下的兑现为例:

//基于IAR的startup.c文件
#if (defined(__ICCARM__))
#pragma section = ".intvec"
#pragma section = ".data"
#pragma section = ".data_init"
#pragma section = ".bss"
#pragma section = "CodeRelocate"
#pragma section = "CodeRelocateRam"
#endif

void init_data_bss(void)
{
#if defined(__ICCARM__)
    uint8_t *data_ram, *data_rom, *data_rom_end;
    uint8_t *bss_start, *bss_end;
    uint8_t *code_relocate_ram, *code_relocate, *code_relocate_end;
    uint32_t n;
// 初始化data段 .data section (initialized data section)
    data_ram = __section_begin(".data");
    data_rom = __section_begin(".data_init");
    data_rom_end = __section_end(".data_init");
    n = data_rom_end - data_rom;
    if (data_ram != data_rom)
    {
        while (n--)
        {
            *data_ram++ = *data_rom++;
        }
    }
// 初始化bss段 .bss section (zero-initialized data)
    bss_start = __section_begin(".bss");
    bss_end = __section_end(".bss");
    n = bss_end - bss_start;
    while (n--)
    {
        *bss_start++ = 0;
    }
// 初始化CodeRelocate段 (执行在RAM中的函数(由IAR指定的__ramfunc修饰的函数)).
    code_relocate_ram = __section_begin("CodeRelocateRam");
    code_relocate = __section_begin("CodeRelocate");
    code_relocate_end = __section_end("CodeRelocate");
    n = code_relocate_end - code_relocate;
    while (n--)
    {
        *code_relocate_ram++ = *code_relocate++;
    }
#endif
}

void init_interrupts(void)
{
    NVIC_ClearEnabledIRQs();
    NVIC_ClearAllPendingIRQs();
}

10. application.c/h
应用文本,此处正是主函数以及各职能函数的聚集了,嵌入式老车手们,请开首你的演艺~葡萄娱乐官方,~~

void taskn(void)
{
    ...
}
int main(void)
{
    printf("hello world\r\n");
    taskn();
    ...
    return 0;
}

  至此,嵌入式开发里的各种来源的source文件豹哥便介绍完成了,掌声在什么地方~~~