精华内容
下载资源
问答
  • 汽车整车控制器底层软件开发及程序集成
  • 本书包含ARM逻辑程序开发、嵌入式Linux系统建构、Linux驱动程序开发三部分。
  • 深入浅出嵌入式底层软件开发包含arm裸机程序开发、嵌入式linux系统建构、linux驱动程序开发三部分。从软硬件的分界面开始,循序渐进,逐一详细介绍嵌入式底层软件开发的各个技术要点,技术体系全面;既有一定的理论...
  • 混合动力汽车整车控制器底层软件设计与实现,混合动力相关的硕士论文。
  • 基于STM32F103的J1939多包传输底层软件设计.pdf
  • 基于arm平台,讲述Linux驱动开发继续。了解arm架构。。
  • 底层软件开发学习(1)

    千次阅读 2019-12-04 09:03:54
    底层软件开发小白(励志在底层领域有所建树,养家糊口同时望能为国家贡献一份力)记录工作过程中自己不懂的相关知识,一来可以加强自己的记忆提高自己,二来希望能给相关的底层开发同仁一点帮助。如有错误的地方帮忙...

        底层软件开发小白(励志在底层领域有所建树,养家糊口同时望能为国家贡献一份力)记录工作过程中自己不懂的相关知识,一来可以加强自己的记忆提高自己,二来希望能给相关的底层开发同仁一点帮助。如有错误的地方帮忙指出,谢谢。

    现在刚接触项目,只能遇到不会的地方记录下来,没有逻辑关系,等一段时间再统一整理。

    1 static inline函数

    头文件中常见static inline,用于定义函数

    引入内联函数的目的是为了解决程序中函数调用的效率问题,内联函数用于函数体小,引用频繁的函数放到头文件中,节省调用函数时需要的保护现场和恢复现场,用空间换时间。

    2. static修饰变量和函数

    A.c源文件中

    char a = 'A'; // global variable
    void msg() 
    {
        printf("Hello\n"); 
    }

    main.c源文件中

    int main(void)
    {    
        extern char a;    // extern variable must be declared before use
        printf("%c ", a);
        (void)msg();
        return 0;
    }

    运行结果:A Hello

    所有未加static前缀的全局变量和函数都具有全局可见性,其它的源文件也能访问——访问方法(1)在一个头文件中说明,要使用这些函数的源文件要包含这个头文件(2)在其他使用这个全局函数的源文件中,用extern先声明这个函数再使用。

    而对于内部函数应该在当前源文件中说明和定义。使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。

    对于函数来讲,static的作用仅限于隐藏,而对于变量,static还有下面两个作用:

    (1) 保持变量内容的持久,只初始化一次

    (2)默认初始化为0,字符默认初始化为'\0'

    局部变量按照存储形式来分,分为auto,static,register
    首先从内存四区的角度去看,auto即为普通的局部变量,存储在栈上,当函数结束时,随之释放。

    register为寄存器变量,存放在寄存器里面,调用速度快。
    在C语言中register变量不能取地址,会报错。
    而在c++中,对register做了增强,党C++编译器发现程序中需要取register变量的地址时,register对变量的声明变得无效。

    static修饰局部变量时该变量是存放在静态存储区,生命周期是整个程序结束。

    const

    关键字const用来定义常量,如果一个变量被const修饰,那么它的值就不能再被改变。C语言中已有#define, 而const修饰符有以下的优点:

    1、预编译指令只是对值进行简单的替换,不能进行类型检查

    2、可以保护被修饰的东西,防止意外修改,增强程序的健壮性

    3、编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。

    修饰局部变量const放在类型的前后没区别,用const修饰变量时,一定要给变量初始化,否则之后就不能再进行赋值了。

    常量指针 const int * n; 不能通过这个指针改变变量的值。可以通过其他的引用来改变变量的值,指向的地址可以改变。

    指针常量 int const * n;指向的地址不能改变。指向的变量的值可以改变。

    全局变量

    全局变量的作用域是整个文件,我们应该尽量避免使用全局变量,因为一旦有一个函数改变了全局变量的值,它也会影响到其他引用这个变量的函数,导致除了bug后很难发现,如果一定要用全局变量,我们应该尽量的使用const修饰符进行修饰,这样防止不必要的人为修改,使用的方法与局部变量是相同的。

    3 --Io 指的是 (为什么加下划线?避免命名冲突)

    __I volatile const:输入口。既然是输入,那么寄存器的值就随时会外部修改,那就不能进行优化,每次都要重新从寄存器中读取。也不能写,即只读,不然就不是输入而是输出了。
    __O volatile:输出口,也不能进行优化,不然你连续两次输出相同值,编译器认为没改变,就忽略了后面那一次输出,假如外部在两次输出中间修改了值,那就影响输出
    __IO volatile:输入输出口,同上

    volatile
    不让编译器进行优化,即每次读取或者修改值的时候,都必须重新从内存或者寄存器中读取或者修改。如果不加这个voliatile修饰,程序是利用catch当中的数据,那个可能是过时的了,加了 voliatile,就在需要用的时候,程序重新去那个地址去提取,保证是最新的

    1. volatile变量可变允许除了程序之外的比如硬件来修改他的内容 
    2. 访问该数据任何时候都会直接访问该地址处内容,即通过cache提高访问速度的优化被取

    一般说来,volatile用在如下的几个地方:
    1、中断服务程序中修改的供其它程序检测的变量需要加volatile;
    2、多任务环境下各任务间共享的标志应该加volatile;
    3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;

    1)一个参数既可以是const还可以是volatile吗?解释为什么。
    2); 一个指针可以是volatile 吗?解释为什么。
    3); 下面的函数有什么错误:

    int square(volatile int *ptr)  
    {   
        return *ptr * *ptr;  
    }  

     

    1)是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
    2); 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
    3) 这段代码有点变态。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:
    
    int square(volatile int *ptr)  
    {   
        int a,b;   
        a = *ptr;  
        b = *ptr;  
        return a * b;   
    }

    由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:

    long square(volatile int *ptr)  
    {   
        int a;   
        a = *ptr;  
        return a * a;   
    }   

    4. <>和""

    < >引用的是编译器的类库路径里面的头文件
    " "引用的是你程序目录的相对路径中的头文件

    如果使用" ",它是会先在你项目的当前目录查找是否有对应头文件;如果没有,它还是会在对应的库目录里面查找对应的头文件

    5. 声明和定义

    • 变量定义:用于为变量分配存储空间,还可为变量指定初始值。程序中,变量有且仅有一个定义。

    • 变量声明:用于向程序表明变量的类型和名字。

    • 定义也是声明,extern声明不是定义

    • 函数的声明和定义区别比较简单,带有{ }的就是定义,否则就是声明

    • 一般情况下头文件中只放变量的声明,因为头文件要被其他文件包含(即#include),如果把定义放到头文件的话,就不能避免多次定义变量

    • 如果声明有初始化式,就被当作定义,即使前面加了extern。只有当extern声明位于函数外部时,才可以被初始化

    6. 临界区和挂起调度器

      访问一个被多任务共享,或是被多任务和中断共享的资源时,需要采用“互斥”技术以保证数据在任何时候都保持一致性。这样做的目的是要确保任务从开始访问资源就具有排它性,直到这个资源又恢复到完整状态。

      临界区是提供互斥功能的一种非常原始的实现方法。临界区的工作 仅仅是简单的把中断全部关掉,或者是关掉优先级在configMAX_SYSCALL_INTERRUPT_PRIORITY以下的中断-依赖具体使用的FreeRTOS移植。抢占式的上下文切换只可能在某中断中完成,因此调用taskENTER_CRITICAL()可以在中断关闭的时段一直保持持续运行状态直到退出临界区。

      基本临界区是指宏taskENTER_CRITICAL()和taskEXIT_CRITICAL()之间的代码区间基本临界区是保护一段代码区间不被其他任务或中断打断。而由挂起调度器实现的临界区只能保护一段代码不被其他任务打断,并不能约束中断,因为在这种方式下,中断是使能的。调度器处于挂起状态时,不能调用FreeRTOS的API函数。

    7. 编辑器 编译器和链接器

    编辑器用来写程序生成源文件。

    编译器 将源文件变成目标文件即计算机能看懂的二进制文件

    链接器 将目标二进制文件和库二进制文件(操作系统提供开发库)链接起来生成一个可执行程序

    从源程序(.h .c文件)到可执行文件(ELF)的全过程如下:
    (1)预处理
    (2)转为汇编代码
    (3)转为目标代码
    (4)链接成可执行文件
    分工
    编译器工作阶段:(1) (2) (3)
    链接器工作阶段:(4)

    8. 堆栈帧

    堆栈帧的创建步骤如下所示:

    1) 被传递的实际参数。如果有,则压入堆栈。

    2) 当子程序被调用时,使该子程序的返回值压入堆栈。

    3) 子程序开始执行时,EEP 被压入堆栈。

    4) 设置 EBP 等于 ESP。从这时开始,EBP 就变成了该子程序所有参数的引用基址。

    5) 如果有局部变量,修改 ESP 以便在堆栈中为这些变量预留空间。

    6) 如果需要保存寄存器,就将它们压入堆栈

    9.

    lib文件里就是放的我们平时中用的.c和.h文件

    首先将C语言源文件经过C编译器生成相应的后缀为.o的目标文件,将汇编源文件(启动文件.s)也编译成相应的.o的目标文件, 最后通过连接器将各目标文件及存储器布局设置(option for target菜单设置)连接起来,生成后缀为.axf的可执行映像文件,这个映像文件可转化为二进制的程序映像文件.bin,也可以转换为十六进制文件.hex。

    平时我们下载到芯片Flash中的代码就是.hex文件,上电后,内核将Flash中的代码加载到SRAM中,就可以开始执行代码了。而调试过程中是将.axf文件直接加载到芯片的SRAM中可以直接运行我们保存在.axf上的代码了。

    展开全文
  • 这本书我自己是受益匪浅的,所以也推荐给大家,真本书对函数的调用,堆栈的理解很深刻
  • 深入浅出嵌入式底层软件开发--唐攀-带全部章节标签,Linux驱动开发,Linux系统开发环境构建详细解释
  • 微软底层软件

    2018-05-09 09:21:49
    如果你的Windows电脑没有安装这个软件,你也无法安装ScreenToGif
  • 唐攀的深入浅出嵌入式底层软件开发,非常有用。对ARM工作原理、嵌入式开发、Linux内核和BootLoader的学习介绍非常详细。
  • PLC底层软件结构论文

    2018-09-06 11:24:00
    这是一片论文(比较学术),以IEC61131–3标准分析plc底层结构。希望有所帮助
  • 不要在小公司做底层软件开发

    万次阅读 2018-01-07 12:11:35
    在这里makekam对底层软件的理解就是指驱动开发,代码移植等工作。其中也包括底层的算法。在小公司做软件不要做底层软件开发,犹如在公司做硬件开发不要只是焊接电路板。  小公司处于产业链的最末端,没有自己的...

            在这里makekam对底层软件的理解就是指驱动开发,代码移植等工作。其中也包括底层的算法。在小公司做软件不要做底层软件开发,犹如在公司做硬件开发不要只是焊接电路板。
            小公司处于产业链的最末端,没有自己的核心技术,只是针对用户需求完成一些系统集成和定制。而核心技术具有普遍适用性如“组合导航技术”、“操作系统移植与软件框架”等技术并不局限于某个领域,这些技术大公司可以集中力量突破,然后将技术卖给各个小公司。所以普遍适用性的技术往往来自大公司。因此,小公司的底层软件要么是测试供应商的软硬件产品,然后与供应商沟通测出的问题,要么是让自己公司的代码匹配供应商的产品,比如驱动开发、代码移植等。这些工作往往代码量奇少无比,体现不出高级程序员和低级程序员的区别,因为做这些事主要是看外设文档,与供应商沟通。只要花费人和时间,这些事情都能完成。

            除此之外,做底层开发还要替硬件填坑背锅。小公司缺少硬件测试流程,问题往往在产品运行时才能发现。假设makekam是做底层软件开发的,当做硬件的人焊接的板子有问题时,这些问题往往无法彻底排除是软件导致的,所以做底层软件的makekam就要花几天时间把底层代码查个遍来分析问题,最后才能让硬件的人用十五分钟解决问题。

            也许你会说,做底层软件做的多了不就积累了很多经验吗?其实不然,只要公司决定出钱购买另一款外围设备,那么之前的经验就很难用得上了。而且底层开发代码量很小,只是匹配主控芯片和外设,哪里有什么创新,哪里有什么复杂度?而且更重要的是,公司的领导心里永远不惦记你,这是因为,公司领导想的都是公司的项目,而这些项目的主要困难是什么?绝不是底层软件开发!底层软件开发只需要人和时间就一定可以完成,这是一个必然事件。而充满不确定性的应用层开发和项目成本估算还有项目需求分析才是这个项目成败的关键。因此,对于领导来说,在项目确定之前需要和三个人沟通,第一是和客户沟通,因为客户决定产品研发方向,第二是和外设供应商沟通,因为只有外设供应商才知道项目的开发平台的属性与成本。第三是和做应用开发的人沟通,因为项目的主要工作量是在应用层。领导不会和做底层软件的人沟通,因为底层软件只是一个桥梁,一个台阶,一个垫脚石。底层软件做的再好,也只不过是把系统做稳定,项目的价值的提升取决于业务目标和应用开发。

            总之,在小公司,面向客户,面向应用才有前途。因为小公司存在的意义就是面向客户整合产业链上游资源。


    展开全文
  • 嵌入式入门学习笔记4:[转]什么是嵌入式底层驱动开发和嵌入式底层软件开发 我们知道嵌入式操作系统(Embedded System)是指以应用为中心、以计算机技术为基础,软件硬件可裁剪、适应应用系统对功能、...

    嵌入式入门学习笔记4:[转]什么是嵌入式底层驱动开发和嵌入式底层软件开发

    我们知道嵌入式操作系统(Embedded System)是指以应用为中心、以计算机技术为基础,软件硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。嵌入式开发分两种,一种是硬件开发,一种是软件开发。简单来说,嵌入式底层驱动开发就是针对嵌入式操作系统的一些设备编写驱动程序。而嵌入式底层软件开发就是进行嵌入式操作系统和应用软件的开发,我们具体来看下。

    嵌入式系统是软硬结合的东西,搞嵌入式开发的人有两类:

    一类是学电子工程、通信工程等偏硬件专业出身的人

    他们主要是搞硬件设计,有时要开发一些与硬件关系密切的底层软件,如BootLoaderBoard Support Package(PCBIOS一样.往下驱动硬件.往上支持操作系统)、初级的硬件驱动程序等。他们的优势是对硬件原理非常清楚,不足是他们更擅长定义各种硬件接口,但对复杂软件系统往往力不从心(例如嵌入式操作系统原理和复杂应用软件等)他们所从事的工作就是我们常说的嵌入式底层驱动开发。

    另一类是学软件、计算机专业出身的人

    他们主要从事嵌入式操作系统和应用软件的开发,当然如果学软件的人对硬件原理和接口有较好的掌握,也完全可以写BSP和硬件驱动程序。嵌入式硬件设计完后,各种功能就全靠软件来实现了。嵌入式设备的增值很大程度上取决于嵌入式软件,这占了嵌入式系统的主要工作(目前有很多公司将硬件设计包给了专门的硬件公司稍复杂的硬件都交给台湾或国外公司设计。的硬件设计力量很弱,很多嵌入式公司自己只负责开发软件,因为公司都知道,嵌入式产品的差异很大程度在软件上。所以我们搞软件的人完全不用担心我们在嵌入式市场上的用武之地,越是智能设备越是复杂系统,软件越起关键作用,而且这是目前的趋势。

    posted @ 2018-12-05 22:33 一直走向深渊的迷途羔羊 阅读( ...) 评论( ...) 编辑 收藏
    展开全文
  • ST完成STM32微控制器全系底层软件部署
  • 游戏底层软件开发谋划书_学位论文.pdf
  • 基于嵌入式CPU的电站DCS控制器的底层软件开发.pdf
  • 基于STM32F103的J1939多包传输底层软件设计.rar
  • ST完成STM32微控制器全系底层软件部署.pdf
  • 底层软件研发推荐软件

    千次阅读 2018-07-21 15:59:20
    和VS相比,虽然SI的功能没那么全面,但是运行大型项目的处理时间却小得多,因此极多做底层软件的公司都选择了source insight。 缺点:不像VS那样在编码时有错误提醒,多个符号,或是使用错误的定义和声明都不会有...

    一、代码编写

    1.source insight

    作为底层软件的研发人员,source insight几乎是最好用的语言编辑器。和VS相比,虽然SI的功能没那么全面,但是运行大型项目的处理时间却小得多,因此极多做底层软件的公司都选择了source insight。
    缺点:不像VS那样在编码时有错误提醒,多个符号,或是使用错误的定义和声明都不会有报错,写代码是有种在白板写代码的感觉(编译的时候可能会出现一大堆错误)。
    附1:合理配置+插件可以极大提高编码效率。
    附2:学生阶段写单片机程序一般用Keil,CodeWarrior,Iar,写应用层的程序常用VS,但是用到了SI又是另一种感受啊。

    2.Nodepad++

    一款文本编辑器,类似于windows的记事本,超轻量级,方便进行代码的编写,修改和对比。
    那为什么用Nodepad不用记事本呢?
    原因是Microsoft开发记事本的团队使用了一个非常弱智的行为来保存UTF-8编码的文件,他们自作聪明地在每个文件开头添加了0xefbbbf(十六进制)的字符,你会遇到很多不可思议的问题,比如明明正确的程序一编译就报语法错误等。
    所以建议不要使用Windows自带的记事本打开任何程序文件。

    3.BeyondCompare

    文件,文件夹对比软件,版本修改时的利器。

    二、效率提升

    1.Q-Dir

    资源管理器,适用于打开非常多的窗口时!!!
    经常会出现同时打开不同盘的不同文件,alt+tab来回切,甚至恨不得换3屏,这是Q-Dir瞬间让人舒服了。

    2.Everything

    文件搜索程序,谁用谁知道。

    3.Snipaste

    方便到极点的截图工具(一定要用钉子功能)。

    4.e-diary

    个人用笔记本推荐Evernote,但是公司内网用的话还是用ediary比较合适,任务、文档、日程的记录都很方便。

    三、团队工作

    GIT和SVN!!!!!

    版本管理几乎是每个团队必备的工具,详细见google。

    四、总结

    个人研发流程:Keil编程,编译,连接——烧录到单板——运行看现象
    企业新模块研发流程:阅读模块技术手册,学习相关知识——团队内反串讲(给大牛们讲解流程和个人理解,由他们提出问题)——解决遗留问题——编码(SourceInsight)——代码检视(个人/大牛)——上传到编译专用Linux服务器——模块编译/改错——版本编译/改错——上传至单板所在的Linux服务器——冒烟(代码在单板环境下运行测试用例)——代码再检视——发布正式版本——联调(与其它模块一起进行)——多轮迭代……

    展开全文
  • 本文主要对单片机的底层和应用层进行了讲解,下面一起来学习下
  • 基于PowerPC的工控主板硬件及底层软件设计,阚彬,崔岩松,为了满足用户对高性能控制板的需求,设计了一种基于MPC8313E的工业控制系统,讲述了如何依据工业需求对外围电路的改进以及多种接口�
  • 多年智能手机底层驱动软件开发, 抽空写了底层调试小结,希望对大家有用!
  • 综合了Intel麦克风阵列和超声波笔输入技术,分析并运用WDM模式、DirectShowfilter、HIDMiniDriver技术对其底层进行构架和实现,采用单向数据通道技术进行共享设计,向第三方开发者提供了友好的底层编程接口,从而为...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 404,094
精华内容 161,637
关键字:

底层软件

友情链接: luffar2006.rar