还剩48页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
嵌入式Linux教案本课程为嵌入式Linux系统开发教案,适合具有基础编程知识的计算机科学、电子工程专业学生以及希望转型嵌入式领域的软件工程师学习课程涵盖从嵌入式系统概念到实际项目开发的全流程知识随着物联网、智能设备的快速发展,嵌入式Linux系统在工业控制、智能家居、汽车电子等领域应用广泛本课程将理论与实践相结合,通过系统化的知识模块和项目实战,帮助学习者掌握嵌入式Linux开发技能嵌入式系统概述嵌入式系统定义嵌入式系统特点主流嵌入式平台嵌入式系统是一种专用的计算机系统,嵌入式系统具有实时性、可靠性高、资作为装置或设备的一部分,具有特定功源受限、低功耗、专用性强等特点这能它通常包含处理器、存储器、输入些特点使其能够在各种环境下稳定运行,输出接口以及特定应用的软件与通用满足特定应用场景的需求嵌入式系统计算机不同,嵌入式系统通常为特定任通常需要长时间不间断工作,因此对软务设计,并对成本、体积、功耗有严格硬件的稳定性要求极高要求Linux在嵌入式领域的地位开源优势移植性和可裁剪性Linux作为开源操作系统,具有源代码开放、免许可费用、社区Linux支持多种硬件架构,包括ARM、MIPS、PowerPC支持完善等显著优势开发者可以自由查看、修改和分发系统代等,使其具有极强的移植性开发者可以将Linux移植到各种嵌码,大大降低了产品开发成本入式平台上,保护了技术投资开源模式使Linux不断吸收全球开发者的智慧,能够快速修复漏洞和问题,安全性和稳定性不断提高同时,丰富的开源工具链和应用生态系统,为嵌入式产品开发提供了强大支持课程学习路径与模块安排基础知识部分嵌入式系统概述、Linux基础知识、系统架构、开发环境搭建等,为后续学习打下坚实基础,建立整体认知框架内核与系统部分内核裁剪与配置、启动流程、根文件系统构建、设备树技术等,深入理解Linux系统的核心机制与工作原理驱动与应用开发字符设备驱动、I/O接口编程、进程与线程、网络编程等,掌握嵌入式系统开发所需的核心技术能力项目实战部分学习Linux基础要求编程基础掌握C语言编程,理解指针、内存管理等概念命令行操作熟悉基本Linux命令和Shell使用硬件基础了解基本电路原理和数字电子知识学习嵌入式Linux开发需要具备一定的前置知识C语言是Linux内核和大多数嵌入式应用的开发语言,熟练掌握C语言编程技能是必不可少的此外,对计算机体系结构、操作系统原理有基本了解,将有助于更好地理解Linux系统的工作机制Linux操作系统体系结构应用程序用户可见的软件程序库函数提供API接口给应用程序系统调用连接用户空间和内核空间的桥梁内核空间包含进程管理、内存管理、文件系统、设备驱动硬件层物理设备和硬件接口Linux操作系统遵循传统UNIX设计哲学,整个系统分为内核空间和用户空间两个主要部分内核空间运行在特权模式下,直接访问硬件资源,负责进程管理、内存管理、文件系统、设备驱动等核心功能用户空间运行在非特权模式下,包含应用程序和库函数,通过系统调用接口与内核交互嵌入式Linux开发环境搭建主机开发环境选择必备开发工具推荐使用Ubuntu或其他需安装编译工具链gcc,Linux发行版作为开发主机系make、版本控制工具统,可提供原生Linux环境及git、文本编辑器vim,丰富的开发工具Windows vscode和调试工具gdb系统可通过WSL2或虚拟机以Ubuntu为例,可通过运行LinuxMacOS虽具有apt installbuild-UNIX基础,但某些开发工具essential gitvim gdb命兼容性有限令快速安装基础工具集交叉编译工具链准备常见嵌入式开发板选型选择合适的开发板是嵌入式Linux学习和开发的重要一步树莓派Raspberry Pi凭借其强大的社区支持和丰富的学习资源,成为初学者的理想选择它采用Broadcom BCM2711处理器,搭载ARM Cortex-A72架构,支持多种外设接口,性价比高NXP的i.MX6系列开发板在工业级应用中广泛使用,具有出色的多媒体处理能力和丰富的接口资源全志AllwinnerA33等国产芯片开发板价格更为亲民,适合成本敏感型项目BeagleBone Black提供了更多GPIO接口,适合需要大量I/O操作的项目选择开发板时,应根据项目需求、预算和个人学习目标进行综合考量交叉编译环境配置流程获取交叉编译工具链根据目标板架构选择合适的工具链例如,ARM架构可以使用arm-linux-gnueabihf-gcc(硬浮点)或arm-linux-gnueabi-gcc(软浮点)可以从芯片厂商官网下载预编译的工具链,或使用包管理器安装sudo aptinstallgcc-arm-linux-gnueabihf配置环境变量将工具链的bin目录添加到PATH环境变量中,以便系统能够找到交叉编译工具在~/.bashrc文件中添加exportPATH=/path/to/toolchain/bin:$PATH,然后执行source~/.bashrc使配置生效可通过which arm-linux-gnueabihf-gcc命令验证配置是否成功验证工具链创建简单的C程序测试交叉编译环境是否正常工作使用命令arm-linux-gnueabihf-gcc-o hellohello.c编译,然后用file hello命令查看生成的可执行文件信息,确认其目标架构是否正确通过指定--sysroot选项可引用目标系统的头文件和库文件常用开发工具简介U-Boot BusyBoxMake GDB广泛使用的开源引导加载程集成了常用Linux命令工具自动化构建工具,通过强大的调试工具,支持断点序,负责初始化硬件、加载的单一可执行文件,被称为Makefile定义编译规则和设置、单步执行、变量查看内核并启动操作系统支持嵌入式Linux的瑞士军刀依赖关系使用make命等功能在嵌入式开发中,多种处理器架构和启动介通过裁剪功能和选项,令可自动检测文件变化并执通常结合gdbserver进行质,提供命令行界面进行交可大幅减小系统体积,适合行必要的编译步骤,提高开远程调试,在目标板上运行互操作可自定义配置参资源受限的嵌入式设备提发效率在嵌入式Linux开gdbserver,在开发主机数、环境变量,实现灵活的供shell环境和基本系统工发中广泛用于内核、驱动和上使用gdb连接并调试程启动控制具,是构建最小根文件系统应用程序的编译构建序的核心组件嵌入式Linux系统启动流程上电复位CPU执行复位向量地址处的指令,通常是ROM中的引导程序这一阶段进行基本硬件初始化,如CPU频率、存储器配置等,为加载Bootloader第一阶段Bootloader做准备ROM引导程序加载Bootloader第一阶段SPL到内部SRAM中执行SPL体积小,功能简单,主要负责初始化关键硬件如DRAM、Bootloader第二阶段Flash并加载第二阶段Bootloader完整Bootloader如U-Boot被加载到RAM中执行,进行全面的硬件初始化,提供命令行界面和环境变量负责加载设备树文件DTB内核启动和Linux内核到内存,并传递启动参数内核接管系统控制权,解压自身,初始化内存、中断控制器等硬件,挂载根文件系统内核根据设备树信息识别硬件设备并加载驱动程序根文件系统挂载内核挂载根文件系统,启动init进程PID为1,这是用户空间的第一个进程挂载成功后,系统控制权从内核空间转移到用户空间用户空间初始化init进程根据/etc/inittab等配置文件完成系统初始化,启动系统服务、网络配置等,最终进入用户界面或应用程序Bootloader原理与U-BootU-Boot基本概念U-Boot常用命令U-BootUniversal Bootloader是嵌入式系统中最流行的
1.printenv显示环境变量开源引导加载程序,支持多种处理器架构它由德国DENX公
2.setenv设置环境变量司开发维护,采用GPL许可证发布
3.saveenv保存环境变量U-Boot的主要任务是初始化系统硬件,为操作系统提供运行环
4.tftp通过网络加载文件境,并负责将内核加载到内存中启动它还提供了丰富的命令行
5.mmc SD卡操作命令接口,方便开发者进行调试和配置
6.nand NAND闪存操作
7.bootm启动内核映像
8.go执行内存中的代码在嵌入式系统中,U-Boot通常分为两个阶段第一阶段SPLSecondary ProgramLoader负责基本初始化并加载主U-Boot;第二阶段是完整U-Boot,提供命令行界面并执行内核加载启动流程中,U-Boot首先初始化CPU、内存和关键外设,然后从存储设备加载内核和设备树,最后跳转到内核入口点执行内核映像制作与烧录内核映像类型映像制作命令常用烧录方法•zImage自解压内核映像,适合低内存•make ARCH=arm•TFTP网络烧录在U-Boot下使用tftp系统CROSS_COMPILE=arm-linux-命令加载gnueabihf-zImage编译内核•uImage添加U-Boot头部的内核映像,•SD卡烧录使用dd命令将映像写入SD卡包含校验和、加载地址等信息•mkimage-A arm-O linux-T•JTAG烧录使用OpenOCD等工具通kernel-C none-a0x80008000-e•dtb设备树二进制文件,描述硬件信息过JTAG接口烧录0x80008000-n Linux-d zImage•fit灵活映像格式,可将内核、设备树和•串口烧录使用kermit等工具通过uImage生成uImage•dtc-I dts-O dtb-o board.dtb根文件系统打包XMODEM协议传输board.dts编译设备树根文件系统结构/etc包含系统配置文件存放网络/lib配置、用户账户信息、服务配/dev存放系统运行和程序执行所需置等重要系统设置文件,是系的共享库文件包含动态链接统管理员最常访问的目录之一设备文件目录Linux中一切库.so文件和内核模块皆文件,/dev下的特殊文件代/bin和/sbin/lib/modules/,是系统正表系统中的各种硬件设备,如其他重要目录包含系统启动和运行所需的基常运行的基础支持串口、块设备、输入设备等本命令/bin目录包含所有用/proc进程信息、/sys内核户可用的基本命令,如ls、cp信息、/tmp临时文件、等;/sbin包含系统管理命令,/usr应用程序和/var可变数如ifconfig、mount,通常只据等目录共同构成了完整的文有root用户可执行件系统层次结构BusyBox介绍与定制BusyBox概述编译与裁剪实践BusyBox是嵌入式Linux系统中常用的工具集合,被称为嵌BusyBox的编译过程与Linux内核类似,支持通过配置选择需入式Linux的瑞士军刀它将多种UNIX工具集成到一个紧凑要的功能首先下载源码并解压,然后执行make defconfig的可执行文件中,通过创建到这个文件的符号链接实现不同命令创建默认配置使用make menuconfig可进入图形配置界的调用面,根据需求选择或禁用各项功能BusyBox支持超过300个常用Linux命令,包括shell解释器在选择配置时,可以禁用不需要的命令以减小体积,或调整命令ash、文件操作cp、mv、文本处理grep、sed、网络工选项以优化功能配置完成后,执行make具ifconfig、ping等,能满足嵌入式系统基本操作需求,同CROSS_COMPILE=arm-linux-gnueabihf-进行交叉时显著减小系统体积编译,最后使用make install创建所有命令的符号链接Linux内核裁剪与配置内核配置基础通过menuconfig等工具进行模块选择精简内核组件移除不需要的驱动和功能模块优化内核参数调整运行参数适应目标硬件Linux内核裁剪是嵌入式系统开发中的重要步骤,通过移除不必要的功能和驱动,可以减小内核体积、降低内存占用并提高启动速度内核配置主要通过make menuconfig图形界面、make config命令行或make defconfig默认配置等命令进行在menuconfig界面中,可以浏览所有配置选项,并将其设置为编译进内核Y、编译为模块M或禁用N常见的裁剪选项包括禁用不需要的文件系统支持、移除目标硬件不使用的驱动程序、关闭调试和追踪功能、优化内存管理参数等对于特定平台,可以使用厂商提供的默认配置作为起点,如树莓派的bcm2711_defconfig配置完成后,使用make命令编译内核,生成适合目标平台的精简内核映像设备树Device Tree基础设备树概念基本语法结构常见节点类型设备树是描述硬件平台的数据结构,采设备树使用类C语法,由节点和属性组设备树中常见节点包括cpu节点描述用树状结构表示系统硬件组件及其关系成节点表示设备或总线,使用花括号处理器信息;memory节点定义系统内它将硬件描述与内核代码分离,使同一定义;属性定义节点特性,采用名称=存大小和地址;soc节点包含片上系统内核映像可支持多种硬件平台,无需重值形式每个设备树必须有一个根节点组件;gpio、i2c、spi等总线节点定义新编译设备树源文件.dts使用特定语/,其下包含各类硬件节点如CPU、通信总线;外设节点如uart、法编写,编译后生成二进制文件.dtb内存、总线和外设等标准属性包括ethernet描述具体设备不同硬件平台供内核使用compatible兼容性、reg寄存器等的设备树结构大同小异,遵循统一规范设备树编写与调试设备树节点示例设备树调试方法以下是一个典型的I2C设备节点示例开发设备树时常见的调试方法包括
1.使用dtc工具检查语法dtc-I dts-O dts-o/dev/null input.dtsi2c@11112222{
2.查看已加载的设备树cat/proc/device-tree/路径/属性compatible=vendor,i2c-controller;
3.通过内核启动日志检查设备树加载情况reg=0x111122220x1000;clock-frequency=100000;
4.使用dtdiff工具比较两个设备树的差异#address-cells=1;
5.设置bootargs中的earlycon参数获取早期启动日志#size-cells=0;开发过程中,可以通过反复修改、编译、测试设备树来解决硬件识别和驱动匹配问题eeprom@50{compatible=at24,24c32;reg=0x50;pagesize=32;};};这个示例定义了一个I2C控制器及其下挂载的EEPROM设备,指定了地址、兼容性等信息Linux驱动开发总览字符设备驱动块设备驱动处理字节流数据,如串口、LED、按键等处理随机访问的块数据,如硬盘、Flash等使用file_operations结构体定义操作函数,存储设备使用通过cdev_init注册block_device_operations和request_queue机制网络设备驱动总线设备驱动处理网络数据包传输,如以太网卡、WiFi基于平台总线、I2C、SPI等通信总线的设等基于net_device结构和协议栈接口实备驱动框架,采用驱动与设备匹配机制现Linux驱动开发遵循模块化设计理念,驱动程序可以编译进内核或作为可加载模块根据设备特性和访问方式,驱动类型主要分为字符设备、块设备、网络设备和总线设备四大类驱动开发需要了解对应设备的硬件原理、寄存器操作和内核提供的框架接口在嵌入式系统中,除了传统驱动类型外,还涉及输入子系统input、GPIO、PWM、ADC等特定子系统现代Linux内核倾向于使用设备树描述硬件,通过驱动与设备匹配机制自动加载适配的驱动程序,而非传统的硬编码方式字符设备驱动原理及框架注册设备号使用register_chrdev_region或alloc_chrdev_region函数申请主次设备号,这些号码用于唯一标识一个字符设备初始化cdev结构创建并初始化cdev结构体,通过cdev_init函数将file_operations结构与cdev关联,然后调用cdev_add添加到系统实现文件操作函数编写open,read,write,ioctl等函数实现设备操作逻辑,这些函数通过file_operations结构体注册到内核释放资源在模块卸载时,调用cdev_del删除设备,unregister_chrdev_region释放设备号,并清理其他分配的资源字符设备是Linux中最基本的设备类型,以字节流方式访问,没有缓冲机制典型的字符设备包括串口、LED、按键等file_operations结构体是字符设备驱动的核心,定义了设备支持的文件操作函数集,如打开、关闭、读写和控制等通过这些函数,用户空间程序可以访问和控制硬件设备字符设备驱动开发实例#include#include#include#include#include#include#define DEVICE_NAME simple_led#define CLASS_NAME simple_led_class#define LED_GPIO17//使用的GPIO引脚编号static intmajor;static structclass*led_class;static structcdev led_cdev;static int led_openstruct inode*inode,struct file*file{printkKERN_INFO LED设备已打开\n;return0;}static ssize_tled_writestruct file*file,const char__user*buf,size_t count,loff_t*ppos{char kbuf
[2];if copy_from_userkbuf,buf,1return-EFAULT;//控制LEDif kbuf
[0]==1gpio_set_valueLED_GPIO,1;//打开LEDelse ifkbuf
[0]==0gpio_set_valueLED_GPIO,0;//关闭LEDreturn count;}static structfile_operations led_fops={.owner=THIS_MODULE,.open=led_open,.write=led_write,};static int__init led_initvoid{dev_t dev;int ret;//
1.申请设备号ret=alloc_chrdev_regiondev,0,1,DEVICE_NAME;if ret0{printkKERN_ERR无法分配设备号\n;return ret;}major=MAJORdev;//
2.初始化cdev结构cdev_initled_cdev,led_fops;led_cdev.owner=THIS_MODULE;ret=cdev_addled_cdev,dev,1;if ret0{printkKERN_ERR添加字符设备失败\n;unregister_chrdev_regiondev,1;return ret;}//
3.创建设备类和设备节点led_class=class_createTHIS_MODULE,CLASS_NAME;if IS_ERRled_class{printkKERN_ERR创建设备类失败\n;cdev_delled_cdev;unregister_chrdev_regiondev,1;return PTR_ERRled_class;}if IS_ERRdevice_createled_class,NULL,dev,NULL,DEVICE_NAME{printkKERN_ERR创建设备节点失败\n;class_destroyled_class;cdev_delled_cdev;unregister_chrdev_regiondev,1;return PTR_ERRled_class;}//
4.申请GPIO资源if gpio_requestLED_GPIO,led_gpio0{printkKERN_ERR申请GPIO失败\n;device_destroyled_class,dev;class_destroyled_class;cdev_delled_cdev;unregister_chrdev_regiondev,1;return-ENODEV;}//
5.设置GPIO为输出模式gpio_direction_outputLED_GPIO,0;printkKERN_INFO LED驱动初始化成功\n;return0;}static void__exit led_exitvoid{dev_t dev=MKDEVmajor,0;//释放GPIOgpio_freeLED_GPIO;//删除设备节点和类device_destroyled_class,dev;class_destroyled_class;//删除字符设备cdev_delled_cdev;//释放设备号unregister_chrdev_regiondev,1;printkKERN_INFO LED驱动卸载成功\n;}module_initled_init;module_exitled_exit;MODULE_LICENSEGPL;MODULE_AUTHOR嵌入式Linux教程;MODULE_DESCRIPTION简单的LED字符设备驱动;块设备与网络设备驱动简介块设备驱动特点网络设备驱动架构块设备以固定大小的块为单位进行数据传输,通常用于存储介质网络设备驱动负责处理网络数据包的发送和接收,如以太网卡、如硬盘、SD卡、U盘等块设备支持随机访问,可以从设备的WiFi适配器等与字符设备和块设备不同,网络设备不通过文任意位置读写数据,不必按顺序访问件系统访问,而是通过套接字接口与应用程序交互Linux内核为块设备提供了缓冲区和页缓存机制,提高I/O效网络驱动基于net_device结构体,需实现发送率块设备驱动需要实现request_queue处理I/O请求,或hard_start_xmit、配置set_config等方法驱动负责使用简化的gendisk框架相比字符设备,块设备驱动结构更硬件初始化、数据包收发和中断处理,而协议处理由内核网络协复杂,但提供了更高级的功能议栈完成通过netif_rx函数将接收的数据包提交给协议栈处理设备节点和udev机制设备节点基础mknod命令创建节点设备节点是位于/dev目录下的特殊文传统方法使用mknod命令手动创建设件,作为用户空间访问内核设备驱动的备节点,格式为mknod/dev/设接口传统上,设备节点分为字符设备备名类型主设备号次设备号例如,c和块设备b两种类型,分别由主设创建一个主设备号为254,次设备号备号和次设备号标识主设备号标识设为0的字符设备mknod备驱动,次设备号区分同类型的不同设/dev/mydev c2540手动方法适备实例用于固定设备配置的嵌入式系统,但在动态变化的环境中显得不够灵活udev自动管理机制现代Linux系统使用udev动态管理设备节点,它监听内核的设备事件,根据预定规则自动创建、删除设备节点udev规则文件存放在/etc/udev/rules.d/目录,通过属性匹配和条件判断控制设备节点的命名、权限和符号链接等这种方式使设备管理更加灵活,支持热插拔设备的动态识别常见外设接口及协议I2C总线SPI总线一种低速串行总线,使用SDA数据线和高速串行外设接口,使用MOSI、MISO、SCL时钟线两根线实现通信采用主从架SCLK和CS四根线实现全双工通信SPI采构,支持多主设备和多从设备,每个设备有用主从架构,一个主设备可通过片选线控制唯一的7位地址I2C适用于短距离、低速通多个从设备相比I2C,SPI具有更高的传信场景,常见于连接传感器、EEPROM等输速率,适合高速数据传输场景,如Flash低速外设存储器、显示屏等USB接口UART接口通用串行总线,提供高速、标准化的连接方通用异步收发器,一种简单的点对点串行通式,支持热插拔和即插即用USB采用主机信协议,使用TX发送和RX接收两根线实-设备架构,可连接多种外设如存储设备、摄现异步通信UART易于实现,无需时钟同像头、网络适配器等在嵌入式系统中,可步,广泛用于调试接口、外设连接和设备间作为主机Host或设备Device使用,提通信,是嵌入式系统最常用的串行接口之供灵活的扩展能力一SPI/I2C驱动开发流程设备信息描述在设备树中定义SPI/I2C设备节点,指定设备地址、兼容性字符串、时钟频率等参数对于SPI设备,还需指定片选信号、传输模式等;对于I2C设备,主要是驱动框架注册设备地址这些信息用于驱动与设备匹配创建spi_driver或i2c_driver结构体,实现probe、remove等回调函数,通过module_spi_driver或module_i2c_driver宏注册到内核驱动probe函数实现需提供compatible表,与设备树中的兼容性字符串匹配,实现自动加载probe函数在驱动与设备匹配成功时调用,负责初始化设备、分配资源、注册设备功能通常包括获取设备树属性、申请GPIO资源、初始化设备工作模式、数据交互接口创建sysfs接口或注册特定子系统(如input、IIO等)实现设备数据读写函数,使用spi_read/spi_write或i2c_master_send/i2c_master_recv等API与硬件交互可能需要实现中断处理程序响应设备事件,或创建工作队列处理异步任务完善错误处理和资源管理确保驱动稳定性GPIO子系统详解
4.4+内核版本支持新的GPIO接口从Linux
4.4版本开始引入,提供统一抽象256典型GPIO数量普通嵌入式平台支持的GPIO引脚数2基本操作模式输入或输出两种基本工作模式3访问方式内核空间API、字符设备和sysfs三种接口GPIO通用输入输出是嵌入式系统中最基本的接口,用于读取或控制数字信号Linux内核提供了完善的GPIO子系统,实现对GPIO硬件的抽象和统一管理在内核空间中,开发者可以使用gpio_request申请引脚,gpio_direction_input/gpio_direction_output设置方向,gpio_get_value/gpio_set_value读写状态用户空间可通过sysfs/sys/class/gpio/或新的字符设备/dev/gpiochipX访问GPIO使用sysfs接口时,首先向export文件写入GPIO编号以导出引脚,然后在对应目录下设置direction和value字符设备接口则通过ioctl调用实现GPIO控制,性能更优GPIO子系统还支持中断处理、去抖动和引脚复用等高级功能,为各类输入设备和简单控制提供了基础IRQ(中断)机制和驱动开发中断申请流程中断是硬件设备通知CPU处理事件的机制,在驱动中处理中断首先需要申请中断线通过request_irq函数申请中断,指定中断号、处理函数、触发方式、设备名称和私有数据如果中断线已被占用,申请会失败驱动卸载时必须调用free_irq释放中断资源中断处理程序编写中断处理程序是一个特殊函数,在中断发生时由内核调用它接收两个参数中断号和传递给request_irq的私有数据处理程序应尽量简短快速,只完成必要的硬件操作如清除中断标志,将耗时工作推迟到下半部执行返回IRQ_HANDLED表示中断已处理,IRQ_NONE表示不是本设备中断中断下半部处理为避免中断处理程序长时间占用系统,Linux提供下半部机制处理耗时任务主要的下半部机制包括tasklet小型、单一CPU任务、工作队列可睡眠的内核线程和软中断高优先级内核事件在上半部中通常只保存必要状态并调度下半部,实际数据处理在下半部完成,例如使用schedule_work安排工作队列任务内核模块机制与Makefile内核模块基础概念模块编译Makefile内核模块是可动态加载和卸载的内核代码,允许在不重启系统的情况下扩展内核功能模内核模块使用特殊的Makefile格式编译,通常包含以下部分块通常用于实现设备驱动、文件系统或系统调用等功能,以.ko文件形式存在模块必须导出init_module和cleanup_module函数或使用module_init/module_exit#指定要编译的模块名和源文件宏,分别在加载和卸载时调用obj-m:=mymodule.omymodule-objs:=file
1.o file
2.o#多文件模块使用insmod命令加载模块,rmmod命令卸载模块,lsmod命令查看已加载模块模块可以声明模块参数module_param宏,允许加载时传递参数调整行为模块间可通#指定内核源码目录过EXPORT_SYMBOL宏导出函数和变量供其他模块使用,建立依赖关系KDIR:=/lib/modules/$shell uname-r/build#默认目标编译模块all:make-C$KDIR M=$PWD modules#清理目标清除编译产物clean:make-C$KDIR M=$PWD clean使用make命令调用此Makefile将编译生成.ko格式的内核模块编译时会自动使用与内核匹配的编译选项,确保模块与内核兼容交叉编译时需修改KDIR指向目标架构的内核源码目录,并设置ARCH和CROSS_COMPILE变量嵌入式Linux应用开发C基础交叉编译工具链配置常用头文件与库嵌入式应用开发通常需要交叉编译环嵌入式Linux应用开发中常用的头文境确保交叉编译器位于PATH环境件包括stdio.h标准I/O、变量中,并使用正确的前缀如arm-stdlib.h内存管理、linux-gnueabihf-调用gcc、g++unistd.hPOSIX API、等工具编译时可能需要指定--fcntl.h文件控制、sys/ioctl.h设sysroot参数指向目标系统的根文件备控制、pthread.h线程等链接系统,以便编译器找到正确的头文件时常用库包括libcC标准库、和库文件libpthread线程支持、libm数学函数等,使用-l参数指定Makefile构建基础使用Makefile管理应用程序构建过程,定义编译选项、依赖关系和目标基本结构包括变量定义CC、CFLAGS等、目标规则和依赖关系嵌入式开发中需要指定交叉编译器、包含路径-I和库路径-L,注意静态链接-static或动态链接选择进程和多线程基础进程创建与控制线程创建与同步Linux使用fork系统调用创建新进程,新进程是父进程的完整线程是轻量级进程,共享进程的地址空间和资源Linux使用副本,但有独立的进程IDfork在父进程中返回子进程PID,POSIX线程pthread库实现线程支持在子进程中返回0进程可通过exec族函数execl,execv等pthread_create函数创建新线程,指定线程函数和参数;加载新程序替换当前程序映像,实现程序切换pthread_join等待线程结束并回收资源;pthread_exit终止当前线程wait/waitpid用于父进程等待子进程结束,获取退出状线程间共享数据需同步机制避免竞态条件态kill函数向进程发送信号,可用于进程间通信或终止进pthread_mutex_lock/unlock实现互斥锁保护临界程进程间数据完全隔离,需使用特定IPC机制通信进程调度区;pthread_cond_wait/signal提供条件变量实现线优先级可通过nice或setpriority调整程协作;pthread_rwlock提供读写锁支持并发读取合理使用线程可提高程序响应性和性能,但增加了复杂性和潜在错误信号与进程间通信IPC信号Signal管道Pipe与命名管道共享内存SharedFIFO Memory信号是软件中断,用于通知进程发生的事件常见信号管道是单向数据流通道,通共享内存是最快的IPC机制,包括SIGINT中断、常用于父子进程间通信允许多个进程直接访问同一SIGTERM终止、pipe创建无名管道,返回内存区域shmget创建共SIGSEGV段错误等进程读写文件描述符对;享内存段,shmat将其附可使用signal或mkfifo创建命名管道,可加到进程地址空间进程可sigaction注册信号处理函用于无关进程间通信管道直接读写共享内存,但需使数,捕获并处理特定信号数据以先进先出方式传输,用信号量等同步机制避免冲信号适合简单通知,不适合具有阻塞特性,适合流式数突适合大量数据高效传输传输大量数据据传输场景消息队列MessageQueue消息队列提供结构化消息传递机制,支持多对多通信msgget创建队列,msgsend/msgrcv发送接收消息消息具有类型字段,支持选择性接收相比管道更灵活,支持非阻塞操作,但性能略低适合命令和控制信息传递文件操作与IO模型1基本文件操作2阻塞IO模型Linux文件操作基于一切皆文件理念,使用统一接口访问常规文件、默认文件操作为阻塞模式,read/write调用会阻塞进程直到操作设备、管道等open打开文件返回文件描述符;read/write读完成对慢速设备如终端、网络套接字,阻塞可能导致进程长时间等待写数据;lseek调整文件位置;close关闭文件释放资源文件描述适合简单应用,实现简单但效率不高通过O_NONBLOCK标志可符是进程级资源,fork后子进程继承父进程的文件描述符改为非阻塞模式,但需轮询检查状态3多路复用IO模型4异步IO模型IO多路复用允许单线程监视多个文件描述符,仅在有事件发生时处理,异步IOAIO允许进程发起IO请求后立即返回继续执行,IO完成时通避免轮询浪费select函数监视描述符集合,有超时机制;poll提过信号或回调通知Linux通过libaio库或io_uring新特性支持异供类似功能但无大小限制;epoll是Linux特有的高效实现,适合高并步IO相比多路复用更高效,但编程复杂度高,适合高性能服务器和发场景多路复用是网络服务器的常用模型数据库系统网络编程基础创建套接字使用socket函数创建通信端点,指定协议族AF_INET/AF_UNIX、类型SOCK_STREAM/SOCK_DGRAM和协议绑定地址服务器使用bind将套接字关联到特定地址和端口,允许客户端连接监听连接TCP服务器调用listen开始接受连接请求,设置等待队列长度建立连接服务器用accept接受客户端连接,客户端用connect连接到服务器数据交换通过read/write或专用的send/recv函数传输数据Linux网络编程基于套接字SocketAPI,提供了标准化的网络通信接口TCP传输控制协议提供可靠的、面向连接的通信,适合需要保证数据完整性的应用,如文件传输、Web访问等UDP用户数据报协议提供无连接的、不可靠的通信,适合实时性要求高的应用,如视频流、游戏等在客户端-服务器模型中,服务器通常监听在固定端口,等待客户端连接使用套接字进行网络编程时,需要考虑字节序转换htons/ntohs、IP地址转换inet_addr/inet_ntoa、超时处理和错误恢复等问题嵌入式系统的网络编程与桌面系统类似,但需要更注重资源消耗和稳定性多进程/多线程网络服务器样例基础服务器架构设计支持并发连接处理的网络服务器框架I/O多路复用实现使用select/poll/epoll监控多个客户端连接线程池处理请求预创建线程池提高响应效率和系统稳定性实现高性能网络服务器的常见模式包括多进程模型、多线程模型和事件驱动模型多进程模型为每个连接创建新进程,进程间完全隔离,稳定性好但资源消耗大;多线程模型使用线程处理连接,共享地址空间,资源占用小但需同步机制;事件驱动模型使用I/O多路复用在单线程中处理多个连接,效率高但编程复杂线程池是一种优化方案,预先创建固定数量线程,避免频繁创建销毁线程的开销主线程接收连接并分发给工作线程,工作线程从任务队列获取请求并处理这种设计限制了系统资源使用,提高了并发处理能力和响应速度,适合嵌入式系统等资源受限环境实现时需注意线程同步、任务队列管理和优雅关闭等问题Qt与图形界面开发简介Qt是跨平台的C++应用程序框架,广泛用于嵌入式Linux的图形界面开发Qt forEmbedded Linux专为嵌入式设备优化,支持各种显示硬件和输入设备Qt提供两种UI开发方式基于C++的Qt Widgets和声明式的Qt QuickQMLWidgets提供传统桌面风格控件,适合复杂应用;QML适合现代触控界面,开发效率高在嵌入式系统上使用Qt需要交叉编译环境首先配置Qt的交叉编译工具链,然后创建项目并编写界面代码一个简单的Hello World应用包括创建主窗口、添加控件和连接信号槽Qt CreatorIDE提供了集成的开发环境,支持UI设计、代码编辑和调试Qt还提供丰富的模块如网络、多媒体、数据库等,方便开发全功能应用程序常见嵌入式Linux文件系统JFFS2闪存日志文件系统专为NOR Flash设计,支持压缩和磨损均衡YAFFS2又一个闪存文件系统针对NAND Flash优化,支持坏块管理UBIFS不受约束的闪存文件系统适用于大容量NAND Flash,性能优于JFFS2EXT4第四扩展文件系统通用文件系统,适用于SD卡和eMMC存储选择合适的文件系统对嵌入式设备的性能和可靠性至关重要Flash存储器有写入次数限制,因此专用文件系统如JFFS
2、YAFFS2和UBIFS实现了磨损均衡和坏块管理,延长存储寿命JFFS2适合小容量NOR Flash;YAFFS2针对NAND Flash设计,处理坏块和位错误;UBIFS是JFFS2的继任者,适合大容量NAND设备,支持日志功能提高可靠性对于SD卡和eMMC等基于闪存的块设备,通常使用传统文件系统如ext4或FAT32ext4提供日志功能和高级特性;FAT32兼容性好但功能有限;F2FS是专为闪存优化的新型文件系统文件系统挂载使用mount命令,如mount-t ubifsubi0:rootfs/mnt在系统设计时应考虑文件系统特性、存储介质类型和应用需求,选择最合适的文件系统类型Flash存储驱动MTD基础MTD子系统概述NAND与NOR Flash区别内存技术设备Memory TechnologyDevice,MTD子系NAND Flash和NOR Flash是两种主要的闪存技术,具有不统是Linux内核中处理Flash存储器的框架它抽象了不同类型同特性Flash设备的底层差异,提供统一访问接口MTD层位于物理•NOR Flash支持随机访问,可直接执行代码,读取速度设备驱动和文件系统之间,处理Flash特有的擦除、写入和坏块快,写入较慢,常用于存储引导程序管理等操作•NAND Flash成本低、密度高,读写以页通常512/2048MTD将Flash设备表示为分区partition,每个分区可用于不字节为单位,需处理坏块,通常用于存储数据和操作系统同用途如引导加载程序、内核或文件系统MTD设备可通过两种Flash都需要先擦除通常以块为单位再写入,这一特性要/dev/mtdX字符设备或/dev/mtdblockX块设备访问,求特殊的驱动处理和文件系统支持MTD子系统提供了适合这前者提供直接访问,后者模拟块设备接口两种Flash特性的不同驱动实现常用MTD命令包括mtdinfo查看MTD设备信息,flash_eraseall擦除整个分区,nanddump/nandwrite读写NAND设备,以及ubiattach/ubidetach挂载卸载UBI卷通过这些工具可以管理和维护Flash存储设备电源管理与低功耗设计应用层省电优化优化算法和任务调度减少CPU使用率CPU频率和电压调节动态调整处理器频率和电压满足性能需求设备运行时电源管理未使用设备自动进入低功耗状态系统睡眠状态控制整个系统进入挂起或休眠模式硬件电源控制电路PMIC和电源域管理,控制电源开关电源管理对电池供电的嵌入式系统尤为重要Linux内核提供了完善的电源管理框架,包括CPUFreq动态频率调节、CPUIdle处理器空闲管理、Runtime PM运行时电源管理和系统级电源管理休眠/挂起现代SoC通常集成PMIC电源管理集成电路,控制多个电源域,并通过I2C/SPI接口接受软件控制实现低功耗设计需采取多层次策略硬件设计上选用低功耗元器件,设计合理的电源域;内核配置中启用电源管理相关选项;驱动实现中支持设备挂起/恢复和运行时PM;应用设计上避免忙等待,使用事件驱动模型通过sysfs接口/sys/power/,/sys/devices/.../power/可以控制和监控系统电源状态,实现自定义电源管理策略交叉调试与gdb用法调试环境设置交叉调试涉及两个系统开发主机运行gdb和目标板运行gdbserver首先需要在开发主机上安装目标架构的gdb,如arm-linux-gnueabihf-gdb;然后在目标板上安装gdbserver编译被调试程序时,需加入-g选项保留调试信息,并避免过高优化-O0或-O1以保持代码可读性启动远程调试会话在目标板上运行命令gdbserver HOST:PORT program[args],其中HOST:PORT指定连接信息如
192.
168.
1.100:2000,program是被调试程序在开发主机上启动交叉编译gdb,使用target remote命令连接目标板target remote
192.
168.
1.101:2000连接成功后,gdb会显示程序停在入口点,可以开始调试常用调试命令gdb提供丰富的调试功能break设置断点、watch监视变量、step/next单步执行、continue继续运行、print打印变量、backtrace显示调用栈、info显示程序信息、examine检查内存等可以使用条件断点break ifcondition针对特定条件触发,或使用命令command在断点处自动执行操作调试多线程程序时,info threads查看线程,thread N切换线程日志系统与调试技巧内核日志机制日志分析方法常见问题排查技巧Linux内核使用printk函数输出日志,系统问题排查通常从日志分析开始内存泄漏可通过valgrind检测或监控可指定不同优先级KERN_EMERG到dmesg|grep ERROR查找内核错误;/proc/meminfo;性能问题可使用KERN_DEBUG日志消息进入内核环tail-f/var/log/syslog实时监控系统日top/htop查看资源占用,perf分析热点形缓冲区,可通过dmesg命令查看,或通志;journalctl-f跟踪systemd日志函数;文件系统问题可使用fsck检查一致过/proc/kmsg和/dev/kmsg设备读取分析时关注时间顺序,寻找错误前后的相性;网络问题可通过ping/traceroute测syslog守护进程如rsyslogd可将内核消关事件,注意设备驱动加载失败、资源不试连通性,tcpdump捕获分析数据包;息存储到文件,通常在/var/log/目录下足、硬件故障等常见问题模式对于死机问题,检查内核oops/panic消息和硬件温度传感器数据安全机制与加固措施文件权限与访问控制MAC安全框架Linux通过用户/组ID和权限位强制访问控制MAC提供比传统rwx控制文件访问嵌入式系统DAC更严格的安全策略应定义合理的用户帐户,为不同服SELinux是NSA开发的MAC框务分配专用用户,避免以root运架,通过安全策略限制程序行为,行程序可使用chmod、即使被攻破也难以提权chown设置恰当权限,禁止关键AppArmor是另一个较轻量的文件的非授权访问目录应避免MAC实现,基于路径控制程序访777权限,可执行文件避免SUID问嵌入式系统可根据资源情况选位除必要情况择合适的MAC框架,通过策略限制各组件权限网络安全加固嵌入式设备经常连接网络,面临远程攻击风险应禁用不必要服务,关闭未使用端口,启用防火墙iptables/nftables限制连接使用SSH替代telnet,启用密钥认证禁用密码登录避免硬编码密钥和证书,考虑使用安全启动验证固件完整性,定期更新系统修复已知漏洞自动化构建与CI简介源码获取从版本控制系统如Git自动拉取最新代码,包括内核、工具链和应用程序源码编译构建使用构建系统如Buildroot、Yocto自动编译生成目标映像,包括内核、根文件系统和应用程序自动测试在模拟器或实际硬件上运行自动化测试套件,验证功能正确性和性能指标打包发布将验证通过的映像打包,生成固件升级包,并发布到指定位置供部署使用自动化构建系统大幅提高了嵌入式Linux开发效率和产品质量Buildroot是一个相对简单的框架,使用Makefile和Kconfig系统,通过菜单配置生成定制化嵌入式Linux系统它集成了交叉编译工具链构建、内核配置、根文件系统生成等功能,适合小型项目和快速原型开发Yocto Project是一个更复杂但更强大的构建框架,基于OpenEmbedded核心,使用配方recipe描述组件构建过程它支持多种硬件架构,提供包管理、依赖解析和层次化配置机制,适合大型商业项目持续集成CI将自动化构建与自动化测试结合,使用Jenkins、GitLab CI等工具在代码更改后自动触发构建和测试流程,及时发现问题并保证产品质量软件包管理与升级机制软件包制作部署更新服务器将应用程序和依赖打包成opkg/ipkg格式建立软件包仓库和分发机制验证与安装设备获取更新验证包完整性并执行更新流程客户端检查并下载更新包嵌入式Linux系统通常使用轻量级包管理器如opkgOpenWrt PackageManager或ipkgItsy PackageManagement System,它们是Debian包管理系统的简化版本这些工具支持软件包的安装、升级、删除和依赖管理,但资源占用更少软件包通常是.ipk或.opkg格式,包含二进制文件、配置文件、依赖信息和安装脚本OTAOver-The-Air升级是物联网设备的关键功能,允许远程更新设备固件实现OTA系统需考虑多个方面安全传输机制HTTPS、升级包签名验证、原子更新避免中断导致设备不可用、回滚机制升级失败时恢复常见的OTA方案包括双分区A/B系统,允许在备用分区安装更新,验证成功后切换;以及基于OSTree或Mender等工具的文件系统级差分更新,减少传输数据量嵌入式Linux音视频子系统ALSA音频架构视频采集与处理框架高级Linux声音架构Advanced LinuxSound Linux视频子系统主要基于V4L2Video forLinux2框架,Architecture,ALSA是Linux内核的标准音频子系统,提供提供摄像头和视频设备的统一接口V4L2支持视频捕获、编码了硬件抽象层和用户空间库ALSA包括内核驱动组件和用户空/解码、格式转换等功能,通过/dev/videoX设备节点访问间API,支持多种声卡和音频功能视频处理流程通常包括打开设备、设置格式分辨率、像素格ALSA的核心概念包括PCM设备播放/录音、混音器控制、式、申请缓冲区、启动流、处理帧数据许多嵌入式SoC集成MIDI接口等应用程序通过ALSA库libasound访问音频硬硬件视频编解码器和ISP图像信号处理器,通过专用驱动加速件,可直接操作或使用更高级的库如PulseAudio、视频处理开发视频应用时,可直接使用V4L2API或选择GStreamer构建复杂应用在嵌入式系统中,常需定制GStreamer、FFmpeg等多媒体框架简化开发,实现摄像头ASOCALSA Systemon Chip驱动,适配特定SoC和编解预览、视频录制、流媒体传输等功能码器组合嵌入式GUI中间件选型框架名称资源占用开发语言特点Qt中高C++/QML功能丰富,跨平台,完整解决方案GTK中C/Vala开源桌面环境标准,GNOME默认工具包LVGL低C轻量级,适合微控制器,支持触控DirectFB低C直接访问帧缓冲,性能优先MicroUI极低Java/C专为IoT设备设计,支持向量图形选择合适的GUI框架对嵌入式产品至关重要Qt是最流行的跨平台框架,提供完整的UI控件、网络、多媒体等模块,适合高性能设备和复杂应用,但占用资源较多GTK源于GIMP项目,是许多Linux桌面应用的基础,API成熟稳定,但移动/触控支持不如Qt完善LVGL是近年流行的轻量级框架,仅需少量RAM和闪存,提供现代化视觉效果和触控支持,适合资源受限设备选型时需考虑多方面因素硬件资源处理器、内存、存储、开发效率、产品需求复杂度、团队技术背景、许可证兼容性等高端产品通常选择Qt,获得更好的开发体验和用户体验;中低端设备可考虑LVGL或DirectFB,满足基本交互需求同时节省资源;特定行业应用可能有专用解决方案如汽车行业的Qt AutomotiveSuite等AI与物联网IoT案例实战TensorFlow LiteMQTT通信协议边缘计算架构移植MQTT消息队列遥测边缘计算将数据处理从TensorFlow Lite是传输是轻量级发布/订云端迁移到设备本地,针对嵌入式设备优化的阅消息协议,为资源受减少延迟和带宽需求机器学习框架,支持限设备和低带宽网络设嵌入式Linux设备可作ARM、x86等架构计在Linux上可使用为边缘节点,运行轻量移植过程包括交叉编Mosquitto、Paho级容器如Docker或译、模型量化与优化,等库实现MQTT客户LXC托管应用,实现以及硬件加速集成许端,连接到云平台或本本地AI推理、数据过滤多嵌入式SoC集成了专地代理服务器和快速响应,仅将必要用AI加速器如NPU、MQTT支持QoS级别数据传输到云端存储和DSP,可通过TF Lite控制消息可靠性,适合分析Delegate机制利用这传感器数据采集和设备些硬件控制实例智能网关系统设计云平台交互层实现与云服务的安全通信应用逻辑层2业务处理、数据分析和决策控制协议转换层多种物联网协议的互通与转换设备接入层物理接口和通信驱动支持智能网关作为物联网系统的核心节点,连接各类终端设备和云平台系统架构采用分层设计,硬件基于ARM Cortex-A处理器,运行裁剪的Linux系统设备接入层支持多种物理接口以太网、WiFi、蓝牙、Zigbee等,通过驱动程序和硬件抽象层管理底层通信协议转换层实现不同物联网协议MQTT、CoAP、Modbus等的互通,使异构设备能够协同工作应用逻辑层包含数据处理引擎、规则引擎和本地存储组件,支持边缘计算功能,可在本地完成部分数据分析和决策,减轻云端负担云平台交互层负责与云服务的安全通信,使用TLS/DTLS加密,实现设备注册、数据上报和指令下发系统采用systemd管理服务,使用Docker容器隔离应用,支持OTA远程升级和安全启动机制,确保系统可靠性和安全性实验指导LED驱动开发与测试硬件准备连接LED到开发板GPIO引脚,通常需要一个限流电阻如220Ω串联确认连接的GPIO引脚号,查阅开发板文档了解引脚功能和编号映射关系准备好电源、串口线、网络等调试必需品驱动代码编写创建基于字符设备的LED驱动程序,实现probe函数识别设备,open/release处理设备打开/关闭,write函数控制LED状态使用gpio_request申请GPIO资源,gpio_direction_output设置输出方向,gpio_set_value控制引脚状态设计合理的错误处理流程确保资源正确释放编译与加载编写Makefile定义编译规则,指定内核源码路径和交叉编译工具链执行make命令编译生成.ko模块文件将模块文件传输到目标板,使用insmod命令加载驱动,确认/dev目录下创建了相应设备节点检查dmesg输出验证加载成功功能测试编写简单测试程序或使用命令行工具验证LED控制功能例如,使用echo1/dev/myled点亮LED,echo0/dev/myled熄灭LED验证不同开关状态,测试错误处理如权限问题、无效输入等记录测试结果并分析性能,如响应时间综合项目嵌入式Linux智能设备开发需求分析与设计明确功能需求、性能指标和硬件限制,创建系统架构图和模块划分系统平台构建选择适合的硬件平台,配置引导加载程序、内核和根文件系统驱动与应用开发实现所需外设驱动,开发核心应用功能和用户界面测试与优化进行功能测试、性能测试和稳定性测试,优化系统配置综合项目旨在将课程所学知识应用到实际嵌入式产品开发中项目以智能家居控制终端为例,集成温湿度传感器、摄像头、触摸屏和网络连接功能学生将完整经历嵌入式产品开发流程,从需求分析到最终实现任务分解包括系统启动与配置引导加载、内核裁剪、文件系统定制;驱动开发传感器驱动、摄像头驱动、触摸屏驱动;应用层开发GUI界面、数据采集与处理、网络通信评估标准包括功能完整性是否实现所有规定功能、代码质量结构清晰、注释完善、性能指标启动时间、响应速度、资源占用、稳定性长时间运行无崩溃和文档质量设计文档、用户手册成果展示环节要求学生演示系统功能,解释技术实现,并回答评审问题通过项目实战,学生能将碎片化知识整合为系统能力,为未来职业发展打下基础总结与拓展学习建议实时系统嵌入式安全探索实时LinuxRT-PREEMPT补丁和学习嵌入式系统安全加固技术,包括安全启动、固件PREEMPT_RT内核,了解调度延迟、优先级反转加密、入侵检测等研究常见漏洞如缓冲区溢出、权等实时系统概念学习Xenomai、RTAI等双内核限提升的防护方法推荐学习安全编程规范和安全审实时解决方案,以及FreeRTOS等RTOS系统,适计工具,如MISRA C标准、Coverity等应不同实时需求场景内核与驱动进阶云与边缘计算深入学习Linux内核源码分析,探索高级驱动开发技术如DMA、中断控制器、时钟框架等参与开源社学习嵌入式设备与云平台集成技术,包括容器化区贡献,阅读《Linux内核设计与实现》等经典著作Docker/K8s、微服务架构等了解AWS IoT、关注内核邮件列表和LWN.net等资源,了解最新发Azure IoT等云服务,掌握边缘计算框架如AWS展Greengrass、Azure IoTEdge的部署和使用方法1本课程系统介绍了嵌入式Linux开发的核心知识,从系统架构、开发环境到驱动开发、应用编程,构建了完整的知识体系通过理论学习和实践项目,学生应已掌握基本的嵌入式Linux开发能力,能够独立完成简单的嵌入式系统设计和实现嵌入式Linux领域发展迅速,建议持续学习并关注新技术趋势推荐资源包括开源项目Linux内核、Buildroot、Yocto等源码;技术社区如Stack Overflow、嵌入式Linux会议ELC;专业书籍如《嵌入式Linux系统开发完全手册》、《Linux设备驱动开发详解》等最重要的是通过实际项目积累经验,解决真实问题,不断提升综合能力和工程素养。
个人认证
优秀文档
获得点赞 0