在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

從文件角度了解Cortex-M開發(1)

電子設計 ? 來源:電子設計 ? 作者:電子設計 ? 2020-10-30 10:44 ? 次閱讀

今天痞子衡給大家講的是嵌入式開發里的 source 文件。


眾所周知,嵌入式開發屬于偏底層的開發,主要編程語言是 C 和匯編。所以本文要講的 source 文件主要指的就是 c 文件和匯編文件。


盡管在平常開發中,我們都只會關注自己創建的 .c/.h/.s 源文件,但實際上我們不知不覺中也跟很多不是我們創建的源文件在打交道,那么問題來了,一個完整的嵌入式工程(以基于 ARM Cortex-M 控制器的工程為例)到底會包含哪些 source 文件呢?


現在就到了痞子衡的 show time 了,痞子衡將這些文件按來源分為五類十種,下面痞子衡按類別逐一分析這些文件:


第一類:Provided by Committee
第一類文件由 C 標準委員會提供,該類文件伴隨著標準的發布而逐漸壯大。該類文件主要就是一種,即 C 標準庫。


1. C standard Library

大家都知道 C 語言是有標準的,常見的 C 標準有 ANSI C(C89)、C99、C11,而 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)

第二類文件由 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;


}


第三類:Provided by ARM

第三類文件由 ARM 提供,嵌入式程序的執行靠的是控制器內核(此處指的內核便是 ARM 內核),ARM 公司在設計內核時,提供了一些內核模塊的接口,開發者可以通過這些接口訪問內核資源,CMSIS header 里就是這些內核模塊資源的接口。


3. CMSIS header
完整的 CMSIS header 目錄應該是下面這個樣子,而必須要關注的只有 /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


第四類文件是由 ARM 芯片生產商提供,我們在選型一個 ARM 芯片時,除了看 ARM 內核類型外,還得看芯片內部外設資源,是這些外設導致了 ARM 芯片差異,于是便有了各大 ARM 廠商爭奇斗艷,比如 NXP(Freescale), ST, Microchip(Atmel),ARM 廠商賦予了 ARM 芯片各種外設資源,同時也會提供這些外設資源的接口。該類別下文件有四種:


4. device.h:芯片頭文件,主要包含中斷號定義(xx_IRQn)、外設模塊類型定義(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);


第五類: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 條件編譯,此處僅以 IAR 下的實現為例:


// 基于 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)


{


// Your task code


}


int main(void)


{


printf("hello world/r/n");


taskn();


...


return 0;


}


至此,嵌入式開發里的各種來源的 source 文件痞子衡便介紹完畢了,掌聲在哪里~~~

審核編輯 黃昊宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Cortex-M
    +關注

    關注

    2

    文章

    229

    瀏覽量

    30179
收藏 人收藏

    評論

    相關推薦
    熱點推薦

    幾個角度了解音頻功放和掌握相關產品

    1. 基本原理與分類 基本原理: 音頻功放的工作原理基于電子電路設計,主要功能是放大來自音源設備(如CD播放器、手機等)的電信號,使其能夠推動揚聲器發聲。放大過程需要保持信號的完整性和保真度,以確保
    的頭像 發表于 04-18 14:45 ?116次閱讀
    <b class='flag-5'>從</b>幾個<b class='flag-5'>角度了解</b>音頻功放和掌握相關產品

    i.MX8MMini中的Cortex-M4不支持SDIO嗎?

    的 FreeRTOS,我們 NXP 論壇獲取了信息,并正在努力為 RTOS 構建環境 我們注意到,在構建完成后移植無線驅動程序時。 RTOS 的當前源代碼不包括 SDIO 驅動程序。 i.MX8MMini 中的 Cortex-M4 不支持 SDIO 嗎? 如果支持,您能
    發表于 04-03 06:45

    瑞薩RA8快速上手指南:Cortex-M85內核瑞薩RA8開發環境搭建 并點亮一個LED

    因為Cortex-M內核,瑞薩RA8系列單片機支持多種市面上常見的開發環境,像Keil MDK、IAR EWARM等,而本文講述的是瑞薩自家官方的IDE(e2 studio)。
    的頭像 發表于 03-17 14:35 ?707次閱讀
    瑞薩RA8快速上手指南:<b class='flag-5'>Cortex-M</b>85內核瑞薩RA8<b class='flag-5'>開發</b>環境搭建 并點亮一個LED

    【瑞薩RA2L1入門學習】+Uart printf

    開發板 RA-Eco-RA2L1-48PIN-V1.0是一款基于48 MHz Arm? Cortex?-M23 內核架構的核心板,主控芯片為R7FA2L
    發表于 03-09 17:33

    【瑞薩RA2L1入門學習】+Key control LED

    開發板 RA-Eco-RA2L1-48PIN-V1.0是一款基于48 MHz Arm? Cortex?-M23 內核架構的核心板,主控芯片為R7FA2L
    發表于 03-09 17:21

    【瑞薩RA2L1入門學習】+Led flash

    開發板 RA-Eco-RA2L1-48PIN-V1.0是一款基于48 MHz Arm? Cortex?-M23 內核架構的核心板,主控芯片為R7FA2L
    發表于 03-09 17:12

    【瑞薩RA2L1入門學習】00. 開箱 + 點燈

    【開箱】 開發板外觀展示 主控介紹 RA-Eco-RA2L1-48PIN-V1.0開發板使用主控芯片為 R7FA2L1AB2DFL。 基于48 MHz Arm?
    發表于 03-07 11:07

    Arm Cortex-A320 CPU助力嵌入式設備實現高能效AI計算

    ,要確定適合特定 AI 應用的處理器,系統開發者需要通過比較基于 Arm Cortex-A、Arm Cortex-M 和 Arm Ethos-U NPU 的設備及其可能的搭配進行決策。除了成本的考量,
    的頭像 發表于 02-27 17:17 ?611次閱讀
    Arm <b class='flag-5'>Cortex</b>-A320 CPU助力嵌入式設備實現高能效AI計算

    如何使用Ozone分析Cortex-M異常

    Ozone可以幫助用戶快速分析和查找導致CPU故障的軟件bug。本文解釋如何使用Ozone的調試功能,深入了解Cortex-M架構上的這些錯誤。
    的頭像 發表于 11-29 11:14 ?1412次閱讀
    如何使用Ozone分析<b class='flag-5'>Cortex-M</b>異常

    度了解SiC的晶體結構

    SiC是由硅(Si)和碳(C)按1:1的化學計量比組成的晶體,因其內部結構堆積順序的不同,形成不同的SiC多型體,本篇章帶你了解SiC的晶體結構及其可能存在的晶體缺陷。
    的頭像 發表于 11-14 14:57 ?2939次閱讀
    深<b class='flag-5'>度了解</b>SiC的晶體結構

    【RA-Eco-RA2E1-48PIN-V1.0開發板試用】RA-Eco-RA2E1-48PIN-V1.0開發板基于Keil MDK環境搭建

    與 RA2L1 產品群引腳和外圍設備兼容,特別適用于電池供電應用以及空間受限應用,以及其他需要高性能和低功耗的系統。 RA2L1 基于 ARM? Cortex?-M23 核心(現今 A
    發表于 11-04 22:58

    【RA-Eco-RA2E1-48PIN-V1.0開發板試用】帶你認識RA-Eco-RA2E1-48PIN-V1.0開發

    RA-Eco-RA2E1-48PIN-V1.0是一款基于48 MHz Arm? Cortex?-M23 內核架構的開發板,板載2個觸摸按鍵,1
    發表于 11-04 22:53

    基于瑞薩Arm Cortex-M85 MCU Feather SOM的解決方案

    開源社區已經傳統的黑客聚集地逐漸擴展到家庭、辦公室以及工業應用等廣泛領域。在這個過程中,瑞薩的Arm Cortex-M85 MCU Feather SOM憑借著卓越的性能和豐富的功能,為開源硬件愛好者和專業開發者提供了強大的支
    的頭像 發表于 08-19 17:32 ?732次閱讀

    樹莓派Pico 2發布,搭載RP2350雙核RISC-V和Arm Cortex-M33微控制器!

    復雜得多的設計,具有: – 兩個 150MHz Arm Cortex-M33 內核,支持浮點和 DSP – 內置 520KB SRAM – 圍繞 Arm TrustZone for Cortex-M
    發表于 08-13 10:07

    使用Keil uVision對TLE9893_2QK Evalkit進行編程,顯示\"未找到Cortex-M SW設備\",為什么?

    我正在使用 Keil uVision 對 TLE9893_2QK Evalkit 進行編程。 當我嘗試調試時,得到以下錯誤信息。 我還收到一個窗口,顯示\"未找到 Cortex-M SW
    發表于 06-03 08:10
    主站蜘蛛池模板: 狠狠色狠狠色狠狠五月ady | 精品视频网站 | 欧美日韩国产乱了伦 | 日本人的色道www免费一区 | 女生张开腿让男人桶 | 欧美一级艳片视频免费观看 | 四虎免费影院4hu永久免费 | 一级一级毛片免费播放 | 男女交性高清视频无遮挡 | 亚洲影院手机版777点击进入影院 | 国产精品9999久久久久仙踪林 | 五月婷婷在线观看视频 | 欧美性性性性性ⅹxxbbbb | 婷婷激情亚洲 | 日本黄色xxxx | 美女被羞羞产奶视频网站 | 手机毛片 | 三级黄色片免费观看 | 777奇米四色米奇影院在线播放 | 色综合天天综合网国产成人 | 嫩草网 | 色婷婷久久免费网站 | 色综合色狠狠天天综合色hd | 3p性小说 | 中文字幕在线观看一区二区三区 | 国产网站大全 | 亚洲精品老司机综合影院 | 天天操夜操| 黄篇网站在线观看 | 欧美成人高清性色生活 | 男男之h啪肉np文 | 2019偷偷狠狠的日日 | a级毛片网 | 国产色爽女| 欧美黄页 | 午夜视频国语 | 国产精品国产三级国产在线观看 | 男男污肉高h坐便器调教 | 午夜男人影院 | 色综合欧美综合天天综合 | 亚洲综合图片人成综合网 |