1. 嵌入式软件系统的分类

  • 嵌入式软件
    • 系统软件
      • 控制、管理计算机系统资源
    • 支撑软件
      • 辅助软硬件开发
    • 应用软件
      • 面向应用领域

2. 嵌入式软件体系结构

  • 应用层
  • 中间件层
  • 操作系统层
  • 驱动层
  • 硬件

    2.1 驱动层

  • 板级初始化程序
  • 与系统软件相关的驱动
  • 与应用软件相关的驱动

    2.2 操作系统层

  • 嵌入式内核、嵌入式TCP/IP网络系统、嵌入式文件系统、嵌入式GUI系统,电源管理等

  • 嵌入式内核是基础和必备部分

    2.3 中间件层

  • 中间件技术

    2.4 应用层

  • 多个独立的应用任务组成

  • 由操作系统调度各个任务的运行

3. 嵌入式软件运行流程

  • 上电复位
  • 板级初始化
  • 引导/升级系统
  • 系统初始化
  • 应用初始化
  • 多任务应用

    3.1 上电复位、板级初始化阶段

  • 板级初始化程序具有完全的硬件特性,一般采用汇编语言实现

  • CPU堆栈指针寄存器初始化
  • BSS段(Block Storage Space未被初始化的数据)的初始化
  • CPU芯片级初始化:中断控制器,内存等初始化

    3.2 系统引导/升级阶段

  • 根据需要进入不同阶段

  • 通过测试通信端口或特定开关判断

  • 系统引导

    • 系统软件从NOR Flash加载到RAM
    • 直接在NOR Flash上运行
    • 将软件从外存(NandFlash、CF卡等)读取加载到RAM
  • 升级阶段

    • 网络远程升级
    • 串口本地升级

      3.3 系统初始化阶段

  • 控制权给操作系统

  • 操作系统系统软件各功能部分必需的初始化工作
  • 初始化需要按特定顺序进行

    3.4 应用初始化阶段

  • 应用任务的创建,信号量、消息队列的创建

    3.5 多任务应用运行阶段

  • 操作系统按照已确定的算法进行任务的调度

4. 嵌入式操作系统

  • 为应用程序提供服务的系统软件
  • 应用软件的运行平台

    4.1 操作系统的作用

  • 让应用程序脱离硬件,提升应用程序的移植性

  • 操作系统为复杂的系统提供管理机制
  • 从用户角度看是API和系统函数

    4.2 操作系统的功能需求

  • 许多的表和数据结构

    4.3 操作系统的特点

  • 可固化

  • 可配置、可剪裁
  • 独立的板级支持包,可修改
  • 需要集成的交叉开发工具

5. 交叉开发工具

5.1 交叉开发

  • 宿主机:建立交叉开发工具
  • 目标机:嵌入式程序运行的硬件平台
  • 交叉开发:主机环境下开发,目标机上运行

    5.2 交叉开发原因

  • 目标机本身待开发,不能使用或不稳定

  • 目标机平台没有本地编译工具和环境
  • 目标机性能不够,编译太慢

  • 宿主机和目标机的区别

  • 体系结构不同
  • 指令集不同
  • 处理能力不同

    5.3 构建交叉编译工具链

  • 针对目标系统的编译器gcc

    • GNU项目的C编译套件,最终输出的是汇编语言源程序
  • 针对目标系统的二进制工具Binutils
    • 与GCC紧密集成,包含汇编器(将汇编程序转成二进制形式),链接器(多个目标文件链接成可执行文件)
  • 针对目标系统的标准c库glibc
    • 提供系统调用和基本函数的C库
  • 针对目标系统的Linux内核头文件
  • 针对目标系统的交叉调试器gdb

    • 用来调试C和C++程序的调试器

      6. Linux

      6.1 目标板与主机的连接

  • 串口

  • 以太网
  • USB接口
  • JTAG接口

6.2 开发环境

6.2.1 GCC

  • Linux下的编译器-GNU项目的C编译器
  • 四个步骤
    • 预处理 -E 指令
      • 从源文件(.c)变为预处理过的C程序(.i)
    • 编译 -S 指令
      • 从预处理过的C程序(.i)变为汇编语言源程序(.s)
    • 汇编 -c 指令
      • 从汇编语言源程序(.s)变为目标文件(.o)
    • 链接 -o 指令
      • 从目标文件(.o)变为可执行的二进制文件

6.2.2 GDB、JTAG

  • GDB本地调试
    • 调试器和被调程序工作在同一计算机上
    • 不适合嵌入式系统
      • 嵌入式目标机缺乏程序运行条件
      • 受主频和内存限制
  • GDB交叉调试

    • 主机GDB调试器,目标机GDB Server
    • 更适合嵌入式系统
      • GDB Server很小,对运行环境要求不高
      • 通过远程GDB协议通信
  • 交叉调试软件调试

    • 以某种通信方式控制被调程序
    • 目标机有调试代理
    • 远端调试 -target 命令
    • 是建立在操作系统上调试,不能用来调试操作系统
    • 必须使用 -g 指令编译调试信息
  • 交叉调试硬件调试

    • 调试能力更强,除了应用程序还可调试操作系统,引导程序
    • ICD调试,JTAG调试
  • 调试流程:

    • 宿主机交叉编译目标机程序(-g),将目标机程序下载到目标机
    • 建立调试器(本地gdb)与目标操作系统的通信连接(串口,网卡等)
    • 目标机开启gdbserver进程,监听对应端口
    • 主机运行gdb调试器寻找gbdserver进程
    • 用户在宿主机上运行gdb下达调试命令,通过gbdserver对目标机上的程序发出控制命令
    • gbdserver把应用程序的调试信息传递到主机的gdb并显示

6.2.3 MAKE

  • 自动化工具
  • 不需要手工编译每个程序文件
  • 宗旨:让编译器知道编译一个文件需要依赖哪些文件,依赖文件改变时自动发现那些部分重新编译。
  • 基本原理:如果某个源程序文件被修改,那么依赖这个源程序文件的所有目标文件都需要重新编译。