【瘟疫公司 进化】今天豹哥给大家讲的是。 无人不晓,嵌入式开垦归属偏底层的开支,首要编制程序语言是C和汇编。所以本文要讲的source文件根本指的正是c文件和汇编文件。
固然在平常开荒中,大家都只会关注自个儿创设的.c/.h/.s源文件,但实在我们万籁无声中也跟比超级多不是大家创立的源文件在社交,那么难题来了,贰个完整的嵌入式工程(以基于ARM
Cortex-M调控器的工程为例卡塔 尔(阿拉伯语:قطر到底会含有哪些source文件呢?
今后就到了豹哥的show
time了,豹哥将那几个文件按来源分为五类十种,上边豹哥按项目逐个解析那几个文件:
第五类:Created by Developer
第五类公事是开采者本人创设,用于贯彻开垦者本身的嵌入式应用,分为应用系统运行文件,应用系统早先化文件,应用文本。个中使用系统运营和最早化文件归属main函数早前的文本,平常能够通用,超越四分之二开采者并不关怀其具体内容,然而领悟其经过能够有加无己对嵌入式系统构造的接头。
8. reset.s:
应用系统重新初始化运行文件,精通ARM原理的都知情,image前8个字节数据分别是微芯片上电的发轫SP,
PC,个中PC指向的正是本文件里的Reset_Handler,那是集成电路履行的率先个函数入口,该函数根本用来完成应用连串开首化职业,满含应用中断向量表重定向、调用集成电路系统初叶化、ARM系统寄放器rx清零、初步化应用程序各数据段、伊始化ARM系统暂停、跳转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条件编译,此处仅以IAGL450下的落实为例:
//基于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 worldrn");
taskn();
...
return 0;
}
至此,嵌入式开拓里的各个来源的source文件豹哥便介绍完结了,掌声在哪个地方~~【瘟疫公司 进化】今天豹哥给大家讲的是。~
第二类:Provided by IDE(Compiler)
第二类公事由IDE提供,C语言是编写翻译型语言,供给编写翻译器将C程序汇编成机器码,全体便有了有些跟编写翻译器天性相关的函数库。
2. Compiler Library
大家在付出嵌入式应用时索要依附集成开辟条件(IDE卡塔 尔(阿拉伯语:قطر,不感觉奇的IDE有GCC(GNUC),Keil
MDK(ARMCC),IAR
EWARM(ICCARM),那么些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;
}
大家好,小编是豹哥,猎豹的豹,犀利哥的哥。今日豹哥给大家讲的是嵌入式开拓里的source文件。
第三类:Provided by ARM
第三类公事由ARM提供,嵌入式程序的实施靠的是调整器内核(此处指的基业就是ARM内核卡塔 尔(英语:State of Qatar),ARM公司在设计基本时,提供了一些内核模块的接口,开拓者能够经过那么些接口访谈基本能源,CMSISheader里正是那几个内核模块财富的接口。
3. CMSIS header
完整的CMSISheader目录应该是底下这么些样子,而必供给关爱的独有CMSISInclude下面的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 Committee
第风华正茂类公事由C规范委员会提供,该类文件伴随着规范的发表而逐级扩张。该类文件重视正是生龙活虎种,即C规范库。
1. C standard Library
我们都了然C语言是有正规的,管见所及的C标准有ANSI
C(C89卡塔 尔(阿拉伯语:قطر、C99、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 Chip Producer
第四类公事是由ARM微电路临盆商提供,大家在选型二个ARM微芯片时,除了看ARM内核类型外,还得看集成电路内部外设资源,是那个外设招致了ARM微电路差距,于是便有了各大ARM商家争妍视若无睹艳,比方NXP(Freescale),
ST,
Microchip(Atmel),ARM厂家付与了ARM微电路各样外设能源,同临时候也会提供这一个外设财富的接口。
该品种下文件有各种:
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使能等,那有个别因微芯片设计而异卡塔 尔(英语:State of Qatar)。
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);
本文由美高梅游戏官网娱乐发布,转载请注明来源
关键词: