豹哥分别给大家介绍了嵌入式开荒中的三种规范input文件


  我们好,笔者是豹哥,猎豹的豹,犀利哥的哥。几近来豹哥给大家讲的是嵌入式开拓里的project文件

  前边两节课里,豹哥分别给大家介绍了嵌入式开荒中的二种标准input文件:source文件linker文件。豹哥要再一次提问了,还大概有没有input文件呢?答案真的是有,但此次真的是有且独有了,本文要介绍的顶梁柱project文件也归于半个input文件。为啥说是半个?因为project文件不但包括开荒者钦赐的input消息,还包含众多任何协理调节和测量检验的input/output音讯,算是嵌入式开垦中承上启下的文书。而本文侧器重在于project文件中与开垦者应用相关的input音讯,仅当拿到了那一个input消息,再加上前边介绍的source和linker文件,那么你就早就取得了application全数的音讯,你能够用它们来能够生成无歧义的可进行image
binary。
  随着嵌入式软件工程的前行,为了酬答日益复杂的须要,现代IDE的职能也尤为强盛了,IDE版本轮番令人接应不暇,Keil
MDK已然步入5.0不经常,IAR
EWARM更是步入了8.0一代,IDE连镳并轸,但本文要讲的内容却是各个IDE必需具备的基本成效,依然三番五次以IAR
EWARM为例开始今天的剧情:

一、标准IDE功能

  在开头明天的宗旨早先,豹哥以为有必不可缺先简要给大家广泛一下正规IDE应该具备的功效。今世IDE基本都以由组件构成,嵌入式开拓中的每种阶段都对应着相应的零件,由这么些组件去得以完成各品级的要求。

1.1 IDE组件

  规范嵌入式开采相应最少满含以下6个级次,而IATiggo里对于每一个阶段都有1个或多少个构件:

  • 输入(IA奇骏 Editor卡塔尔:编辑源文件代码。
  • 编写翻译(ICCARM、IASMARM卡塔 尔(英语:State of Qatar):编写翻译源文件代码生成可实践二进制机器码。
  • 浅析(C-STAT、MISRA-C卡塔 尔(英语:State of Qatar):编译进度中反省代码中潜在的标题。
  • 链接(ILINK卡塔 尔(阿拉伯语:قطر‎:链接可进行二进制机器码到内定ARM存款和储蓄空间地址。
  • 下载(I-jet、flashloader卡塔尔:将链接好的可推行二进制机器码下载进微芯片内部非易失性存款和储蓄器。
  • 调治将养(C-SPY、C-RUN卡塔尔国:在线调试代码在集成电路中施行意况。

  project文件根本用来记录整合上述6个阶段的具备支付要求。

1.2 IDE文件类型

  既然IDE有大多组件,那么与此同一时候也会设有不相同门类的文件以存款和储蓄那个零器件的所急需的音讯。IA凯雷德里帮衬的文书扩充类型比非常多,豹哥在那间仅列举你所成立的工程根目录下的与工程同名的强盛文件,相信你势必会认为熟练。

.eww           // Workspace file
.ewp           // IAR Embedded Workbench project
.ewd           // Project settings for C-SPY
.ewt           // Project settings for C-STAT and C-RUN</td>
.dep           // Dependency information

  本文要讲的剧情都含有在.ewp文件里,ewp文件记录了开垦者为使用钦定的不得缺点和失误的input音讯,未有这几个讯息,application工程是残破的。换句话说,借使您获得了application的具备source文件和linker文件,但尚无ewp文件的话,可能招致最后生成的image
binary文件是莫衷一是的。

Note:愈来愈多IA凯雷德帮助的恢弘文件类型请查阅IA奇骏软件安装目录下\IAR
Systems\Embedded Workbench
xxx\arm\doc\EWARM_IDEGuide.ENU.pdf文书档案里的File types风度翩翩节。

二、解析project(ewp)文件

  前边豹哥铺垫了众多IDE/project幼功概念,该是直接奔着大旨的时候了,本文主演ewp工程文件到底满含哪些开采者钦赐的input音信?豹哥从下面3个方面为大家报料:

2.1 源文件组织

  叁个稍微复杂一点的嵌入式工程,应用代码行数应该是以百行/千行为单位测算的(此处仅指的是由开采者自身创办的文本与代码卡塔尔国,大家在公司代码的时候一定不会只创设一个.c文件,单文件会招致代码功效模块结构不清晰,不实惠工程的保管与保卫安全。
  当大家为工程成立多少个文本时,就能够波及到叁个自然难点:引用路径难题(所以路线音信就是本文要说的首先个input新闻卡塔 尔(阿拉伯语:قطر‎。当源文件数量超级多时,常常大家会创制差别文件夹把相通效果的源文件都位居一同,当编写翻译器以前编写翻译.c源文件时会寻觅include语句所包罗的头文件。熟习C语言的意中人料定晓得下边二种不相同include语句的用法:

#include <file.h>           // 引用编译器类库下的头文件(IDE安装路径)
#include "file.h"           // 引用当前工程下的头文件(project路径)

  所以在ewp文件里会含有路线消息,全体路子都应有列在Options->C/C++
Compiler->Preprocessor下有Additional include
directories里,这几个渠道不只能够是当下PC的相对路线,也得以是以ewp文件为尺度的相对路线,为了确认保障工程得以在随便PC大几个人置下正规编写翻译,推荐应用如下相对路线方式列出富有路子:

ewp当前路径:$PROJ_DIR$/
ewp下级路径:$PROJ_DIR$/xxFolder/
ewp上级路径:$PROJ_DIR$/../

  聊到路线难点,豹哥在此顺便给大家介绍风华正茂种精髓的嵌入式工程文件目录协会章程:

\projectDir
           \doc                            --放置工程文档

           \bsp                            --放置bsp(板级)相关的source file
                  \linker                    --工程linker文件
                  \src                       --板级相关的源文件(比如pinout,clock等)
                  \builds\xxBuild\.ewp       --工程ewp文件
                  .eww                       --工程workspace文件

           \src                            --放置bsp无关的source file
                  \platform                  --芯片头文件及CMSIS文件
                  \drivers                   --芯片片内外设driver
                  \include                   --要被所有source引用的头文件
                  \startup                   --标准的startup code
                  \utilities                 --标准的通用函数
                  \middleware                --独立的中间件
                  \components                --板级外设组件driver
                  \application               --当前应用主逻辑代码

2.2 全局宏定义

  平日应用法规编写翻译的意中人肯定晓得workspace文件与project文件的涉嫌,三个类型常常只会有三个eww文件,但却大概会有多个ewp文件,那是因为源代码里时不经常会有规范化编译,咱们偶然会给项目分化的布署进而编写翻译出不相同的结果(速度优先/面积优先,性情调整…卡塔尔国,那么些布署正是由全局宏定义来落成的,张开Options->C/C++
Compiler->Preprocessor下的Defined
symbols,在框内写入你供给定义的大局宏:

MACRO1            // 等价于源文件里的#define MACRO1 (1)
MACRO2=2          // 等价于源文件里的#define MACRO2 (2)

  全局宏新闻正是本文要说的首个input音信,如若全局宏音讯错过,不常候工程编写翻译并不会报错,因为编写翻译器在管理如下遍布用法里的原则编写翻译语句时会暗中认可未定义的宏为0,而在拍卖推荐用法里的尺码编写翻译语句则会报错,所以推举大家使用第两种标准编写翻译用法来躲藏全局宏难点。

// 普遍用法
#if MACRO
    // your code block 1
#else
    // your code block 2
#endif

// 推荐用法
#if !defined(MACRO)
    #error "No valid MACRO defined!"
#elif (MACRO == 1)
    // your code block 1
#else
    // your code block 2
#endif

2.3 编写翻译选项

  编写翻译选项包蕴了编写翻译器所供给的有着音信,代码需经过编译器编写翻译本事生成二进制机器码,分化的编写翻译器选项配置会生成分裂的机器码,那么需求钦命哪些选项呢?张开project的Options选项卡,分别安装下表item:

Position

Item

Description

General Options->Target->

Processor variant->Core

钦定ARM内核版本

Endian mode

钦命内核大小端情势

Floating point settings->FPU

钦赐内核扶持的FPU版本

General Options->Library Configuration->

Library

分选C/C++动态链接库版本

General Options->Library Option 2->

Heap selection

选料HEAP实现版本

C/C++ Compiler->

Language 1->Language

内定编制程序语言类型

Language 1->C dialect

内定C语言标准

Language 1->Language conformance

选料对标准C/C++的遵照程度

Language 2->Plain ‘char’ is

选择对char的符号性默许管理方法

Language 2->Floating-point semantics

慎选对浮点数的拍卖信守C规范的等级次序

Code->Process mode

点名内核指令集格局

Code->Position-independence

选取要转移地点毫无干系代码的对象

Optimizations->Level

选料优化等第

Note:愈来愈多ewp文件中option解释请查阅IAPRADO软件安装目录下\IAR
Systems\Embedded Workbench
xxx\arm\doc\EWARM_IDEGuide.ENU.pdf文书档案里的General
Options和Compiler Options俩小节。

  编写翻译设置消息正是本文要说的第三个input音信,当在project中组织好源文件并设置好精确的大局宏定义和编写翻译选项,那么恭喜你,你的application设计专门的职业后生可畏度基本做到了。

三、创建demo工程

  为便于后续课程的展开,本节课在结尾顺便创制一个demo工程,以下是demo工程的新闻:

IDE:        IAR EWARM v8.11.2
Device:     NXP MKL25Z128VLH4
project layout:   
    \D\myProject\bsp\builds\demo\demo.ewp
    \D\myProject\bsp\linker\iar\KL25Z128xxx4_flash.icf
    \D\myProject\bsp\src\startup_MKL25Z4.s   (仅保留前16个系统中断)
    \D\myProject\bsp\src\system_MKL25Z4.c   (仅做关闭WDOG操作)
    \D\myProject\bsp\src\system_MKL25Z4.h
    \D\myProject\bsp\helloArm.eww
    \D\myProject\src\platfrom\CMSIS
    \D\myProject\src\platfrom\devices\MKL25Z4
    \D\myProject\src\startup\reset.s
    \D\myProject\src\startup\startup.c
    \D\myProject\src\startup\startup.h
    \D\myProject\src\application\main.c
    \D\myProject\src\application\task.c
    \D\myProject\src\application\task.h

// main.c
//////////////////////////////////////////////////////////
#include "task.h"
const uint32_t s_constant = 0x7f;
int main(void)
{
    uint32_t l_variable = 0x7f;
    if (s_constant == l_variable)
    {
        normal_task();
        ram_task();
        heap_task();
    }
    while (1);
}

// task.c
//////////////////////////////////////////////////////////
#include "task.h"
static    uint32_t s_variable0;
__no_init uint32_t n_variable1;
static    uint32_t s_variable2 = 0x5a;
static uint8_t s_array[16];
void normal_task(void)
{
    s_variable0 *= 2;
}
__ramfunc void ram_task(void)
{
    n_variable1++;
}
void heap_task(void)
{
    uint8_t *heap = (uint8_t *)malloc(16 * sizeof(uint8_t));
    if (heap != NULL)
    {
        memset(heap, 0xa5+s_variable2, 16);
        memcpy(s_array, heap, 16);
        s_variable0 = (uint32_t)heap;
        free(heap);
    }
}

番外大器晚成、多少个小技艺

  又过来豹哥番外时间了,留意的意中人看出上表有两处标蓝,是的不利,前日的番外内容便是标蓝的类型有关。

技艺1:运营于异构双核

  近年来嵌入式产物越发复杂,对MCU的性质须求也尤为高,各大ARM厂商也在相连推出品质更是强盛的ARM
MCU成品,异常高主频,双核,四核MCU已经不鲜见了。对于里边的风度翩翩部分异构双核MCU产物,一时在开荒中会有那般的供给:你有生机勃勃份的middleware会被异构双核同期调用,而五个差别基本功的命令集有望是不雷同的,怎么消除那一个难点?有朋友会想到分别在种种核上面都编写翻译风流浪漫份binary停放于存款和储蓄器不相同职责,运转时分别指向对应的binary,那是一个主意,但比较浪费存款和储蓄空间,且有希望会搞混淆引致误调用。有未有越来越好的情势?
  为了能实现Cortex-M软件重用,ARM集团在布署Cortex-M微型机时为其授予了计算机向下宽容软件二进制向上包容特色。通俗的话来讲正是在相当低版本微处理机上编写翻译的代码能够在较高版本微型机上推行。所以解决措施就是采纳异构双核里比较低版本的基业在编写翻译middleware,那样这份middleware能够同期被七个核调用。

技巧2:生成PIC代码

  平常和bootloader打交道的仇敌一定晓得,代码在经过链接阶段生成binary文件后,这么些binary实际不是能够投身大几人置的,必得置于linker文件钦点的职责,假设地方未有放正确,大概会引致实行出错。究其原因,是因为编写翻译器在汇编源代码时因为有的国策并不再三再四将具有function都汇编成地点非亲非故代码。若是大家赖以IDE编写翻译选项将middleware汇编成PIC代码,那么大家可以在工程中一向参加middleware的binary,然后依靠linker的自定义section功效将其放置于自由有些地方,最终只要为那些middleware
binary创立一个以binary首地址为标准的函数指针地址列表就可以无障碍调用这么些middleware。

技巧3:引用.c文件

  在项目支出中,我们在多个workspace下会创制七个project,平时是因为差异project需求包涵不一样的.c文件以变成区别的职能。那么能还是无法只开创叁个project呢能兑现分裂功效吗?当然可以!经常景况下我们在.c文件中只会用#include
“xx.h”语句来引用.h头文件,其实大家也如出生龙活虎辙可以援用.c文件,比方这样#include
“xx.c”,只是必要小心尽量不要在.h文件中引用.c文件(除非该.h只会被一个.c文件include卡塔 尔(阿拉伯语:قطر‎。见到这里的仇敌若是脑洞再大学一年级些,你居然足以形成工程里只要求加上一个.c文件,而任何.c文件全体由增加进工程的特别.c文件逐级(仅能单级卡塔尔国援用进工程。

  至此,嵌入式开拓里的project文件豹哥便介绍完结了,掌声在哪里~~~