pdf

高质量嵌入式Linux C编程

  • 1星
  • 日期: 2020-09-29
  • 大小: 97.19MB
  • 所需积分:0分
  • 下载次数:3
  • favicon收藏
  • rep举报
  • 分享
  • free评论
标签: linux

Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的UNIX工具软件、应用程序和网络协议。它支持32位和64位硬件。Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

c

c

本书从嵌入式开发角度出发,以Linux操作系统为开发平台,将隐藏在系统开发背后的关于C语言、计算机组成原理、计算机操作系统等方面的机制和知识娓娓道来,不仅能让读者知其然,更要让读者知其所以然,揭开嵌入式Linux C系统开发背后鲜为人知的秘密,并让这些知识再反作用于编程实践,从而帮助读者写出高质量的嵌入式Linux C代码。具体说来,本书主要讨论了包括嵌入式C语言高级编程、嵌入式Linux系统编程、多任务解决机制、网络编程等多个方面的话内容。

目 录

  第1章 嵌入式Linux C语言开发工具1

  1.1 嵌入式Linux C语言开发概述1

  1.2 嵌入式Linux C开发环境1

  1.3 嵌入式文本编辑器2

  1.3.1 基本模式2

  1.3.2 基本操作3

  1.3.3 实训操作5

  1.4 嵌入式编译器6

  1.4.1 初识GCC编译器6

  1.4.2 gcc命令常用选项及工作流程6

  1.4.3 库的使用10

  1.5 嵌入式调试器12

  1.6 工程管理器15

  1.6.1 Makefile16

  1.6.2 Makefile特性介绍18

  1.7 Eclipse程序开发26

  1.7.1 Eclipse环境安装26

  1.7.2 Eclipse C程序开发28

  第2章 数据类型35

  2.1 变量与常量35

  2.2 变量35

  2.2.1 什么是变量35

  2.2.2 变量名和变量值36

  2.2.3 局部变量和全局变量38

  2.3 常量40

  2.4 基本内置类型41

  2.4.1 数据类型大小42

  2.4.2 陷阱之有符号与无符号42

  2.5 声明与定义43

  2.5.1 定义43

  2.5.2 声明43

  2.6 乱世枭雄:static与extern44

  2.6.1 政权旗帜static44

  2.6.2 外来的和尚会念经extern45

  2.7 铁布衫:const47

  2.8 隐形刺客:auto48

  2.9 闪电飞刀:register49

  2.10 专一王子:volatile50

  2.11 typedef详解51

  2.11.1 typedef与结构的问题51

  2.11.2 typedef与#define的问题53

  2.11.3 typedef与#define的另一例53

  2.11.4 typedef与复杂的变量声明54

  2.12 枚举55

  2.12.1 枚举类型的使用方法55

  2.12.2 枚举与#define 宏的区别56

  2.13 联合体56

  2.13.1 联合体的定义56

  2.13.2 从两道经典试题谈联合体(union)的使用57

  第3章 运算符、表达式59

  3.1 运算符简介59

  3.1.1 运算符优先级59

  3.1.2 一些容易出错的优先级问题61

  3.1.3 逻辑运算符61

  3.2 条件运算符和条件表达式62

  3.3 ++、操作符63

  3.4 位运算64

  3.4.1 按位与运算及应用64

  3.4.2 按位或运算及应用64

  3.4.3 按位异或运算及应用65

  3.4.4 左移和右移65

  3.5 C语言性能优化:使用位操作65

  第4章 语句67

  4.1 空语句67

  4.2 基础语句68

  4.2.1 表达式语句68

  4.2.2 函数调用语句68

  4.3 语句if68

  4.3.1 布尔变量与零值比较69

  4.3.2 整型变量与零值比较69

  4.3.3 浮点变量与零值比较69

  4.3.4 指针变量与零值比较70

  4.3.5 对if语句的补充说明70

  4.4 跳转语句:goto70

  4.5 循环语句71

  4.5.1 do-while语句72

  4.5.2 for语句72

  4.5.3 循环语句的效率74

  4.6 break和continue75

  4.6.1 break语句75

  4.6.2 continue语句75

  4.7 switch语句77

  第5章 数组与指针79

  5.1 数组认知79

  5.2 使用数组之常见问题80

  5.2.1 数组的下标总是从0开始吗80

  5.2.2 可以使用数组后面第一个元素的地址吗81

  5.2.3 为什么要小心对待位于数组后面的那些元素的地址呢82

  5.2.4 数组作为参数传递给函数时,可以通过sizeof得到数组的大小吗82

  5.2.5 指针或带下标的数组名都可以访问元素,哪一种更好呢83

  5.2.6 可以把另外一个地址赋给一个数组名吗85

  5.2.7 array_name和&array_name有什么不同86

  5.2.8 为什么用const说明的常量不能用来定义一个数组的初始大小87

  5.2.9 字符串和数组有什么不同87

  5.3 指针89

  5.3.1 指针是变量90

  5.3.2 指针的类型和指针所指向的类型90

  5.3.3 指针的值91

  5.3.4 指针本身所占据的内存区91

  5.4 指针的运算92

  5.4.1 指针的算术运算92

  5.4.2 指针的关系运算92

  5.4.3 间接引用93

  5.4.4 最多可以使用几层指针93

  5.5 常量指针和指针常量95

  5.5.1 常量指针与指针常量的实例95

  5.5.2 常量指针的应用96

  5.6 空指针及其使用97

  5.6.1 NULL总是被定义为0吗97

  5.6.2 NULL总是等于0吗97

  5.6.3 空指针的使用98

  5.7 指针void:万能指针99

  5.8 指针数组与数组指针100

  5.9 字符串函数详解101

  5.10 函数指针与指针函数105

  5.11 复杂指针声明:“int * (* (*fp1) (int) ) [10];”106

  5.11.1 基础106

  5.11.2 const修饰符107

  5.11.3 typedef的妙用108

  5.11.4 函数指针109

  5.11.5 右左法则109

  第6章 内存管理111

  6.1 你的数据放在哪里111

  6.1.1 未初始化的全局变量(.bss段)111

  6.1.2 初始化过的全局变量(.data段)112

  6.1.3 常量数据(.rodata段)112

  6.1.4 代码(.text段)113

  6.1.5 栈(stack)113

  6.1.6 堆(heap)113

  6.2 内存分配方式114

  6.3 野指针115

  6.4 常见的内存错误及对策115

  6.5 段错误以及调试方法116

  6.5.1 方法一:利用gdb逐步查找段错误117

  6.5.2 方法二:分析core文件118

  6.5.3 方法三:段错误时启动调试119

  6.5.4 方法四:利用backtrace和objdump进行分析120

  6.6 指针与数组的对比121

  第7章 预处理、结构体125

  7.1 宏定义:#define125

  7.1.1 无参宏定义125

  7.1.2 带参宏定义127

  7.2 文件包含128

  7.3 条件编译129

  7.4 宏定义使用技巧131

  7.5 关于#和##132

  7.6 结构体133

  7.6.1 内存字节对齐135

  7.6.2 内存对齐正式原则138

  7.7 #define和typedef的区别139

  7.8 结构体和联合体的区别139

  7.9 浅谈C语言中的位段139

  7.9.1 位段的使用140

  7.9.2 位段结构在内存中的存储方式140

  第8章 函数141

  8.1 函数声明与定义141

  8.1.1 定义141

  8.1.2 声明与定义不同142

  8.2 形式参数和实际参数143

  8.3 参数传递143

  8.3.1 简单变量或数组元素作为函数参数143

  8.3.2 指针变量或数组名作为函数参数144

  8.3.3 数组名作函数参数145

  8.3.4 结构体数组作函数参数146

  8.4 如何编写有多个返回值的C语言函数146

  8.4.1 利用全局变量146

  8.4.2 传递数组指针148

  8.4.3 传递结构体指针148

  8.5 回调函数149

  8.6 变参函数详解:printf的实现151

  8.7 可变参数问题152

  第9章 编码规范155

  9.1 排版155

  9.2 注释158

  9.3 标示符名称163

  第10章 shell编程165

  10.1 什么是shell165

  10.2 几种流行的shell165

  10.3 shell程序设计(基础部分)166

  10.3.1 shell基本语法166

  10.3.2 shell程序的变量和参数167

  10.4 shell程序设计的流程控制169

  10.4.1 test测试命令169

  10.4.2 if条件语句170

  10.4.3 for循环171

  10.4.4 while和until循环171

  10.4.5 case条件选择172

  10.4.6 无条件控制语句break和continue173

  10.4.7 函数定义173

  10.5 命令分组174

  10.6 信号174

  10.7 运行shell程序的方法175

  10.8 bash程序的调试175

  10.9 bash的内部命令176

  第11章 文件操作179

  11.1 Linux文件结构179

  11.1.1 Linux文件系统179

  11.1.2 Linux目录结构180

  11.1.3 Linux文件分类182

  11.1.4 常见文件类型183

  11.1.5 Linux文件属性183

  11.2 系统调用184

  11.3 Linux文件描述符184

  11.4 不带缓存的I/O操作185

  11.4.1 creat函数185

  11.4.2 open函数186

  11.4.3 read函数188

  11.4.4 write函数189

  11.4.5 lseek函数189

  11.4.6 close函数189

  11.4.7 经典范例:文件复制190

  11.5 带缓存的I/O操作191

  11.5.1 三种类型的缓冲191

  11.5.2 fopen函数193

  11.5.3 fclose函数194

  11.5.4 fdopen函数194

  11.5.5 fread函数195

  11.5.6 fwrite函数195

  11.5.7 fseek函数196

  11.5.8 fgetc函数、getc函数和getchar函数197

  11.5.9 fputc函数、putc函数和putchar函数198

  11.6 fgets函数与gets函数比较分析199

  11.7 输出与输入201

  11.7.1 printf函数、fprintf函数和sprintf函数201

  11.7.2 scanf函数、fcanf函数和sscanf函数203

  第12章 进程控制编程207

  12.1 为何需要多进程(或者多线程),为何需要并发207

  12.1.1 进程207

  12.1.2 进程分类208

  12.1.3 进程的属性208

  12.1.4 父进程和子进程208

  12.2 Linux进程管理209

  12.2.1 ps监视进程工具209

  12.2.2 pgrep查询进程工具211

  12.2.3 终止进程的工具kill、killall、pkill、xkill211

  12.2.4 top监视系统任务的工具213

  12.2.5 进程的优先级:nice和renice214

  12.3 Linux进程的三态215

  12.3.1 三种基本状态215

  12.3.2 三种状态间的转换215

  12.4 Linux进程结构216

  12.5 Linux进程控制块PCB216

  12.6 Linux进程调度218

  12.6.1 调度的目标218

  12.6.2 调度算法218

  12.6.3 优先级反转220

  12.7 进程创建221

  12.7.1 获取进程221

  12.7.2 启动进程:fork( )222

  12.7.3 启动进程:vfork( )224

  12.7.4 启动进程:exec族225

  12.7.5 启动进程:system228

  12.8 进程等待229

  12.8.1 僵尸进程的产生229

  12.8.2 如何避免僵尸进程231

  12.8.3 wait函数和waitpid函数231

  12.9 进程退出235

  12.9.1 退出方式的不同点236

  12.9.2 exit( )和_exit( )函数236

  12.9.3 exit( )和_exit( )的区别237

  第13章 进程间通信方式239

  13.1 进程间通信方式概述239

  13.1.1 进程间通信的目的239

  13.1.2 Linux进程间通信方式简介240

  13.2 管道通信241

  13.2.1 建立无名管道241

  13.2.2 读写无名管道242

  13.2.3 无名管道应用实例246

  13.2.4 创建有名管道248

  13.2.5 读写有名管道250

  13.3 管道通信方式的应用场景253

  13.4 信号254

  13.4.1 信号及信号来源254

  13.4.2 信号种类254

  13.4.3 信号处理方式256

  13.4.4 信号发送256

  13.4.5 自定义处理信号方式258

  13.4.6 信号集操作262

  13.4.7 使用信号注意事项264

  13.5 消息队列265

  13.5.1 消息队列基础理论266

  13.5.2 使用消息队列266

  13.5.3 消息队列API267

  13.5.4 消息队列的限制269

  13.5.5 消息队列的应用实例270

  13.6 信号灯273

  13.6.1 信号灯概述273

  13.6.2 内核实现原理274

  13.6.3 使用信号灯274

  13.6.4 信号灯API275

  13.6.5 信号灯的限制277

  13.6.6 竞争问题277

  13.6.7 信号灯应用实例277

  13.7 共享内存方式一281

  13.7.1 内核实现原理281

  13.7.2 mmap( )及其相关系统调用282

  13.7.3 mmap( )范例283

  13.7.4 对mmap( )返回地址的访问287

  13.8 共享内存方式二289

  13.8.1 系统V共享内存原理289

  13.8.2 系统V共享内存API290

  13.8.3 系统V共享内存范例291

  第14章 多线程编程295

  14.1 线程概述295

  14.1.1 为什么有了进程的概念后,还要再引入线程呢295

  14.1.2 多线程的优点296

  14.1.3 多线程的缺点296

  14.2 多线程的实现297

  14.2.1 线程的创建297

  14.2.2 终止线程299

  14.2.3 等待线程终止300

  14.3 线程属性300

  14.3.1 线程属性初始化301

  14.3.2 线程分离301

  14.3.3 线程的继承性302

  14.3.4 线程的调度策略303

  14.3.5 线程的调度参数304

  14.3.6 实例分析305

  14.4 线程同步机制306

  14.4.1 互斥锁Mutex306

  14.4.2 互斥锁使用实例308

  14.4.3 条件变量Conditions310

  14.4.4 条件变量使用实例311

  第15章 网络编程313

  15.1 TCP/IP协议概述313

  15.1.1 TCP/IP 起源313

  15.1.2 TCP/IP的特性与应用315

  15.1.3 互联网地址315

  15.1.4 域名系统316

  15.1.5 封装317

  15.1.6 TCP/IP工作模型318

  15.1.7 TCP/IP 协议层318

  15.1.8 TCP/IP应用320

  15.1.9 网桥、路由器和网关321

  15.2 TCP和UDP322

  15.2.1 TCP协议322

  15.2.2 三次握手协议322

  15.2.3 TCP数据报头323

  15.2.4 UDP协议324

  15.2.5 协议的选择324

  15.2.6 IP和端口号324

  15.3 套接字325

  15.3.1 Socket概念325

  15.3.2 Socket类型325

  15.3.3 Socket信息数据结构325

  15.3.4 数据存储优先顺序的转换326

  15.3.5 地址格式转化327

  15.3.6 名字地址转化328

  15.4 网络编程330

  15.4.1 建立Socket331

  15.4.2 绑定地址332

  15.4.3 监听333

  15.4.4 接受请求334

  15.4.5 连接服务器335

  15.4.6 发送数据335

  15.4.7 接收数据336

  15.5 采用TCP协议的C/S架构实现338

  15.5.1 模块封装338

  15.5.2 服务器的实现340

  15.5.3 客户端的实现341

  15.6 并发服务器模型342

  15.6.1 多进程解决方案342

  15.6.2 多线程解决方案342

  15.6.3 调用fcntl将sockfd设置为非阻塞模式348

  15.7 多路转接模型348

  15.7.1 服务器的实现349

  15.7.2 客户端的实现354

  15.8 采用UDP协议C/S架构的实现355

  15.8.1 服务器的实现355

  15.8.2 客户端的实现356

  15.8.3 UDP协议传输文件的实现357

  参考文献360

更多简介内容

推荐帖子

TL437x-EVM评估板测试手册(1)
前言 本指导文档适用开发环境: Windows开发环境:Windows 7 64bit、Windows 10 64bit Linux开发环境:Ubuntu 14.04.3 64bit 虚拟机:VMware14.1.1 U-Boot:U-Boot-2017.01 Kernel:Linux-4.9.65、Linux-RT-4.9.65 Linux Proces
Tronlong小分队 ARM技术
【SC8905 EVM测评】+放电输出调压
前天拿到南芯的开发板后感觉很强大的,开关管都集成在那么小的一个IC里,最大电流可达6A,还可以双向工作,带I2C输出调压调流,完全可以做成一个输出可调的稳压电源使用了,以后做实验就方便了。还是先完成任务吧! 1,电脑安装USB转I2C驱动。插入调试工具后,电脑会显示不能识别设备,在电脑设备管理器中会出现一个有!的设备。这时点击这个设备,重新安装驱动,选择从网站上下载的DLL文件即可。安装成功
luck_gfb 国产芯片交流
【CH579M-R1】3. ADC 内部测温,外部通道及触摸按键 测试
本帖最后由 yanxinboy 于 2020-9-25 20:20 编辑 节前加月底,巨忙中! CH579内部集成了一个12位的逐次逼近型模拟数字转换器ADC,最大16个通道,支持14个外部模拟信号源和2个内部信号源 - 内部温度检测通道和内部电池电压检测通道。 输入支持单端和差分输入,可选PGA增益(建议按手册的实际可用测量范围选择合适的PGA增益,提高准确度)。
yanxinboy 国产芯片交流
TI 博文:如何选择汽车摄像头模块的电源
本帖最后由 qwqwqw2088 于 2020-9-27 10:12 编辑      随着汽车摄像头技术的发展,其分辨率、动态范围和帧速率越来越高,电源架构需要根据具体的用例需求进行调整。在本文中,我将回顾三种可用于为汽车摄像头模块供电的策略: 全离散 全集成 部分集成      本文重点介绍小外形摄像头模块,该模块不包含任何数据处理、可将原始视频数据输出到独立
qwqwqw2088 模拟与混合信号
ESP32学习笔记3 -- WS2812 16*16点阵的点线面绘画
大家晚上好,上次强占的发帖位这次给大家补上了 上次初步介绍了WS2812的16*16点阵  传送门在这里   ----->   http://bbs.eeworld.com.cn/thread-1141816-1-1.html 有兴趣的可以看一下啊 一个图形是由线条组成的,而线条是由点构成的,那么画点则是重中之重 首先我想建立一个坐标系,就是所有的点都在坐标系上,坐
是最帅的啊 MicroPython开源版块
MSP430旋转流量计的扫描接口和USB 集成
    MSP430 MCU 集成了模拟和数字外设以满足您的检测和监控需求。集成外设包括 ADC、DAC、运算放大器、计时器、SPI、UART、I2C、USB 和 LCD 驱动器 MSP430™ CapTIvate™ 微控制器可将低功耗电容式触控按钮、滑块和滚轮轻松添加到您的 MCU 应用中。可在存在噪声和湿气的环境中通过塑料、玻璃和金属覆盖层进行可靠的触控检测 , 适用于高精度水量、热量和
fish001 微控制器 MCU

评论

登录/注册

意见反馈

求资源

回顶部

datasheet推荐 换一换

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版 版权声明

北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved
$(function(){ var appid = $(".select li a").data("channel"); $(".select li a").click(function(){ var appid = $(this).data("channel"); $('.select dt').html($(this).html()); $('#channel').val(appid); }) })