具体描述
编辑推荐
国内领先的嵌入式培训机构华清远见出品,作者具有多年从业经验,真正从企业用人需求出发,培养和提升读者能力;
历经市场考验,第三次修订改版;
书中配有大量微课,详细讲解重点难点 内容简介
本书较为全面地介绍了嵌入式开发中C语言编程的基础知识。全书共11章,内容包括嵌入式Linux C语言开发工具、数据、数据的输入输出、运算符和表达式、程序结构和控制语句、数组、指针、函数、用户自定义数据类型、嵌入式C语言的高级用法、嵌入式Linux内核常见数据结构。每章都提供详细的练习题和视频讲解,通过练习、操作实践及相关视频,帮助读者巩固所学的内容。
本书可以作为院校嵌入式相关专业和计算机相关专业的教材,也可以作为计算机软硬件培训班教材,还可供嵌入式研究方向的专业人员和广大计算机爱好者自学使用。 作者简介
刘洪涛,北京华清远见科技信息有限公司技术总监,ARM公司全球认证讲师。参与编写过几十本专业图书;国内知名物联网方向技术顾问;首批高校物联网专业建设教学指导委员会专家委员会成员;丰富的嵌入式及物联网系统软、硬件产品开发经验;主持开发过多个大型嵌入式及物联网项目,涉及工业控制、网络、通讯、消费电子等众多领域。 目录
第1章 嵌入式Linux C语言开发工具 1
1.1 嵌入式Linux下C语言概述 2
1.1.1 C语言简史 2
1.1.2 C语言特点 2
1.1.3 嵌入式Linux C语言编程环境 3
1.2 嵌入式Linux编辑器vi的使用 3
1.2.1 vi的基本模式 4
1.2.2 vi的基本操作 4
1.2.3 vi的使用实例分析 8
1.3 嵌入式Linux编译器GCC的使用 9
1.3.1 GCC概述 9
1.3.2 GCC编译流程分析 10
1.3.3 GCC警告提示 12
1.3.4 GCC使用库函数 14
1.3.5 GCC代码优化 15
1.4 嵌入式Linux调试器GDB的使用 16
1.4.1 GDB使用实例 16
1.4.2 设置/删除断点 19
1.4.3 数据相关命令 20
1.4.4 调试运行环境相关命令 20
1.4.5 堆栈相关命令 21
1.5 make工程管理器 21
1.5.1 Makefile基本结构 22
1.5.2 Makefile变量 23
1.5.3 Makefile规则 26
1.5.4 make使用 27
小结 28
思考与练习 28
第2章 数据 29
2.1 ANSI C与GNU C 30
2.1.1 ANSI C简介 30
2.1.2 GNU C简介 30
2.2 基本数据类型 31
2.2.1 整型家族 31
2.2.2 实型家族 33
2.2.3 字符型家族 35
2.2.4 枚举家族 37
2.2.5 指针家族 38
2.3 变量与常量 39
2.3.1 变量的定义 39
2.3.2 typedef 40
2.3.3 常量的定义 41
2.3.4 作用域 41
2.3.5 存储模型 44
2.4 预处理 47
2.4.1 预定义 47
2.4.2 文件包含 53
2.4.3 条件编译 53
2.5 需要注意的问题 55
2.5.1 字长和数据类型 55
2.5.2 数据对齐 56
2.5.3 字节序 56
小结 57
思考与练习 57
第3章 数据的输入输出 58
3.1 数据的输出 59
3.1.1 字符输出函数putchar 59
3.1.2 格式化输出函数printf 59
3.2 数据的输入 62
3.2.1 字符输入函数getchar 62
3.2.2 格式化输入函数scanf 63
3.3 数据输入输出综合示例 68
3.4 字符串输入输出函数 70
小结 71
思考与练习 72
第4章 运算符和表达式 73
4.1 概述 74
4.2 运算符和表达式 74
4.2.1 算术运算符和表达式 74
4.2.2 赋值运算符和表达式 77
4.2.3 逗号运算符和表达式 80
4.2.4 位运算符和表达式 81
4.2.5 关系运算符和表达式 84
4.2.6 逻辑运算符和表达式 86
4.2.7 sizeof操作符 89
4.2.8 条件运算符 90
4.2.9 运算符优先级总结 91
小结 93
思考与练习 93
第5章 程序结构和控制语句 94
5.1 C语言程序结构 95
5.2 C语言控制语句 95
5.2.1 条件判断语句 95
5.2.2 循环语句 105
5.2.3 转向语句 109
小结 112
思考与练习 112
第6章 数组 114
6.1 一维数组 115
6.1.1 数组的定义 115
6.1.2 一维数组的引用 115
6.1.3 一维数组的初始化 117
6.1.4 一维数组的内存分配 118
6.1.5 一维数组程序举例 119
6.2 多维数组 121
6.2.1 多维数组定义及初始化 121
6.2.2 二维数组的内存分配 122
6.2.3 深入理解二维数组 123
6.2.4 二维数组程序举例 124
6.3 字符数组 126
6.4 字符串 127
6.4.1 字符串的定义 127
6.4.2 字符串的输入输出 127
6.4.3 字符串处理函数 129
小结 133
思考与练习 133
第7章 指针 134
7.1 指针基础 135
7.1.1 指针变量的定义 135
7.1.2 指针变量的赋值 135
7.1.3 指针变量的引用 136
7.2 指针的运算 139
7.2.1 指针的算术运算 140
7.2.2 指针的关系运算 141
7.2.3 空指针 144
7.3 指针与数组 145
7.3.1 指针与一维数组 145
7.3.2 指针与多维数组 147
7.4 多级指针 150
7.4.1 多级指针的定义及引用 150
7.4.2 多级指针的运算 152
7.5 指针数组 152
7.5.1 指针数组的定义及初始化 152
7.5.2 理解指针数组名 153
7.6 const与指针 155
7.7 void指针 157
7.8 字符指针 158
7.8.1 字符串 158
7.8.2 字符指针数组 159
小结 160
思考与练习 161
第8章 函数 162
8.1 函数基础 163
8.1.1 函数定义和声明 163
8.1.2 函数的调用、参数传递和返回值 164
8.1.3 函数和数组 171
8.1.4 main函数的参数 173
8.2 指针函数 174
8.2.1 指针函数的定义和使用 174
8.2.2 指针函数程序举例 177
8.3 函数指针 179
8.3.1 函数指针的声明 179
8.3.2 定义函数指针类型 180
8.3.3 函数指针数组 181
8.3.4 函数指针程序举例 182
8.4 递归函数 184
8.4.1 递归函数的定义 184
8.4.2 函数调用机制说明 185
8.4.3 递归调用的形式 185
8.4.4 递归的条件 186
8.5 回调函数 187
8.5.1 回调函数的定义 187
8.5.2 回调函数实现机制 188
8.5.3 自定义回调函数 188
8.5.4 嵌入式开发中常见的回调函数 189
8.6 attribute机制介绍 189
小结 195
思考与练习 195
第9章 用户自定义数据类型 196
9.1 结构体 197
9.1.1 结构体的定义 197
9.1.2 结构体变量的声明、使用及初始化 199
9.1.3 结构体数组 206
9.1.4 结构体指针 210
9.2 位域 211
9.2.1 位域的定义 211
9.2.2 位域变量的说明 213
9.2.3 位域的使用 214
9.3 共用体 215
9.4 枚举 217
9.4.1 枚举类型的定义 218
9.4.2 枚举变量的声明和使用 219
小结 221
思考与练习 221
第10章 嵌入式C语言的
高级用法 223
10.1 内存管理 224
10.2 动态内存的申请和释放 225
10.2.1 malloc函数 225
10.2.2 free函数 226
10.2.3 关于野指针 228
10.3 堆和栈的区别 230
10.4 动态内存程序举例 231
10.5 C语言和汇编语言的接口 233
10.5.1 内联汇编的语法 233
10.5.2 编译器优化介绍 236
10.5.3 C语言关键字volatile 236
10.5.4 “memory”描述符 236
小结 236
思考与练习 236
第11章 嵌入式Linux内核常见数据结构 239
11.1 链表 240
11.1.1 单向链表 240
11.1.2 双向链表 243
11.1.3 循环链表 245
11.1.4 ARM Linux中链表使用实例 245
11.2 树、二叉树、平衡树 247
11.2.1 树的定义 247
11.2.2 二叉树 248
11.2.3 平衡树 254
11.2.4 ARM Linux中红黑树使用实例 255
11.3 哈希表 258
11.3.1 哈希表的概念及作用 258
11.3.2 哈希表的构造方法 259
11.3.3 哈希表的处理冲突方法 260
11.3.4 ARM Linux中哈希表
使用实例 262
小结 263
思考与练习 263
嵌入式Linux C语言程序设计实用指南:从入门到精通 内容概述 本书是一本系统阐述嵌入式Linux C语言程序设计的实用指南,旨在帮助读者从零基础开始,逐步掌握嵌入式Linux系统下的C语言开发技能,并能独立完成实际项目。本书内容涵盖了嵌入式Linux开发所需的各个关键环节,包括开发环境的搭建、Linux基础命令的掌握、C语言的深入理解、Linux系统编程、嵌入式硬件交互、常见嵌入式Linux应用开发以及调试与优化技巧。本书强调理论与实践相结合,通过大量的代码示例、实战项目和案例分析,让读者在学习过程中能够快速上手,理解抽象概念,并培养解决实际问题的能力。 目标读者 初学者: 对嵌入式系统和C语言编程感兴趣,希望系统学习嵌入式Linux开发的初学者。 在校学生: 电子工程、计算机科学、自动化等相关专业的学生,需要掌握嵌入式Linux开发技术的学习者。 嵌入式工程师: 接触过其他嵌入式平台(如MCU、RTOS)但希望转向嵌入式Linux开发的工程师,或是初级嵌入式Linux开发者,希望巩固基础、提升技能的工程师。 项目开发者: 需要在嵌入式Linux平台上开发产品的开发者,希望快速掌握开发流程和关键技术。 本书特色 循序渐进,结构清晰: 从最基础的Linux环境搭建和C语言语法讲解开始,逐步深入到系统编程、硬件交互等高级主题,逻辑严谨,适合不同层次的学习者。 实战导向,案例丰富: 每个章节都配有详实的示例代码,并贯穿多个由浅入深的实战项目,例如GPIO控制、串口通信、网络编程、文件系统操作等,让读者在动手实践中学习。 概念解析,深入浅出: 对于Linux内核、系统调用、进程管理、内存管理等核心概念,本书力求用清晰易懂的语言进行解释,辅以图示和比喻,帮助读者建立正确的认知。 工具链完整,实操性强: 详细介绍交叉编译工具链的安装与使用,是嵌入式Linux开发的关键一步。读者可以根据本书指导,搭建一套完整的开发环境。 调试技巧,问题解决: 讲解常用的调试方法和工具,如GDB、Valgrind等,帮助读者定位和解决开发过程中遇到的各种疑难杂症。 前沿技术,拓展视野: 在基础内容之外,还触及一些常用的嵌入式Linux库和框架,为读者进一步学习和探索奠定基础。 详细内容章节预览 第一部分:嵌入式Linux开发基础 第一章:嵌入式Linux系统概览与开发环境搭建 1.1 嵌入式Linux系统简介 什么是嵌入式系统? 为什么选择Linux作为嵌入式操作系统? 嵌入式Linux系统的特点与优势 常见的嵌入式Linux发行版介绍(如Buildroot, Yocto, Debian for embedded) 1.2 搭建嵌入式Linux开发环境 宿主机(Host)与目标机(Target)的概念 选择合适的宿主机操作系统(Windows, Linux, macOS) 虚拟机与真机开发的选择与配置 安装和配置交叉编译工具链(Cross-compilation toolchain) 理解交叉编译原理 下载和安装预编译的工具链 手动编译构建工具链(可选,高级) 目标机系统的准备与烧写 SD卡/eMMC的准备 Bootloader(如U-Boot)的理解与烧写 Linux内核的编译与烧写 根文件系统的构建与烧写 SSH远程登录与开发 NFS/TFTP网络文件系统调试 VS Code, CLion等IDE的配置与使用 第二章:Linux命令行与Shell编程基础 2.1 Linux基本概念与常用命令 文件系统结构(/bin, /etc, /home, /usr, /var等) 文件与目录操作(ls, cd, pwd, mkdir, rmdir, cp, mv, rm, touch) 文本查看与编辑(cat, more, less, head, tail, vi/vim, nano) 权限管理(chmod, chown, chgrp) 进程管理(ps, top, kill, pkill, nice) 查找命令(find, grep, which, whereis) 系统信息命令(uname, df, du, free, uptime) 网络相关命令(ping, ifconfig, ip, netstat, ssh, scp) 2.2 Shell脚本编程入门 Shell脚本的用途与特点 第一个Shell脚本的编写与执行 变量与数据类型 运算符与表达式 流程控制(if-else, case, for, while) 函数定义与使用 输入与输出重定向(>, >>, <, |) 常用Shell命令的脚本化应用 编写简单的自动化脚本(如编译脚本、部署脚本) 第三章:C语言精讲与嵌入式开发特性 3.1 C语言基础回顾与强化 数据类型、变量、运算符 控制流语句(if, switch, for, while, do-while) 函数、参数传递、作用域 数组、指针、字符串 结构体、联合体、枚举 预处理器(宏定义,文件包含,条件编译) 3.2 指针的高级应用与嵌入式开发的关联 多级指针 指针与数组的关系 指针与函数 指针与结构体 void指针、const指针 动态内存分配(malloc, calloc, realloc, free)及内存管理注意事项 3.3 C语言中的位操作 位运算符(&, |, ^, ~, <<, >>) 掩码(Mask)的使用 在硬件寄存器操作中的应用 3.4 C语言代码规范与可移植性 良好的编码风格 避免缓冲区溢出 常量与宏的合理使用 针对不同平台的编译选项 第二部分:嵌入式Linux系统编程 第四章:Linux系统调用与API 4.1 系统调用的概念与工作原理 用户空间与内核空间 系统调用的发生过程 常见系统调用分类(文件I/O, 进程控制, 内存管理, IPC等) 4.2 文件I/O编程(POSIX API) 文件描述符(File Descriptor) open, read, write, close 函数 lseek, stat, access 函数 缓冲I/O与非缓冲I/O的区别 高级文件操作:fcntl, ioctl 4.3 进程管理 进程与线程的概念 fork, exec系列函数创建新进程 getpid, getppid, getuid, getgid wait, waitpid 回收子进程 exit, _exit 终止进程 kill 信号发送 4.4 线程编程(POSIX Threads - pthreads) 线程与进程的区别 创建和管理线程:pthread_create, pthread_join, pthread_exit 线程同步与互斥:互斥锁(mutex)、条件变量(condition variable) 线程局部存储(Thread-Local Storage - TLS) 4.5 内存管理 mmap, munmap 内存映射 brk, sbrk (了解) 理解Linux内存分配模型 第五章:进程间通信(IPC) 5.1 IPC的重要性与分类 为什么需要IPC? 常见的IPC机制 5.2 管道(Pipes) 匿名管道(pipe()) 命名管道(mkfifo()) 管道的读写模型与局限性 5.3 消息队列(Message Queues) System V消息队列(msgget, msgsnd, msgrcv, msgctl) POSIX消息队列(mq_open, mq_send, mq_receive, mq_close, mq_unlink) 5.4 共享内存(Shared Memory) System V共享内存(shmget, shmat, shmdt, shmctl) POSIX共享内存(shm_open, mmap, munmap, shm_unlink) 共享内存的同步问题 5.5 信号量(Semaphores) System V信号量(semget, semop, semctl) POSIX信号量(sem_open, sem_wait, sem_post, sem_close, sem_unlink) 信号量的应用:资源控制,同步 5.6 套接字(Sockets) 文件描述符的扩展 网络编程基础(后续章节详述) 第六章:嵌入式设备驱动接口编程 6.1 Linux设备模型与设备文件 字符设备、块设备、网络设备 `/dev` 目录下的设备文件 设备驱动的基本原理 6.2 GPIO(通用输入输出)控制 GPIO原理与硬件接口 Linux GPIO子系统:`sysfs`接口 (/sys/class/gpio) 使用C语言控制GPIO(导出、设置方向、读写值) 实战项目:LED闪烁与按键检测 6.3 串口(UART)通信 UART原理与通信协议 Linux串口设备节点(/dev/ttyS 或 /dev/ttyAMA) 使用C语言进行串口配置与数据收发(open, read, write, ioctl - termios) 实战项目:PC与嵌入式设备通过串口进行数据交互 6.4 I2C/SPI通信 I2C/SPI总线原理与应用 Linux I2C/SPI子系统接口(`/dev/i2c-`, `/dev/spidev`) 使用C语言进行I2C/SPI设备通信 实战项目:读取传感器数据(如温度、湿度传感器) 6.5 内存映射(Memory-Mapped I/O) 理解硬件寄存器与内存地址的映射 使用`mmap`直接访问硬件寄存器(需要root权限或特定驱动支持) 实战项目:直接操作特定硬件寄存器 第三部分:嵌入式Linux应用开发 第七章:嵌入式Linux网络编程 7.1 网络编程基础 TCP/IP协议栈概述 Socket API详解 socket, bind, listen, accept, connect 函数 send, recv, write, read 函数 close, shutdown 函数 7.2 TCP客户端与服务器开发 实战项目:一个简单的TCP聊天室 7.3 UDP客户端与服务器开发 sendto, recvfrom 函数 UDP的特点与应用场景 实战项目:简单的UDP文件传输 7.4 DNS解析与域名访问 gethostbyname, getaddrinfo 7.5 嵌入式网络应用实例 HTTP客户端/服务器(了解,可使用库如libcurl) MQTT客户端(用于物联网通信) 第八章:文件系统操作与管理 8.1 Linux文件系统概述 常见嵌入式Linux文件系统(ext4, JFFS2, UBIFS, SquashFS) 文件系统挂载与卸载 8.2 C语言文件操作函数回顾 fopen, fclose, fread, fwrite, fseek, ftell, rewind fprintf, fscanf, fgets, fputs 文件状态获取:stat, access 8.3 嵌入式文件系统的特殊操作 固态存储(NAND/NOR Flash)的文件系统特性 日志文件系统(JFFS2, UBIFS)的理解 写时复制(Copy-on-Write) SquashFS(只读压缩文件系统)的应用 8.4 内存文件系统(tmpfs/ramfs) 在内存中创建临时文件 应用场景:临时数据存储,性能优化 8.5 实战项目:嵌入式设备日志记录与管理 第九章:嵌入式Linux的内存与性能优化 9.1 内存分析与调试 top, free 命令分析内存使用 valgrind 工具的内存检测与分析 AddressSanitizer (ASan) 内存泄漏的定位与解决 9.2 CPU性能分析 top, htop 命令分析CPU占用 perf 工具的使用 函数调用图与性能瓶颈分析 9.3 代码优化技巧 算法优化 循环优化 数据结构选择 编译器优化选项(-O2, -Os等) 利用CPU特性(SIMD指令 - 了解) 9.4 嵌入式系统功耗优化 了解CPU的低功耗模式 合理管理外设电源 软件层面的功耗控制策略 第十章:调试与故障排除 10.1 嵌入式Linux开发中的常见问题 编译错误、链接错误 运行时崩溃(Segmentation fault) 死锁、竞态条件 内存访问越界 设备驱动问题 10.2 强大的调试工具 GDB (GNU Debugger) 的使用 远程调试(gdbserver) 断点设置、单步执行、变量查看 内存查看、汇编代码查看 Printf 调试法的妙用 何时使用 printf 调试? 如何让 printf 调试更有效? 10.3 日志系统与错误报告 syslog, klog 自定义日志记录 10.4 逻辑分析仪与示波器的配合使用 硬件层面的问题排查 理解信号时序 第四部分:项目实战与进阶 第十一章:综合实战项目——智能家居网关原型开发 11.1 项目需求分析 硬件平台选择 系统架构设计 功能模块划分(设备接入、数据采集、远程控制、本地存储) 11.2 关键技术实现 设备接入: 使用MQTT协议连接云平台或本地服务器。 数据采集: 通过GPIO读取传感器状态,通过串口/I2C/SPI读取温湿度等传感器数据。 本地存储: 将采集到的数据存储到SQLite数据库或文件中。 远程控制: 接收来自云平台的指令,通过GPIO控制继电器开关。 Web UI(可选): 使用简单的CGI或框架实现基本的Web管理界面。 11.3 项目开发流程与代码实现 模块化设计与编码 交叉编译与部署 调试与测试 11.4 项目总结与扩展 第十二章:其他嵌入式Linux开发技术概览 12.1 嵌入式GUI开发简介 Qt for Embedded GTK+ for Embedded Framebuffer 和 VNC 12.2 嵌入式系统中的多媒体开发(简述) GStreamer 12.3 容器技术在嵌入式中的应用(如Docker, LXC) 12.4 嵌入式Linux安全性考量 附录 常用Linux命令速查 C语言标准库函数参考 嵌入式Linux开发常用术语表 通过本书的学习,读者将能够熟练掌握嵌入式Linux C语言编程的核心技术,能够独立完成嵌入式Linux下的应用程序开发,为从事嵌入式Linux开发工作奠定坚实的基础。