昨天出去玩了,回来花了一个傍晚才明白这门课到底是什么
现在离考试只有一天了,我必须要开始写这个文档。
上午:1-7 下午:8-13 晚上:看实验和作业
第1章 嵌入式系统概述
问题1.1 什么是嵌入式系统?
- 狭义:嵌入式系统是指操作系统和功能软件集成于计算机硬件系统之中。
- 广义:嵌入式系统是以应用为中心,以计算机技术为基础,采用可剪裁软硬件,适用于对功能、可靠性、成本、体积、功耗等有严格要求的专用计算机系统。
问题1.2 嵌入式系统组成
- 硬件平台+软件平台:软件平台=操作系统+应用软件 硬件平台=处理器+外围设备
- 硬件核心: 嵌入式处理器(微处理器)
- 常见的外围设备: USB LCD SD card Other
时钟模块、电源模块、输入输出设备、存储设备、通信模块
问题1.3 嵌入式和通用型计算机的区别
嵌入式系统结合各行业具体应用,技术密集、高度分散、不断创新
- 应用特性: 嵌入式系统通常是面向特定应用的
- 设计方法: 软硬件都必须高效率设计,量体裁衣、去除冗余(专用性)
- 开发能力: 嵌入式系统本身不具备自主开发能力
- 有机结合: 升级换代和具体产品同步进行
- 软件固化: 软件一般固化在存储器芯片或单片机本身, 不是~~磁盘~~
第2章 ARM处理器和架构
问题2.1 嵌入式处理器结构对比
普林斯顿结构=冯诺依曼结构
普林斯顿结构 | 哈佛结构 | |
---|---|---|
指令与数据寄存器 | 一体化设计 | 独立设计 |
指令与数据地址 | 统一编码 | 独立编址、独立访问 |
储存传输通道 | 有瓶颈 | 四总线制 |
取指与执行能并发 | 不能并发 | 取指与执行能并发 |
- 四总线制:程序的地址总线、数据总线,数据的地址总线、数据总线
问题2.2 关键寄存器 CPSR SPSR PC
-
CPSR
: 当前程序状态寄存器,存储当前程序的状态信息。 -
SPSR
:保存程序状态寄存器,存储在异常处理过程中保存的程序 状态。 -
PC
:程序计数器,用于存储当前正在执行的指令的地址。
问题2.3 指令集,微架构,芯片产品
三者关系:指令集 -> 微架构 -> 芯片产品
- 指令集: 指令集架构(ISA)的缩写,硬件和软件之间交互(指令)的规范标准 格式+功能
- 微架构: 将指令集功能实例化,开发,变成源代码
- 芯片产品: 将版图流片,封装,获得芯片
问题2.4 RISC-V特点(相对ARM的比较优势)
技术与市场 | x86或ARM架构 | RISC-V |
---|---|---|
架构篇幅 | 数千页 | 少于三百页 |
指令数 | 多,不兼容 | 基本指令集47条 |
模块化 | 不支持 | 支持 |
可扩展性 | 不支持 | 支持 |
硬件实现 | 复杂度高 | 硬件设计与编译实现非常简单 |
商业运作 | x86封闭,ARM昂贵 | 开源、免费 |
生态环境 | 成熟 | 快速起步中 |
应用市场 | PC,服务器,移动,嵌入 | 全计算领域 |
应用特点 | 垄断地位 | 高性能,普适,可控 |
应用风险 | 不可控、缺乏弹性、成本 | 生态不足、碎片化、专利问题 |
问题2.5 嵌入式处理器的分类和列举
- 嵌入式处理器分类: EMPU、MCU、EDSP、SOC
- EMPU种类:MIPS、Power PC、SH处理器、ARM
问题2.6 ARM是什么
- ARM是一种精简指令集计算机(RISC)架构,广泛用于嵌入式系统和移动设备中的处理器设计。
问题2.7 区别ARMv7和ARM7
* ARM7
系列是处理器版本型号,而ARMv7
是ARM架构版本号,两者没有本质关联。
问题2.8 ARM特点?(基于RISC架构
的ARM处理器
的特点)
- 体积小,低功耗,低成本
- 兼容好:支持Thumb(16 位)/ARM(32位)双指令集,能很好兼容8位/16位器件
- 高性能:大量使用寄存器,指令执行速度快
- 寄存器:大多数数据操作都在寄存器中完成
- 寻址:寻址方式灵活简单,执行效率高
- 指令:采用固定长度的指令格式
问题2.9 ARM微处理器中 Cortex 的3个系列
场景 | 流水线 | 处理器 | |
---|---|---|---|
Cortex-A | 高性能 | 13级 | 1-4个核 |
Cortex-R | 高实时性 | 8级 | 专用集成电路(ASIC) |
Cortex-M | 低功耗 | 3级 | 微控制器 |
问题2.10 ARM指令集特点和组成
ARM指令集属于加载/存储型指令: 操作数都储存在寄存器中,处理结果直接放回到目的寄存器中
ARM指令基本组成部分:<操作码>{<条件码>}{S} <目标操作数>,< 存放第1操作数的寄存器> {,<第2操作数>}
-
< >
内的项目必选,{ }
内的项目可选 - 若加上“S”,则在指令完毕后会自动更新CPSR中条件码标志位的值
- 第2操作数,灵活,可以是
寄存器
,立即数
问题2.11 ARM指令和Thumb指令
ARM指令 | Thumb指令 | |
---|---|---|
指令条件 | 条件执行(除v5T等) | 无条件执行(除了B等) |
指令格式 | 2地址 | 3地址 |
位数 | 32位 | 16位 |
问题2.12 寻址方式回顾
- 立即寻址:#0x1 #表示立即数
- 寄存器寻址:R1 直接使用寄存器号
- 寄存器偏移寻址:R1,ROR/ROL #0x2
- 基址变址寻址:[R2, #0x2]
第3章 嵌入式Linux操作系统
问题3.1 操作系统的作用
本课程:系统资源管理,硬件虚拟化,提供资源
问题3.2 常见嵌入式OS?
嵌入式Linux、Windows CE、Symbian、VxWorks、QNX、Palm等
问题3.3 鸿蒙的特点
卡片化的前端管理,物联网;统一OS,弹性部署;
硬件互助,资源共享;一次开发,多端部署
问题3.4 嵌入式Linux组成
Linux组成结构(4部分):内核 shell 文件系统 应用程序
问题3.5 Linux内核的组成
- 进程调度程序(SCHED) 控制进程访CPU
- 内存管理程序(MM) 进程共享主存(虚拟内存)
- 虚拟文件系统(VFS) 提供抽象设备的细节。兼容的不同文件系统格式
- 网络接口(NET) 对网络硬件的访问
- 进程间通信(IPC)实现进程之间的通信
问题3.6 Linux内核的命名机制
主版本号.次版本号.修订版本号
问题3.7 嵌入式Linux的特点(了解)
- 广泛的硬件支持,内核高效稳定,开放源码,软件丰富,
- 优秀的开发工具,完善的网络通信和文件管理
第4章 嵌入式软件编程技术
问题4.1 谈谈make和makefile的区别
make
:编译修改过的文件,缩短编译时间
Makefile
:文件,包含make
工具生成目标文件的规则
问题4.2 Makefile的格式如何
组成:规则的目标,依赖和命令
- TARGET… : PREREQUISITES… # 规则的目标: 规则的依赖
- COMMAND # 规则的命令
问题4.2 可重入问题
可重入函数可以有多个任务并发使用,而不必担心数据出错
- 将全局变量或静态变量改为局部变量
- 采用信号量进行临界资源保护
- 禁止程序执行中进行中断
问题4.3 C语言和汇编语言混合编程
汇编调用C:IMPORT C程序+ BL C函数
C调用汇编:嵌入式和内联
- 嵌入式:C使用extern,汇编使用EXPORT
- 内联:在C程序中使用
__asm__(输出:输入:修改)
语句实现
第5章 嵌入式软件开发环境
问题5.1 嵌入式软件开发的主要步骤
- 选择硬件-建立环境-建立系统-开发应用
- Linux开发步骤:编辑,编译,调试,运行
问题5.2 嵌入式系统开发模式
宿主机-目标机开发模式
- 首先在通用计算机上编写软件
- 然后通过本地编译或者交叉编译生成目标平台上可以运行的二进制代码格式
- 最后再下载到目标平台上运行
问题5.3 嵌入式软件的交叉编译
- 交叉编译:在一种平台上编译出能在另一种平台上运行的程序
- 交叉编译器类型目标文件格式取决于目标机的OS
- 交叉编译环境:交叉编译,交叉链接,交叉调试
- 配置交叉编译环境需要安装交叉编译工具机ToolChain
问题5.4 建立宿主机-目标机之间的通信连接
- JTag:芯片级接口,第一个运行软件需要通过
JTAG
口传递,
注:也用于芯片内部测试以及对系统进行仿真,调试 - 串口:慢短小,配置灵活,可做终端,实现简单,可以传送文件。
- 网络:快远大,复杂。TFTP,两端均提供驱动(C/S)
- USB:快速、灵活、易于使用,支持热插拔。
问题5.5 TFTP协议是什么。
Trivial File Transfer Protocol
- 承载在UDP上,可以利用TFTP下载Linux映像
问题5.6 如何进行gdb调试
- 在编译时,必须要把调试信息加到可执行文件中
- 使用编译器(cc / gcc / g++)的 -g 参数
问题5.7 如何进行远程调试环境
stub方案(插桩):在目标操作系统和宿主机调试器内分别添加一些功能模块
- 用
ROM Monitor
调试目标板程序 - 用
kgdb
调试系统内核 - 用
gdbserver
调试用户空间应用程序
远程调试的步骤:宿主机启用调试器,两机建立通信通道,向目标系统发送调试信息。
目标机被调试程序若触发异常,调用异常处理程序,转入调试端口通信
- 三种方法:远程调试、内核调试、网络调试。
第6章 Boot Loader技术
问题6.1 PC机与嵌入式系统的启动过程及其差别?
PC | 嵌入式 | |
---|---|---|
1 | 加电自检(POST ) | 硬件初始化 |
2 | BIOS /UEFI 初始化 | … |
3 | 加载引导程序 | 加载引导程序 |
4 | 加载操作系统 | 内核启动 |
5 | … | 加载根文件系统 |
6 | … | 启动用户程序 |
- 嵌入式系统没有
POST
,用没有BIOS
,启动过程更加简单和定制化, - 可以是直接从固化的存储器中(如闪存)加载引导程序,更快速和更高效率;
- PC系统启动往往会做一系列检查,而嵌入式启动直接初始化。
问题6.2 什么是Boot Loader?
在操作系统内核运行之前运行的一段小程序(引导加载程序)
Boot Loader的目标:调用内核
Boot Loader的典型结构 两阶段:CPU驱动+C语言
常见:U-Boot
、vivi
、Redboot
问题6.4 Bootloader 的主要工作
- 初始化硬件设备和建立内存空间的映射图
- 将系统的软硬件环境带到一个合适的状态
- 为最终调用操作系统内核准备好正确的环境
问题6.5 Boot Loader的操作模式
- 启动加载模式:启动时加载非易失没接中的映像
- 下载模式:启动时自动下载(串口/网络)映像
问题6.6 Boot Loader与主机之间的通信设备及协议
- 最常见的是串口,协议xmodem / ymodem / zmodem
- 以太网,协议TFTP
问题6.7 Boot Loader的使用方法
- 烧写Boot Loader :JTAG
- Boot Loader加载或烧写内核和文件系统: trampoline
- Boot Loader检测内存(RAM)可读写
- Boot Loader与内核的通信
第7章 ARM-Linux内核
问题7.1 内存管理的内容和两个方面
内容: 地址映射(包括IO和段地址)、内存分配,访问限制。
两个方面:操作系统的内存管理+ARM的MMU(内存管理单元)
问题7.2 聊聊关于MMU?
- MMU:内存管理单元,提供一组寄存器
- 作用:地址映射,访问限制,作为协处理器
- 映射方式:段,页
问题7.3 嵌入式Linux内核的内存管理
- 虚拟内存:允许每个进程拥有自己的虚拟地址
- 内存映射:对文件的读写操作可以通过内存访问来完成
问题7.4 进程管理和调度
- 进程:任务,动态执行过程,执行的程序,系统资源分配的最小单位。
- 三个过程:创建,执行,销毁
- 创建:sys_fork,sys_vfork,clone
- sys_fork:完整派生
- sys_vfork:通过参数复制资源
- sys_clone:复制结构,共享数据,阻塞父进程
- 执行: fork产生新的PID,exec启动新程序,替换原有的进程,PID不变
- 销毁:进程结束,信号终止,do_exit
问题7.5 进程调度依据
- Policy:区分实时进程和普通进程,实时优于普通
- Priority:进程(包括实时和普通)的静态优先级
- Counter:进程剩余的时间片,起始值就是priority的值,动态优先级
- rt_priority:实时进程特有的,用于实现进程间的选择
问题7.6 谈谈Linux中的模块机制,它结构是怎样的
必要性:弥补Linux可拓展性以及可维护性差的缺点
结构:头文件,宏声明,初始化函数,退出函数,入口出口函数设置
- 头文件: <linux/module.h> <linux/init.h> <linux/kernel.h>
- 模块宏声明:
MODULE_LICENSE
MODULE_DESCRIPTION
MODULE_AUTHOR
- 初始化函数:
static int __init mod_init_func(void)
: 当模块被加载时调用,以__init
结尾。 - 退出函数:
static void __exit mod_exit_func(void)
: 当模块被卸载时调用,以__exit
结尾。 - 入口出口函数设置(宏):
module_init(mod_init_func)
module_exit(mod_exit_func)
问题7.7 与Linux模块相关的命令有哪些
- lsmod 把现在kernel中已经安装的modules列出来
- insmod 把某个module安装到kernel中
- rmmod 把某个没在用的module从kernel中卸载
- depmod 制造module dependency file,以告诉将来的insmod要去哪儿找modules来安装
问题7.8 谈一谈中断管理
流程:中断请求,保护现场,判断是否需要中断
三个环节: 中断响应,中断处理,中断返回
GPIO: 是一个通用的可编程I/O接口,每一位都可在程序的控制下设置用于输入或者输出;
GPIO用于输入时,可引发中断请求
问题7.9 系统调用的实现方式
- 通过经过封装的C库(
libc
) x86
:通过自陷指令INT 0x80
实现ARM
:通过自陷指令SWI
实现
保护现场,查找相应函数执行,恢复现场
问题7.9 启动和初始化方法
过程:Boot Loader =》内核数据结构=》外设
init
程序通过读取该文件作为其行为指针
inittab
是以行为为单位的描述性(非执行性)文本
inittab格式: /etc/inittab: id:runlevel:action:process
入口标识符:运行级别:动作代号:具体的执行程序
问题7.10 嵌入式Linux内核如何编译
内核配置 make config/menuconfig/xconfig
内核编译 make /zImage/bzImage
内容下载或者内容烧写
第8章 文件系统
问题8.1 控制设备驱动的途径有哪些?
设备API直接访问,通过文件管理器访问。
问题8.2 Linux文件系统组织结构
树:bin/sbin/etc/dev/proc/var/temp/usr/home
/root/boot/lib/opt/mnt/media/srv/sys
问题8.3 Linux文件系统与Windows文件系统区别
Linux(EXT) | Windows(NTFS) | |
---|---|---|
格式 | / 区分大小写 | \ 不区分大小写 |
组织 | /etc/home | \Windows\Users |
建立 | 挂载 | 分区 |
权限 | rwx | 面向对象(笑话) |
兼容 | 开源 | 商业 |
命令 | ls cp mv | dir copy move |
问题8.4 谈谈常用的文件系统
通用文件系统 ext2 能否做嵌入式文件系统? (其实可以)
嵌入式文件系统 日志,性能,专用性等角度
- NAND Flash ⟶ \longrightarrow ⟶ YAFFS2 位翻转和坏块管理,长期存储
- NOR Flash ⟶ \longrightarrow ⟶ JFFS2:日志恢复,频繁读写,快速启动
- RAM ⟶ \longrightarrow ⟶ RAMFS 临时存储和高性能读写,短期存储
- Network ⟶ \longrightarrow ⟶ NFS 网络挂载远程文件系统
问题8.5 根文件系统
- 什么是根文件系统?第一个文件系统,包含启动目录/文件
- 如何建立根文件系统?cramfs嵌入式根文件系统构造
make menuconfig -> make -> make install
创建一些必要文件(rc,rcS,motd…) -> mkfs.cramfs -> 烧入
第9章 设备驱动
问题9.1 设备驱动有什么用?
初始化和释放,向设备读写数据,检测设备错误
问题9.2 Linux设备有哪些种类?
字符设备,块设备,网络设备
问题9.3 Linux设备文件有什么作用,如何表示?
抽象了对硬件的处理为普通文件。
- 主设备号: 标识该设备的种类,也标识了该设备所使用的驱动程序
- 次设备号: 标识使用同一设备驱动程序的不同硬件设备
问题9.4 Linux设备驱动程序如何编写?
编写,编译,下载到目标板,挂载
- 驱动程序结构:注册与注销,打开与释放(open/release),读写(read/write),中断和轮询
- 编译方法:make -C /path/to/linux/kernel M=
pwd
- 下载方法:老三样 串口 USB 网络(tftp,nfs等)
问题9.5 如何挂载Linux设备驱动
- 挂载方法:insmod /path/to/driver.ko
- 卸载方法:rmmod driver
- 创建设备文件:mknod /dev/device c major minor
- 设置设备权限:chmod 666 /dev/device
问题9.6 谈谈设备的同步机制
- 内核同步: 同步锁、信号量、原子操作和完成事件
- 设备操作:同步 or 异步
问题9.7 DMA(Direct Memory Access)是什么?
- 直接内存存取: 不需要处理器的干预,在设备和系统内存高速传输数据
第10~12章 三种设备和驱动程序设计
问题10.1 字符型设备的驱动数据结构是什么
- struct file_operations:一组函数指针,开关读写
- struct file:代表打开的文件
- struct inode: 索引节点,包含了文件的信息
问题10.2 谈一谈串行总线接口(协议)
- SPI:通信协议,高速、全双工、同步、短距离
- I2C:通信协议,低速、多主从
I2C组成:Adapter(适配器),Algorithm(算法) ,Client(具体设备)
问题10.3 块设备的驱动数据结构是什么
- gendisk:设备的基本信息
- request_queue:来自上层的中断请求,为他们排队
- request:IO请求在内核中的表示
问题10.3 块设备驱动的主要操作有哪些
初始化:gendisk
,request_queue
,设置block_device_operations
,硬件初始化
请求处理:make_request
,queue_rq
,中断处理,清除队列
问题10.3 网络设备的驱动数据结构是什么
- net_device:设备的基本信息 MAC地址,MTU等)
- sk_buffer:处理网络数据包的数据结构
问题10.3 网络设备驱动的主要操作
初始化 init:注册网络设备,设置net_device,硬件初始化
打开接口 open:启用,配置网络设备
第13章 嵌入式GUI及应用程序设计
问题 11.1 什么是嵌入式GUI
- 嵌入系统的图像用户界面,视觉+操作
问题11.2 嵌入式GUI有哪些种类,说几个名字
- 种类:操作系统,外挂平台,简单GUI
- 列举:Plam,WinCE,Android,iOS,鸿蒙
问题11.3 能解释一下嵌入式GUI的体系结构和分层设计吗?
- 抽象层 隐藏硬件的复杂性,为上层提供统一的接口
- 核心层 包含了渲染引擎、事件处理、窗口管理器等核心功能。
- App接口层 提供API和工具,使开发者能创建、设计和管理用户界面
问题11.4 Android应用程序由哪些构成?
- 活动(Activity)它表示一个具有用户界面的单一屏幕
- 意图(Intent)一个消息传递对象,使用它请求其他组件执行操作。
- 服务(Service)一个没有用户界面的应用组件,在后台执行长时间运行的操作
- 内容提供器(Content Provider)管理一组共享的应用数据,在文件系统、数据库或网络上
问题11.5 谈谈Android应用程序的生命周期
- onCreate(): 在Activity第一次创建时调用。
- onStart(): 在Activity变得可见时调用。
- onResume(): 在Activity开始与用户交互时调用。
- onPause(): 当系统开始要恢复另一个Activity时调用。
- onStop(): 当Activity不再可见时调用。
- onDestroy(): 在Activity被销毁前调用。
- onRestart(): 在Activity被停止后重新启动时调用。
问题11.6 谈谈Android开发环境
idea就可以开发(其实这个PPT太老了,现在是Kotlin)
- libs: 项目构建和运行时需要的预编译库。
- main.java: 主函数的源文件,程序执行的入口点。
- main.res: 资源文件(如布局、字符串、图片等)
- build.gradle: 构建脚本,配置如何构建项目。
- .properties: 这是一个属性文件,存储配置信息。
问题11.7 鸿蒙应用开发的流程
- 配环境,Ability,GUI,业务功能开发,调试,发布
- Ability = FA:GUI + PA:服务(多对多)
问题 11.8 鸿蒙系统的特点
- 卡片化的前端管理,物联网;统一OS,弹性部署;
- 硬件互助,资源共享;一次开发,多端部署
当看到这里的时候,我想应该再去看看代码了吧