首页资源分类嵌入式系统Linux > 从零开始学习嵌入式Linux系统编程

从零开始学习嵌入式Linux系统编程

已有 445791个资源

下载专区

文档信息举报收藏

标    签:嵌入式开发linux系统系统编程

分    享:

文档简介

从零开始学习嵌入式Linux系统编程:

学习Linux系统编程,实验手册本身涵盖所有知识点,包括大大小小 60 个左右的实验

文档预览

Linux 系统编程 Linux 系统编程........................................................................................................................... - 1 版本介绍........................................................................................................................... - 19 - 第一章 前言............................................................................................................................. - 23 视频资源................................................................................................................... - 23 - Linux 相关工作分析.........................................................................................................- 23 linux 编程怎么入门..........................................................................................................- 26 什么是 Linux 系统编程....................................................................................................- 27 关于 linux 系统编程实验手册.........................................................................................- 28 关于 linux 驱动.................................................................................................................- 29 学习 linux 的时间.............................................................................................................- 30 第二章 最小 Linux 系统..........................................................................................................- 32 2.1 本章导读..................................................................................................................... - 32 - 2.1.1 工具.................................................................................................................. - 32 2.1.2 预备课程.......................................................................................................... - 33 2.1.3 视频资源.......................................................................................................... - 33 2.2 学习目标..................................................................................................................... - 33 2.3 最小 Linux 系统简介................................................................................................ - 34 2.4 搭建好的最小 linux 系统..........................................................................................- 34 2.5 配置 Busybox............................................................................................................ - 35 2.6 编译和安装 Busybox................................................................................................ - 46 2.7 完善最小 Linux 系统的文件.................................................................................... - 49 - 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 2.8 安装打包软件和编译................................................................................................ - 72 2.9 最小 Linux 系统的烧写............................................................................................ - 74 2.10 常见错误..................................................................................................................- 75 第三章 helloworld...................................................................................................................- 76 3.1 本章导读..................................................................................................................... - 76 3.1.1 工具.......................................................................................................................... - 76 - 3.1.2 预备课程.......................................................................................................... - 76 3.1.3 视频资源.......................................................................................................... - 77 3.2 学习目标..................................................................................................................... - 77 3.3 代码简介.................................................................................................................... - 77 3.4 编辑和目录介绍........................................................................................................ - 78 3.5 编译............................................................................................................................ - 81 3.5 修改权限和运行-U 盘................................................................................................ - 84 3.6 修改权限和运行-TF 卡............................................................................................. - 86 3.7 将 helloworld 编译进文件系统.................................................................................- 89 3.8 程序分析..................................................................................................................... - 90 3.9 小贴士,关于 linux 命令的一点说明.......................................................................- 91 第四章 linux 用户、用户组、权限等....................................................................................- 92 4.1 本章导读..................................................................................................................... - 92 4.1.1 工具.......................................................................................................................... - 92 4.1.2 预备课程.......................................................................................................... - 92 - 版本号:V2.0 日期:2015-10-2 -2- www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 4.1.3 视频资源.......................................................................................................... - 93 4.2 学习目标..................................................................................................................... - 93 4.3 Linux 用户管理...........................................................................................................- 93 - 4.3.1 超级用户.......................................................................................................... - 94 4.3.2 创建和删除用户............................................................................................. - 94 4.3.3Linux 用户的组织............................................................................................ - 96 4.4 Linux 组.......................................................................................................................- 97 4.4.1 用户组的操作.................................................................................................. - 98 4.4.2 用户和组的联系............................................................................................. - 99 4.5 Linux 权限................................................................................................................ - 100 4.6 linux 绝对路径和相对路径..................................................................................... - 105 4.6.1 绝对路径........................................................................................................- 105 4.6.2 相对路径........................................................................................................- 106 4.7 代码运行返回信息...................................................................................................- 108 4.7.1 启动信息........................................................................................................- 108 4.7.2 程序运行错误................................................................................................- 110 4.7.3 函数返回值错误............................................................................................- 111 4.7.4 特殊变量错误................................................................................................- 111 第五章 专题 文件 IO............................................................................................................ - 114 5.1 本章导读...................................................................................................................- 114 5.1.1 工具........................................................................................................................- 114 - 版本号:V2.0 日期:2015-10-2 -3- www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 5.1.2 预备课程........................................................................................................- 115 5.1.3 视频资源........................................................................................................- 115 5.2 学习目标...................................................................................................................- 115 5.3 Linux 中 IO 的概念介绍.......................................................................................... - 116 5.3.1 什么是缓存 I/O............................................................................................ - 116 5.3.2 缓存 I/O 的缺点.......................................................................................... - 117 5.3.3 小贴士-关于文件的相关知识的一点说明..................................................- 117 5.3.4 函数头文件简介............................................................................................- 118 5.4 实验-打开文件函数 open........................................................................................ - 118 5.4.1 open 函数例程.............................................................................................. - 118 5.4.2open 函数代码............................................................................................... - 120 5.4.3 编译运行测试...............................................................................................- 121 5.5 实验-创建函数 creat 和 open................................................................................. - 125 5.5.1 creat 函数介绍.............................................................................................. - 125 5.5.2 creat 函数例程.............................................................................................. - 125 5.5.3 编译运行测试................................................................................................- 127 5.6 实验-关闭函数 close................................................................................................ - 129 5.6.4close 函数介绍............................................................................................... - 129 5.6.2close 函数例程............................................................................................... - 130 5.7 实验-写函数 write................................................................................................... - 130 5.7.1write 函数介绍...............................................................................................- 130 - 版本号:V2.0 日期:2015-10-2 -4- www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 5.7.2write 函数例程...............................................................................................- 130 5.7.3 编译运行测试................................................................................................- 132 5.8 实验-文件的读 read 函数........................................................................................- 134 5.8.1read 函数介绍................................................................................................ - 134 5.8.2read 函数例程................................................................................................ - 135 5.8.3 编译运行测试................................................................................................- 137 第六章 实战 字符设备控制................................................................................................. - 139 6.1 本章导读...................................................................................................................- 139 6.1.1 工具........................................................................................................................- 139 6.1.2 预备课程........................................................................................................- 140 6.1.3 视频资源........................................................................................................- 140 6.2 学习目标...................................................................................................................- 140 6.3 入口 main 函数的参数............................................................................................ - 141 6.3.2 main 函数简介.............................................................................................. - 141 6.3.3main 函数例程............................................................................................... - 142 6.3.4 编译运行测试................................................................................................- 142 6.4 字符类 led 灯............................................................................................................- 144 6.4.1 小灯测试例程................................................................................................- 146 6.4.2 编译运行测试................................................................................................- 148 6.5 字符类 Buzzer 蜂鸣器............................................................................................. - 151 6.5.1 蜂鸣器测试例程............................................................................................- 152 - 版本号:V2.0 日期:2015-10-2 -5- www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 6.5.2 编译运行测试................................................................................................- 154 6.6 字符类 ADC 模数转换............................................................................................. - 157 - 6.6.1 模数转换例程................................................................................................- 159 6.6.2 编译运行测试................................................................................................- 160 第七章 实战 Linux 串口编程.............................................................................................. - 164 7.1 本章导读...................................................................................................................- 164 7.1.1 工具........................................................................................................................- 164 7.1.2 预备课程........................................................................................................- 165 7.1.3 视频资源........................................................................................................- 165 7.2 学习目标...................................................................................................................- 165 7.3 几个关于串口的基本概念.......................................................................................- 166 7.3.1 什么是串口通信............................................................................................- 166 7.3.2 什么是串口....................................................................................................- 166 7.3.3 什么是 RS232................................................................................................- 166 7.3.4 RS232 的针脚定义........................................................................................ - 167 7.3.5 什么是流控...................................................................................................- 167 7.4 串口编程的流程分析...............................................................................................- 167 7.5 实验-开机启动运行..................................................................................................- 169 7.5.1 实验例程........................................................................................................- 169 7.5.2 操作方法........................................................................................................- 169 7.6 实验-打开串口..........................................................................................................- 175 - 版本号:V2.0 日期:2015-10-2 -6- www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 7.6.1 如何确认设备节点........................................................................................- 175 7.6.2 串口打开和关闭例程....................................................................................- 177 7.6.3 编译运行测试................................................................................................- 179 7.7 串口初始化参数介绍...............................................................................................- 181 7.7.1 串口的初始化结构介绍................................................................................- 182 7.7.2 串口的初始化常用函数介绍........................................................................- 184 7.7.4 初始化流程分析...........................................................................................- 187 7.7.4 例程:串口初始化代码................................................................................- 188 7.8 实验-串口发送..........................................................................................................- 191 7.8.1 串口发送例程................................................................................................- 192 7.8.2 编译运行测试................................................................................................- 194 7.8.3 只有一个串口的测试方法............................................................................- 198 7.9 实验-串口接收..........................................................................................................- 201 7.9.2 串口接收例程................................................................................................- 201 7.9.2 编译运行测试................................................................................................- 203 第八章 TFTP 服务器搭建和测试.......................................................................................... - 207 8.1 本章导读...................................................................................................................- 207 8.1.1 工具........................................................................................................................- 207 8.1.2 预备课程........................................................................................................- 207 8.1.3 视频资源........................................................................................................- 208 8.2 学习目标...................................................................................................................- 208 - 版本号:V2.0 日期:2015-10-2 -7- www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 8.2.1 学习目标........................................................................................................- 208 8.2.2Linux 网络部分的学习方法.......................................................................... - 208 8.3Ubuntu 服务端的搭建.............................................................................................. - 209 8.3.1 基本知识介绍................................................................................................- 209 8.3.2 搭建服务器....................................................................................................- 209 8.4 服务器测试...............................................................................................................- 216 第九章 开发板实现 TFTP 文件传输.................................................................................... - 221 9.1 本章导读...................................................................................................................- 221 9.1.1 工具........................................................................................................................- 221 9.1.2 预备课程........................................................................................................- 221 9.1.3 视频资源........................................................................................................- 222 9.2 学习目标...................................................................................................................- 222 9.3 同一网段的概念.......................................................................................................- 222 9.3.1IP 地址............................................................................................................ - 223 9.3.2 子网掩码........................................................................................................- 225 9.3.3 确认 IP 在同一网段...................................................................................... - 227 9.3.4 根据实际情况修改 IP 和子网掩码............................................................. - 228 9.4 配置...........................................................................................................................- 230 9.5 客户端的测试...........................................................................................................- 231 9.6TFTP 传输应用程序..................................................................................................- 234 第十章 实现 NFS 网络文件系统.......................................................................................... - 237 - 版本号:V2.0 日期:2015-10-2 -8- www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 10.1 本章导读.................................................................................................................- 237 10.1.1 工具......................................................................................................................- 237 - 10.1.2 预备课程......................................................................................................- 238 10.1.3 视频资源......................................................................................................- 238 10.2 学习目标.................................................................................................................- 238 10.3 基本环境介绍.........................................................................................................- 238 10.4 搭建 NFS 服务器....................................................................................................- 239 10.5 测试 NFS 服务器....................................................................................................- 248 10.7 配置内核 1............................................................................................................. - 251 10.7 配置内核 2............................................................................................................. - 262 第十一章 以 NFS 方式调试应用以及最小网络.................................................................. - 266 11.1 本章导读.................................................................................................................- 266 11.1.1 工具......................................................................................................................- 266 11.1.2 预备课程......................................................................................................- 267 11.1.3 视频资源......................................................................................................- 267 11.2 学习目标.................................................................................................................- 267 11.3 利用 NFS 调试程序............................................................................................... - 267 11.4 最小局域网实现 tftp 和 NFS.................................................................................- 273 11.4.1PC 网络配置................................................................................................. - 274 11.4.4 修改开发板设置并测试..............................................................................- 279 11.4.2 虚拟机的设置..............................................................................................- 281 - 版本号:V2.0 日期:2015-10-2 -9- www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 11.4.3 测试三者之间网络......................................................................................- 284 11.4.4 实现 tftp 下载功能..................................................................................... - 286 11.4.5 修改内核配置实现 NFS..............................................................................- 288 第十二章 专题实战延时....................................................................................................... - 289 12.1 本章导读.................................................................................................................- 289 12.1.1 工具......................................................................................................................- 289 12.1.2 预备课程......................................................................................................- 290 12.1.3 视频资源......................................................................................................- 290 12.2 学习目标.................................................................................................................- 290 12.3linux 中的延时函数介绍........................................................................................ - 290 12.5 实验 Linux 应用中的延时..................................................................................... - 292 12.5.1 函数代码......................................................................................................- 292 12.5.2 编译运行测试..............................................................................................- 293 12.6Linux 内核驱动中的延时....................................................................................... - 295 第十三章 专题实战时间....................................................................................................... - 296 13.1 本章导读.................................................................................................................- 296 13.1.1 工具......................................................................................................................- 296 13.1.2 预备课程......................................................................................................- 297 13.1.3 视频资源......................................................................................................- 297 13.2 学习目标.................................................................................................................- 297 13.3Linux 中时间的几个基本概念............................................................................... - 298 - 版本号:V2.0 日期:2015-10-2 - 10 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 13.4 实验-时间的调用................................................................................................... - 298 13.4.1 时间调用函数..............................................................................................- 298 13.4.2 函数代码......................................................................................................- 299 13.4.3 编译运行测试..............................................................................................- 300 - 13.5 实验-时间的转换................................................................................................... - 302 13.5.1 时间转换的函数..........................................................................................- 302 13.5.2 函数代码......................................................................................................- 303 13.5.3 编译运行测试..............................................................................................- 305 13.5.3 小提示..........................................................................................................- 307 - 13.6 实验-处理器性能的测试....................................................................................... - 307 13.6.1 高精度时间函数..........................................................................................- 307 13.6.2 实验代码......................................................................................................- 308 13.6.3 编译运行测试..............................................................................................- 310 - 第十四章 Linux 编程中 man 命令的使用........................................................................... - 313 14.1 本章导读.................................................................................................................- 313 14.1.1 工具......................................................................................................................- 313 14.1.2 预备课程......................................................................................................- 313 14.1.3 视频资源......................................................................................................- 314 14.2 学习目标.................................................................................................................- 314 14.3 关于英语.................................................................................................................- 314 14.4man 命令简介......................................................................................................... - 314 - 版本号:V2.0 日期:2015-10-2 - 11 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 14.4.1man 命令简介.............................................................................................. - 314 14.4.2man 系统...................................................................................................... - 315 14.4.2man 的分页.................................................................................................. - 317 14.4.3 手册页的框架..............................................................................................- 319 14.4.4linux 命令手册页举例 1..............................................................................- 321 14.4.4linux 命令手册页举例 2..............................................................................- 323 第十五章 专题 管理文件和目录......................................................................................... - 326 15.1 本章导读.................................................................................................................- 326 15.1.1 工具......................................................................................................................- 327 15.1.2 预备课程......................................................................................................- 327 15.1.3 视频资源......................................................................................................- 327 15.2 学习目标.................................................................................................................- 328 15.3 文件元数据以及基础知识.....................................................................................- 329 15.4 实验-stat 函数组.................................................................................................... - 330 15.4.1 使用 man 学习 stat 函数组........................................................................- 330 15.4.2stat 函数组例程........................................................................................... - 336 15.4.3 编译运行测试..............................................................................................- 338 15.5 实验-chmod 权限函数...........................................................................................- 340 15.5.1 使用 man 学习 chmod 函数...................................................................... - 340 15.5.2chmod 函数例程.......................................................................................... - 343 15.5.3 编译运行测试..............................................................................................- 344 - 版本号:V2.0 日期:2015-10-2 - 12 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 15.6 目录以及基础知识.................................................................................................- 346 15.7 实验-getcwd 函数.................................................................................................. - 347 - 15.7.1 使用 man 学习 getcwd 函数......................................................................- 347 15.7.2getcwd 函数例程......................................................................................... - 351 15.7.3 编译运行测试..............................................................................................- 352 15.8 实验-mkdir 函数.................................................................................................... - 354 15.8.1 使用 man 学习 mkdir 函数........................................................................- 355 15.8.2mkdir 函数例程........................................................................................... - 356 15.8.3 编译运行测试.............................................................................................- 358 15.9 实验-rmdir 函数................................................................................................... - 360 15.9.1 使用 man 学习 rmdir 函数........................................................................ - 360 15.9.2rmdir 函数例程............................................................................................- 362 15.9.3 编译运行测试.............................................................................................- 363 15.10 实验-chdir 函数................................................................................................... - 365 15.10.1 使用 man 学习 chdir 函数....................................................................... - 365 15.10.2chdir 函数例程.......................................................................................... - 367 15.10.3 编译运行测试.......................................................................................... - 370 15.11 实验-opendir 和 closedir 函数........................................................................... - 373 15.11.1 使用 man 学习 opendir 和 closedir 函数...............................................- 373 15.11.2opendir 和 closedir 函数例程.................................................................. - 375 15.11.3 编译运行测试.......................................................................................... - 377 - 版本号:V2.0 日期:2015-10-2 - 13 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 15.12 实验-readdir 函数............................................................................................... - 379 15.12.1 使用 man 学习 readdir 函数................................................................... - 379 15.12.2readdir 函数例程.......................................................................................- 382 15.12..3 编译运行测试..........................................................................................- 383 - 15.13 链接以及基础知识.............................................................................................. - 385 15.14 实验-硬链接 link..................................................................................................- 387 - 15.14.1 使用 man 学习 link 函数......................................................................... - 387 15.14.2link 函数例程.............................................................................................- 389 15.14.3 编译运行测试.......................................................................................... - 391 15.15 实验-符号链接 symlink.......................................................................................- 396 15.15.1 使用 man 学习 symlink 函数.................................................................. - 396 15.15.2symlink 函数例程......................................................................................- 398 15.15.3 编译运行测试.......................................................................................... - 399 15.16 实验-解除链接 unlink......................................................................................... - 403 15.16.1 使用 man 学习 unlink 函数..................................................................... - 403 15.16.2unlink 函数例程........................................................................................ - 405 15.16.3 编译运行测试.......................................................................................... - 406 15.17 拷贝和移动文件.................................................................................................. - 409 15.18 实验-拷贝............................................................................................................. - 409 15.18.1 拷贝简介................................................................................................... - 409 15.18.2 拷贝例程................................................................................................... - 410 - 版本号:V2.0 日期:2015-10-2 - 14 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 15.18.3 编译运行测试........................................................................................... - 412 15.19 实验-移动............................................................................................................. - 416 - 15.19.1 使用 man 学习 rename 函数...................................................................- 416 15.19.2rename 文件例程...................................................................................... - 418 15.19.3 编译运行测试........................................................................................... - 419 本章小结......................................................................................................................... - 421 第十六章 专题 Linux 的进程............................................................................................... - 423 16.1 本章导读.................................................................................................................- 423 16.1.1 工具......................................................................................................................- 423 16.1.2 预备课程......................................................................................................- 424 16.1.3 视频资源......................................................................................................- 424 16.2 学习目标.................................................................................................................- 424 16.3 进程的基本概念.....................................................................................................- 425 16.3.1 嵌入式 linux 和嵌入式单片机最重要区别............................................... - 425 16.3.2 几个基本概念..............................................................................................- 426 16.4 实验-进程 ID.......................................................................................................... - 427 16.4.1 进程 id 基本概念........................................................................................ - 427 16.4.2 使用 man 学习 getpid 和 getppid............................................................. - 428 16.4.3 例程..............................................................................................................- 430 16.4.4 编译运行测试..............................................................................................- 431 小贴士-如何查看当前程序的进程........................................................................- 433 - 版本号:V2.0 日期:2015-10-2 - 15 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 16.5 执行新程序-exec 函数族一..................................................................................- 433 16.5.1 使用 man 学习 exec 函数...........................................................................- 434 15.2exec 函数族例程............................................................................................. - 437 5.4.3 编译运行测试...............................................................................................- 438 - 16.6 实验-fork 创建新进程........................................................................................... - 440 16.5.1 使用 man 学习 fork 进程........................................................................... - 440 16.5.2 函数例程......................................................................................................- 443 16.5.3 编译运行测试..............................................................................................- 444 15.4 关于如何理解进程的调用.............................................................................- 446 - 16.6 进程终止 exit........................................................................................................ - 447 16.6.1 使用 man 学习 exit 函数............................................................................- 448 小贴士:linux 命令的本质....................................................................................- 449 - 16.7 exec 函数族+fork 进程+linux 命令+linux 时间函数例程...................................- 449 16.7.1 例程..............................................................................................................- 449 16.7.2 编译运行测试..............................................................................................- 452 - 第十七章 专题 实战 Linux 进程间通信............................................................................. - 456 17.1 本章导读.................................................................................................................- 456 17.1.1 工具......................................................................................................................- 456 17.1.2 预备课程......................................................................................................- 457 17.1.3 视频资源......................................................................................................- 457 17.2 学习目标.................................................................................................................- 458 - 版本号:V2.0 日期:2015-10-2 - 16 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 17.3 无名管道 pipe........................................................................................................ - 458 17.3.1 使用 man 学习 pipe 函数...........................................................................- 458 17.3.2pipe 函数例程.............................................................................................. - 462 17.3.3 编译运行测试.............................................................................................- 465 - 17.4 有名管道 fifo.......................................................................................................... - 467 17.4.1 使用 man 学习 mkfifo 函数....................................................................... - 467 17.4.2mkfifo 函数例程...........................................................................................- 469 17.4.3 编译运行测试..............................................................................................- 475 - 17.5 消息队列 msg.........................................................................................................- 482 17.5.1 使用 man 学习 msgget 等函数..................................................................- 482 17.5.2msgget 函数例程......................................................................................... - 485 17.5.3 编译运行测试..............................................................................................- 488 - 17.6 信号 signal..............................................................................................................- 492 17.6.1 使用 man 学习 signal 等函数.................................................................... - 492 17.6.2signal 例程 1................................................................................................ - 494 17.6.3 编译运行测试..............................................................................................- 496 17.6.4signal 例程 2................................................................................................ - 497 17.6.5 编译运行测试..............................................................................................- 499 - 17.7 信号量 Semaphore................................................................................................ - 501 17.6.1 使用 man 学习 semget 等函数..................................................................- 501 17.6.2Semaphore 例程.......................................................................................... - 503 - 版本号:V2.0 日期:2015-10-2 - 17 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 17.6.3 编译运行测试..............................................................................................- 507 17.8 共享内存 shmdata................................................................................................. - 509 - 17.6.1 使用 man 学习 shmget 等函数..................................................................- 509 17.6.2shmdata 例程...............................................................................................- 512 17.6.3 编译运行测试..............................................................................................- 517 第十八章 实战 网络通信-套字节 TCP................................................................................ - 520 18.1 本章导读.................................................................................................................- 520 18.1.1 工具......................................................................................................................- 520 18.1.2 预备课程......................................................................................................- 521 18.1.3 视频资源......................................................................................................- 521 18.2 学习目标.................................................................................................................- 521 18.3 实验操作.................................................................................................................- 521 第十九章 实战 网络通信-套接字 UDP............................................................................... - 535 19.1 本章导读.................................................................................................................- 535 19.1.1 工具......................................................................................................................- 535 19.1.2 预备课程......................................................................................................- 535 19.1.3 视频资源......................................................................................................- 536 19.2 学习目标.................................................................................................................- 536 19.3 实验操作.................................................................................................................- 536 第二十章 实战 搭建 web 服务器........................................................................................ - 547 20.1 本章导读.................................................................................................................- 547 - 版本号:V2.0 日期:2015-10-2 - 18 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 20.1.1 工具......................................................................................................................- 547 20.1.2 预备课程......................................................................................................- 547 20.1.3 视频资源......................................................................................................- 548 - 20.2 学习目标.................................................................................................................- 548 20.3 实验操作.................................................................................................................- 548 第二十一章 实战 web 控制 led...........................................................................................- 584 21.1 本章导读.................................................................................................................- 584 21.1.1 工具......................................................................................................................- 584 - 21.1.2 预备课程......................................................................................................- 584 21.1.3 视频资源......................................................................................................- 585 21.2 学习目标.................................................................................................................- 585 21 实验操作....................................................................................................................- 585 - 版本介绍 注意:《iTOP-4412 Linux 系统编程》会不定期更新,更新之后会直接上传到迅为 QQ 技 术支持群的共享文件中。 当前版本为《iTOP-4412 Linux 系统编程 V2.0》 更新说明 V2.0 框架修改说明 20151020-1031 简化难度大的实验“最小文件系统””TFTP 服务器”“NFS 文件系统”等,并针对不同网络提供额外的解决方案 版本号:V2.0 日期:2015-10-2 - 19 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 添加更多的基础知识,例如绝对路径和相对路径,代码运行返 回信息,同一网段等基本概念 20150501-10.13 V2.0 实验手册做了手术刀式的改动! 抛弃原来教程的架构,将需要大篇幅介绍的知识点转为“专 题”; 将保留的 V1.1 版本中大部分代码更新,具有更强的可读性, 学习性,紧凑感; 在本手册中,梳理整个 Linux 系统中重要的知识点。 内容修改说明 新添加 04_linux 用户、权限等基本概念简介 将 V1.1 中文件 IO 相关知识和代码单独合为一个大的专题“专 题-文件 IO”,其中包含多个实验 将 V1.1 和设备节点 IO 相关的内容合为专题实战“字符设备 控制”,包含多个实验 将 V1.1 和串口相关的内容合为专题实战“linux 串口编程” 将 V1.1 和 NFS 相关的内容合为专题“NFS 网络文件系统”, 做了更加细化的介绍 将 V1.1 和进程相关的内容编为专题“进程”和“进程通信”, 分别包含多个实验 将 V1.1 和进程相关的内容编为专题“时间管理”,包含多个实 验 版本号:V2.0 日期:2015-10-2 - 20 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 将 V1.1 和 TFTP 相关的内容合为专题实战“TFTP 服务器搭建 和测试”,做了更加细化的介绍 将 V1.1 和 TFTP 相关的内容合为专题实战“开发板实现 TFTP 文件传输”,做了更加细化的介绍 新添加专题“管理文件和目录” 参考网站 https://www.ibm.com/developerworks/ IBM 开发者社区(中文) https://www.kernel.org/ linux 社区(英文) https://github.com/ github 社区(英文) 参考书目 C 程序设计语言(第二版.新版) (美)Brian W.Kernighan Dennis M.Ritchie 编著 徐宝文 李志 译 机械工业出版社 现代操作系统 (荷)Andrew S.Tanenbaum(Vrije 大学) 编著 陈向群 马宏兵等译 机械工业出版社 其它资料 三星 TOPEET_coreboard4412_scp 或者 TOPEET_coreboard4412_pop 版本号:V2.0 日期:2015-10-2 - 21 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 迅为电子用户使用手册 迅为电子开发板 iTOP4412_MAIN_CLASICS 原理图 版本号:V2.0 日期:2015-10-2 - 22 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第一章 前言 很多学习用户购买开发板的时候,似乎目标很明确“学习 linux 驱动”。但是在实际的学 习过程中却会进入一些误区,白白浪费很多时间,甚至做大量的无用功。 废话少说,学习型用户买来开发板,最终的目标是能够获取一份相关的工作。既然大家的 “终极目标”很明确了,那么就先从 linux 相关的工作说起。 视频资源 本章配套视频为: “视频 01 前言” Linux 相关工作分析 Linux 作为一个庞大的体系,有很多相关的研究领域,总结起来大致有五个方向: 一、服务器维护:需要了解 Linux 服务,熟练使用 Shell,了解网络配置。 二、服务器开发:需要学习 Linux 程序设计和 Linux 网络编程。 三、嵌入式 Linux 应用程序:需要学习 C 语言和基本的 Linux 常识。 四、嵌入式 Linux 驱动:除了需要学习“嵌入式 Linux 应用程序”的知识以外,还需要了 解简单的芯片原理以及一些电路基础知识,还需要对 Linux 内核有一定的了解”。 五、Linux 可视化应用程序:除了需要学习“嵌入式 Linux 应用程序”的知识以外,还需 要学习 GDK 或者 QT 或者 Android 的知识。 版本号:V2.0 日期:2015-10-2 - 23 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 大家会发现只要是和 linux 编程相关的工作岗位,都是必须掌握编写 linux 应用程序,所有 linux 应用的基础是 linux 系统编程。就拿 linux 驱动工程师,大家可以想象一下驱动工程师将 驱动写好之后,是给上层使用的,那么驱动工程师也是需要先编写应用程序来测试的。 那么先来看看 51job 或者 58 同城等招聘网上对 linux 工程师的要求。 如下图所示,是作者随机截取的招聘信息。 职位一:关键词是“北京+linux 软件工程师”。下面的测试,熟悉 linux 操作系统,网络 编程等都是这本实验手册中介绍的主要内容,需要额外的数据库技能(这个公司可能是做服务 器开发的)。 职位二:关键词是“北京+linux 软件工程师”。网络编程,操作系统等,额外技能是可视 化开发(java+Android)+硬件基础知识(这个公司应该是做嵌入式产品的)。 版本号:V2.0 日期:2015-10-2 - 24 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 职位三:关键词是“北京+linux 软件工程师”。网络编程,linux 操作系统等,额外技能 是 linux 驱动开发+对音频视频开发非常熟练(可能是做安防监控或者类似的公司)。 版本号:V2.0 日期:2015-10-2 - 25 - www.topeetboard.com 北京迅为电子有限公司 linux 编程怎么入门 iTOP-4412 Linux 系统编程 V2.0 最好的 linux 学习突破口是 linux 系统编程,没有之一! 有人说是裸机,看看招聘信息就知道,没有任何招聘信息在任何一点提到裸机程序。 那么裸机程序是给那些用户使用的?裸机程序不是给学习单片机或者 stm32 程序员准备 的,是给只有上位机变成经验的纯软件工程师准备的。 大家可以看一下网上的招聘信息,部分会要求对硬件有一定的了解,例如 gpio,i2c,uart, 485 等,这些需要程序员用到示波器,万用表之类的工具,需要用到一些最简单的硬件应用的 知识。对于专业是软件工程的程序员,一直从事软件开发,那么会有一点点对硬件理解上的帮 助。 假如你的专业是自动化,计算机,电子,电气工程,通信工程,物理专业等等,学习这东 西完全是在浪费时间,学习过大学物理,模电,数电等相关课程,完全没必要去使用裸机,单 片机编程就是裸机编程。特别强调的一点,学习过单片机的用户,假如到了操作系统,还在想 着利用裸机入门是永远学不会 linux 编程的! 少数的单片机老师,在给大家介绍单片机学习的时候,会传递类似这样的信息“学习了单 片机,带操作系统的编程也是一样的”等等。 其实完全不一样!带有任何一个操作系统之后,操作系统本身会带很多功能,提供了很多 接口。在初期,学习的重点就是学习使用这些自带的功能,熟悉这些接口。 还有一点给大家说明一下,linux 程序员什么时候会接触到最底层。 版本号:V2.0 日期:2015-10-2 - 26 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 例如 linux 的网络编程,最底层的网络部分已经有全世界最优秀的程序员完成,花费了几 十年时间,而且目前仍然在维护升级中,这个是世界性的任务,作为初学者,在很长时间的一 段时间内都是直接拿来使用。 那么学习到了什么程度会做这些开发呢?如果大家英文不错,可以看一下国外做 linux 最 底层开发的招聘要求,一般是 8 年或者 10 年以上的经验,这个几乎是硬性规定。 所以大家老老实实的一步一步的来,不要想太多没用的东西。 什么是 Linux 系统编程 任何一个操作系统编程都需要对系统本身有一定的了解。 前面最基础的实验中,介绍了搭建 linux 环境,linux 命令行,gcc 编译,各种开发工具等 等,都是必须掌握和熟悉使用的。 它们都是工具,俗话说“磨刀不误砍柴工”,跟着手册走通一遍,以后新的环境就没有什 么问题了。 Linux 系统编程,最主要的是介绍 linux 的一些编程思想以及 linux 中相关的 API 用法。 Linux 最核心的思想是“一切皆文件”!包括: 在其它操作系统中就是以文件形式出现的例如文本,音频,视频等等; Linux 下的目录,是以文件形式出现的; linux 驱动的接口等等。 Linux 中 API 包括: 版本号:V2.0 日期:2015-10-2 - 27 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 各种文件的操作等等 进程的 API(作为操作系统,学习多任务是必须的) Linux 的内部通信,进程间通信等 网络通信(常规的 socket,udp,tcp 等等) Linux 的时间(linux 有一套自己的时间接口) 另外如果对 C 不是很熟悉,还需要学习 C 自带的一些函数,在做技术支持的过程中,发现 这个问题很严重,一些例程中直接调用的一些 C 库函数,经常有用户来问。 还有结构体知识,数据结构非常重要,如果对 C 中的数据结构不是很熟悉,也是需要夯实 C 的基础。 关于 linux 系统编程实验手册 实验手册本身涵盖所有知识点,包括大大小小 60 个左右的实验,大家可以对照手册的目 录来了解一下。 一 介绍最小 linux 系统和 helloworld 小程序。也就是先来看一下这个最小操作系统是怎 么来的,大概有一个了解,然后运行一下小程序,熟悉一下 linux 系统编程的编译和运行。 二 linux 中基本的概念。用户、用户组、权限等等,这些可能是大家在其它操作系统中不 怎么注意到,但是在 linux 中需要理解的概念。 三 linux 中的文件部分。这部分贯穿整个手册,包括各种普通文件的基本操作,设备节点 文件的操作,目录文件等等,几乎占了一半篇幅。 版本号:V2.0 日期:2015-10-2 - 28 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 四 串口应用的编程。这个实在太重要了,对于任何一份针对新手程序员的工作,几乎一半 以上都会接到串口编程的任务!这个和单片机串口开发完全不一样!和其它任何操作系统的串 口编程是类似的,好好学习这部分内容,新工作中绝对会直接用到! 五 进程以及进程通信。实现多任务就靠这部分知识了,主要是一些系统接口。如果手册中 提到系统函数或者系统接口或者系统 API,都是同一个意思。 六 网络通信。Linux 下几乎支持所有的网络通信协议,非常强大!手册中选取了包括 TFTP 服务器以及客户端,NFS 文件启动,TCP 以及 UDP,WEB 服务器等。 七 man 命令。授人以鱼不如授人以渔!程序员的基础修养中,看文档是必须的,在长时 间的技术支持过程中,无数次提到要大家看文档,很多用户顽固的执着的“屡教不改”!所以 在手册升级过程中,花了大量的时间做引导工作。Linux 中的文档,非常方便,就是使用 man 命令查看相关文档,类似 window 和 Android 的开发文档。 这部分多说几句,很多用户问我“不想看英文的手册”,我的回答是“如果一直顽固的不 去看英文手册,那就从事别的工作,或者做一辈子的单片机工程师,那个中文文档多一些”。 既然选择了,就去努力,这个是基础,单词一个一个记,函数和接口一个一个的去理解,文档 一篇一篇的看。 当一个人一心前行,整个世界都会为他让路,不就是几个单词么!作为程序员,其实哪怕 大部分单词不会读都没关系,只要看到单词知道是什么意思即可,估计不到 2000 个单词,坚 持几个月,看到不认识的就记录下来,反复拿出来记忆,很快阅读英文手册就没什么问题了。 关于 linux 驱动 关于 linux 驱动,这里先简单介绍一下。 版本号:V2.0 日期:2015-10-2 - 29 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 学习 linux 最好的方式就是阅读源码,这句话本身没有错。但是对于新手就是容易产生一 个误导,很多新手会以为是从 linux 启动的程序开始阅读,这样理解就大错特错了! 大家可以这样理解,Linux 本身可以类比为地球,一直转着,你不要管是谁推动了第一下, 你要做的就是在上面盖房子,linux 驱动相当于房子的地基!阅读 linux 源码,其实是去看地基。 “地基”分为三大类,字符设备,块设备,网络设备。块设备和网络设备是属于摩天高楼, 有固定的人去做,大部分程序员不需要去写,大部分字符设备必须自己会修改会写。 大家可以看一下 linux 驱动工程师的招聘要求,要求高一点,肯定会要求 BSP 开发,也就 是板级开发,这个过程就是说的 linux 移植。板级开发需要对英文熟练,掌握 gcc 的编译,调 试修改 BUG 等,主要内容是将系统在板子上跑起来,调试通网络和摄像头等等驱动,这个过程 一般是需要两年或者三年以上经验,而且也不需要自己去写块设备和网络设备,只是去移植。 迅为另外的一本 Linux 驱动实验手册会详细介绍字符设备的开发,以及网络设备开发的关 键点。作为初学者,不要着急去弄驱动,这都是有一个过程,基础不牢固,基本的概念没弄明 白,直接学习驱动会事倍功半,反而得不偿失。 学习 linux 的时间 前面介绍过,linux 程序员有不同的要求,不可能一口吃个胖子。 单片机只需要 15 天,甚至更短的时间,就可以找到相关的工作。作者当年毕业后,就是 学习了一个星期,然后就找工作,面试,通过,接着从事了一段时间的嵌入式单片机开发。 无论是什么样 linux 编程相关的工作岗位,都是可以终身从事的职业。做应用,做驱动, 做可视化开发等,都需要长期终身的学习。 版本号:V2.0 日期:2015-10-2 - 30 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 假如从来没有接触过操作系统编程的知识,平均每天两小时,坚持一年时间,就基本可以 从单片机编程到 linux 编程了;如果接触过其它操作系统编程,那就会非常快,三个月左右就 可以了。 如果有了操作系统编程的基础之后,加上基础比较好(主要是阅读英文文档的能力和编程 能力),转到 linux 驱动开发会非常快。 如果要做到熟练 BSP 开发,培养周期一般就是三年左右了。以迅为电子的工程师为例,板 级开发的工程师,从事程序员工作都是 5-15 年左右。 如果更高级的底层开发,前面介绍过最基本要求是 8 年以上 linux 编程经验,而且要求英 文口语过关,交流没障碍。 版本号:V2.0 日期:2015-10-2 - 31 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第二章 最小 Linux 系统 2.1 本章导读 Exynos-4412 不仅可以运行 Android,还可以运行简单的 Linux 最小文件系统。 最小 Linux 系统是“麻雀虽小,五脏俱全”,它是不带图形界面的 linux 系统,可以用来 学习 linux 系统编程,便于理解。 本章主要介绍如何生成最小 Linux 系统,用户也可以在网盘目录“iTOP4412 开发板资料 汇总(不含光盘内容)”→“iTOP-4412 开发板视频教程及其相关”→“02-嵌入式 Linux 视 频”→“视频 02_01 搭建好的最小 linux 系统”中找到已经搭建好的最小 Linux 系统。如下图 所示“视频 02_02 搭建最小 linux 系统”目录下还有其它工具。 2.1.1 工具 2.1.1.1 硬件工具 PC 机 开发板 2.1.1.2 软件工具 版本号:V2.0 日期:2015-10-2 - 32 - www.topeetboard.com 虚拟机 Ubuntu 系统 Busybox 工具 北京迅为电子有限公司 2.1.2 预备课程 基本开发工具的使用 常用 linux 命令 最小 linux 系统 2.1.3 视频资源 本章配套视频为: “视频 02_01 搭建好的最小 linux 系统” “视频 02_02 搭建最小 linux 系统” 2.2 学习目标 本章需要学习以下内容: Linux 常用命令 Linux 内核的编译 Vim 编辑器的使用 iTOP-4412 Linux 系统编程 V2.0 版本号:V2.0 日期:2015-10-2 - 33 - www.topeetboard.com 北京迅为电子有限公司 2.3 最小 Linux 系统简介 iTOP-4412 Linux 系统编程 V2.0 制作文件系统我们需要使用到 Busybox 工具。BusyBox 是一个集成了一百多个最常用 linux 命令和工具的软件。BusyBox 包含了一些简单的工具,例如 ls、cat 和 echo 等等,还包 含了一些更大、更复杂的工具,例 grep、find、mount 以及 telnet。有些人将 BusyBox 称 为 Linux 工具里的瑞士军刀。简单的说 BusyBox 就好像是个大工具箱,它集成压缩了 Linux 的许多工具和命令,也包含了 Android 系统的自带的 shell。 Busybox 的下载网址是 http://www.busybox.net/,这是一个开源的程序,并且一直在更 新中,这里使用的版本是 busybox-1.21.1.tar.bz2。 下面 2.4 小节直接使用制作好的最小 linux 系统,可以烧写制作好的最小 linux 系统,感受 一下最小 linux 系统。 本章 2.5 小节及其后面的小节介绍如何一步步制作最小文件系统。 2.4 搭建好的最小 linux 系统 如下图所示,在配套视频目录“视频 02_01 搭建好的最小 linux 系统”下提供了 “system.img”文件系统。 版本号:V2.0 日期:2015-10-2 - 34 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 开发板运行一个完整的操作系统需要四个文件“u-boot-iTOP-4412.bin”“zImage” “ramdisk-uboot.img”“system.img” 文件“u-boot-iTOP-4412.bin”不用烧写,是通用的。 内核 zImage 使用 QtE 的即可,可以使用光盘“image/linux”目录下的“zImage”文 件。“ramdisk-uboot.img”可以直接使用光盘目录“image/linux”下的“ramdisk-uboot.img” 文件。 最后的文件系统“system.img”使用如上图所示的文件 烧写最小文件系统的方式和 Android 文件系统的烧写一样。 需要注意的是,最小 linux 系统并没有显卡,只能在超级终端控制台中进行操作。 烧写之后重启开发板,如下图所示 2.5 配置 Busybox 下面来讲解一下如何使用 BusyBox 制作最小文件系统。 在虚拟机的 Ubuntu 的目录“/home”下新建目录“mkdir minilinux”,这个目录可以 根据个人习惯建立,并不是强制要求,如下图所示。 版本号:V2.0 日期:2015-10-2 - 35 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用 SSH 软件拷贝 busybox-1.21.1.tar.bz2(这个软件在对应的实验视频目录文件下)到 虚拟机的 Ubuntu 系统上的目录“/home/minilinux”下,然后在目录“/home/minilinux” 下,执行解压命令“tar -xvf busybox-1.21.1.tar.bz2”解压完成后如下图。 然后使用“cd busybox-1.22.1”进入到 busybox-1.22.1 目录中,如下图。 版本号:V2.0 日期:2015-10-2 - 36 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 Busybox 的编译配置和 Linux 内核编译配置使用的命令是一样的,下面我们开始配置 Busybox,如下图所示,使用命令“make menuconfig”如下图。 会出现 Busybox 的配置界面,如下图: 版本号:V2.0 日期:2015-10-2 - 37 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图,选中 Busybox Settings,然后按回车进入到 Busybox Settings 界面,如下图。 在 Busybox Settings 配置选项里面需要修改两个地方,第一个是 Build Optiions-> Cross Compiler prefix,它是指定用什么编译器来编译 Busybox,选中 Build Options 如上图,然后 按回车,进入到 Build Options 配置界面,如下图。 版本号:V2.0 日期:2015-10-2 - 38 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 选中 Build Options 配置界面的 Cross Compiler prefix 如上图,然后按回车,进入 Cross Compiler prefix 配置界面,如下图。 输入使用的交叉编译工具 arm-none-linux-gnueabi-,如下图: 版本号:V2.0 日期:2015-10-2 - 39 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后按回车返回到 Build Options 配置界面,这时可以看到刚才设置的交叉编译工具,如 下图。 然后使用键盘的左右按键选中 Exit,如下图。 版本号:V2.0 日期:2015-10-2 - 40 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后按回车,回到 Busybox Settings 设置界面,如下图。 选中 Installation Options 如上图,然后按回车,进入 Installation Options 配置界面,如 下图。 版本号:V2.0 日期:2015-10-2 - 41 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 选中 BusyBox installation prefix 如上图所示,然后按回车进入 BusyBox installation prefix 配置界面(这个界面是设置编译完 Busybox,把最终生成的二进制文件安装到哪个目录 下面),如下图。 删除上图里面的./_install,然后输入“../system”(最终生成的二进制文件会安装到当前 目录的上一级目录下的 system 目录里面,注意有两个点),如下图: 版本号:V2.0 日期:2015-10-2 - 42 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后按回车,回到 Installation Options,如下图。 使用键盘的向右方向键移动光标到“Exit”,如下图。 版本号:V2.0 日期:2015-10-2 - 43 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后按回车,返回到 Busybox Settings,使用键盘向右的方向键,移动光标到“Exit”, 如下图。 然后按回车,返回到 Busybox Configuration,使用键盘向右的方向键移动光标到“Exit”, 如下图。 版本号:V2.0 日期:2015-10-2 - 44 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后输入回车,弹出保存配置界面,使用键盘向右的方向键,移动光标到“Yes”,然后按 回车保存配置,退出配置界面,如下图。 然后按回车保存配置,退出配置界面,如下图。 版本号:V2.0 日期:2015-10-2 - 45 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 2.6 编译和安装 Busybox 现在 Busybox 的配置已经完成了,接下来开始编译 Busybox,在 Ubuntu 的终端输入 make 命令开始编译 Busybox,如下图。 下图为编译过程中的截图: 版本号:V2.0 日期:2015-10-2 - 46 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,编译完成。 现在编译完成了,接下来我们需要把编译生成的二进制文件安装到刚才我们指定 的../system 目录里面,使用命令“make install”安装二进制文件到“../system”目录,如下 图。 版本号:V2.0 日期:2015-10-2 - 47 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,执行完成。 使用命令“cd ../system/”,打开“../system”目录,看看里面安装的文件,如下图。 版本号:V2.0 日期:2015-10-2 - 48 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 2.7 完善最小 Linux 系统的文件 这一小节给大家介绍如何添加最小系统需要的网络文件、用户文件、库等。 本节使用到的文件都可以在对应的视频目录下找到,如下图所示。 版本号:V2.0 日期:2015-10-2 - 49 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 制作的文件系统还需要 dev,etc,lib,mnt,proc,sys,tmp,var 文件夹,使用命令“mkdir dev etc lib mnt proc sys tmp var”创建文件夹,如下图所示。 使用命令“cd etc”进入到刚才创建的 etc 文件夹,如下图所示。 在 etc 目录下使用命令 vi 或者 vim 建立 eth0-setting 文件,并在 eth0-setting 文件里输 入下面的内容。 版本号:V2.0 日期:2015-10-2 - 50 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示。 如下图所示。 版本号:V2.0 日期:2015-10-2 - 51 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后保存并退出 eth0-setting,使用“chmod 755 eth0-setting”命令修改 eth0-setting 的权限,如下图。 在 etc 目录下用“mkdir init.d”命令建立 init.d 文件夹,如下图所示。 版本号:V2.0 日期:2015-10-2 - 52 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后使用“cd init.d”命令进入到 init.d 文件夹,如下图所示。 在 init.d 文件夹下面使用“vim ifconfig-eth0”命令建立 ifconfig-eth0 文件,如下图所 示。 版本号:V2.0 日期:2015-10-2 - 53 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后在 ifconfig-eth0 文件输入下面的内容。 如下图所示。 版本号:V2.0 日期:2015-10-2 - 54 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后保存并退出 ifconfig-eth0,使用命令“chmod 755 ifconfig-eth0”修改 ifconfig-eth0 的权限,如下图所示。 然后在 init.d 文件夹下面使用“vim rcS”命令建立 rcS 文件,如下图。 版本号:V2.0 日期:2015-10-2 - 55 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后在 rcS 文件输入下面的内容。 版本号:V2.0 日期:2015-10-2 - 56 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示。 版本号:V2.0 日期:2015-10-2 - 57 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后保存并退出 rcS,使用命令“chmod 755 rcS ”修改 rcS 的权限,如下图。 接下来使用“cd ../”命令返回到 init.d 的上一级目录 etc,如下图所示。 版本号:V2.0 日期:2015-10-2 - 58 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接下来在 etc 目录下使用命令“vim passwd”建立文件 passwd,如下图: 在新建立的 passwd 文件输入下面的内容。 版本号:V2.0 日期:2015-10-2 - 59 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 输入结果如下图。 然后保存并退出 passwd,使用“chmod 755 passwd”命令修改 passwd 的权限,如下 图所示。 版本号:V2.0 日期:2015-10-2 - 60 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后使用命令“vim profile”在 etc 目录建立 profile 文件,如下图所示。 然后在 profile 输入下面的内容。 版本号:V2.0 日期:2015-10-2 - 61 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 输入结果如下图。 版本号:V2.0 日期:2015-10-2 - 62 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后保存并退出 profile,使用“chmod 755 profile”命令修改 profile 的权限,如下图所 示。 接下来使用“mkdir rc.d”命令在 etc 目录建立文件夹 rc.d,如下图所示。 使用 cd 命令进入到刚才建立的 rc.d 文件夹,如下图所示。 版本号:V2.0 日期:2015-10-2 - 63 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接下来使用命令“cd rc.d/”进入 rc.d 目录,在 rc.d 目录下使用命令“mkdir init.d”建立 init.d 文件夹,如下图所示。 然后使用“cd init.d”命令进入到刚才建立的 init.d 文件夹,如下图所示。 版本号:V2.0 日期:2015-10-2 - 64 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着在 init.d 文件夹,使用“vim netd”命令建立 netd 文件,如下图所示。 然后在 netd 文件里面输入下面的内容: 版本号:V2.0 日期:2015-10-2 - 65 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 输入结果,如下图所示。 版本号:V2.0 日期:2015-10-2 - 66 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后保存并退出 netd,使用“chmod 755 netd”命令修改 netd 的权限,如下图所示。 接着使用“cd ../../”命令返回到 etc 目录,如下图所示。 版本号:V2.0 日期:2015-10-2 - 67 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着使用“cd ..”命令返回到 system 目录,如下图所示。 接着使用“cd lib”命令进入到 lib 目录,如下图所示。 版本号:V2.0 日期:2015-10-2 - 68 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 因为使用的交叉编译环境和编译内核的相同,所以编译器是/usr/local/arm/arm-2009q3, Busybox 编译生成的二进制文件十一动态链接库的形式运行,所以我们需要拷贝编译器里面的 库文件到 lib 目录,使用下面的命令: “cp /usr/local/arm/arm-2009q3/arm-none-linux-gnueabi/libc/lib/* ./” 执行结果如下图所示。 版本号:V2.0 日期:2015-10-2 - 69 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 库文件拷贝完成后,使用“cd ../”命令返回到 system 目录,如下图: 接下来使用“cd var”命令进入到 var 目录,如下图所示。 然后使用“mkdir lib lock log run tmp”命令在 var 目录下建立 lib,lock,log,run, tmp 五个目录,如下图所示。 版本号:V2.0 日期:2015-10-2 - 70 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 至此,文件系统所需要的文件都已经创建好了,使用 cd ../../命令返回到 system 文件夹的 上一级目录,如下图所示。 到了这一步,制作好的文件夹“system”,可以在视频教程对应的目录下找到。如果发现 后面的操作命令出现了问题,可以对照着修改文件,看看问题出在什么地方。 版本号:V2.0 日期:2015-10-2 - 71 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 2.8 安装打包软件和编译 打包工具 make_ext4fs 可以文件系统制作成二进制文件,先来安装一下 make_ext4fs 工 具。这个工具是光盘“tools”目录下的“linux_tools.tgz”压缩文件。 拷贝压缩包“linux_tools.tgz”到 Ubuntu 系统的“/”目录下,注意目录是“/”,如果 前面在编译 QtE 的时候已经解压过了,这里可以跳过去,如下图所示。 使用解压命令“tar -vxf linux_tools.tgz”解压,如下图所示。 版本号:V2.0 日期:2015-10-2 - 72 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 安装好打包编译工具“make_ext4fs”之后。 使用命令“cd /home/minilinux/”进入目录“/home/minilinux/”,使用命令 “make_ext4fs -s -l 314572800 -a root -L linux system.img system”生成 system.img 文件系统镜像,如下图所示。 接着可以使用 ls 命令查看一下生成的 system.img。 版本号:V2.0 日期:2015-10-2 - 73 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 现在已经完成了 linux 文件系统的制作,最终生成的二进制文件在对应的视频目录下也有, 如下图所示。 2.9 最小 Linux 系统的烧写 最后需要把制作好的 system.img 烧写到 iTOP-4412 开发板上,烧写的方式和 Android 文件系统的烧写一样。 uboot 文件不用烧写,是通用的。 内核 zImage 使用 QtE 的即可,可以参考使用手册编译出对应的内核也可以使用光盘 “image/linux”目录下的 zImage 文件。 版本号:V2.0 日期:2015-10-2 - 74 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 剩下的文件 ramdisk-uboot.img”可以直接使用光盘目录“image/linux”下的 “ramdisk-uboot.img”。 2.10 常见错误 最小系统的步骤比较多,操作的时候容易出问题,目前统计的最常见的有以下两个不容易 发现的错误。 错误一: 使用 vim 编辑器粘贴代码的时候,没有进入输入模式,导致第一个“i”字符之前全部的代 码都没有粘贴上 错误二: 如下图所示,烧写之后可以启动但是提示找不到串口。 这种情况多半是 init.d 文件夹下的 rcS 文件权限不对,修改一下权限即可。注意修改的时 候最好将其中的内容“修改一下”,例如,在一个没有代码的地方输入一个空格,然后将这个 空格删除。然后保存退出再修改权限,不然编译打包的时候会默认没有修改导致二进制文件仍 然报错。 版本号:V2.0 日期:2015-10-2 - 75 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第三章 helloworld 3.1 本章导读 本实验介绍经典的 helloworld 程序,就几行代码,非常简单,主要是需要学习一下应用程 序如何编译、如何运行、如何修改权限等等实际操作。 3.1.1 工具 3.1.1.1 硬件工具 开发板 PC 机 U 盘或者 TF 卡 3.1.1.2 软件工具 Ubuntu12.04.2 以及虚拟机 Arm-2009q3 编译器 Notepad++编辑器 超级终端 Vim 编辑器 3.1.2 预备课程 基本开发工具的使用 版本号:V2.0 日期:2015-10-2 - 76 - www.topeetboard.com 常用 linux 命令 最小 linux 系统 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 3.1.3 视频资源 本章配套视频为: “视频 03_01helloworld-U 盘” “视频 03_02helloworld-TF 卡” “视频 03_03helloworld 编译到最小文件系统” 3.2 学习目标 本章需要学习以下内容: 编译应用程序 运行应用程序 如何修改应用程序权限 3.3 代码简介 如下图所示,代码非常简单,只要有 C 语言的基础就可以很轻松的搞定。 版本号:V2.0 日期:2015-10-2 - 77 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,首先调用了头文件“stdio.h”,这是告诉编译器本程序中包含标准输入/输出 库的信息,只不过在学习 C 语言的时候,输入/输出是在 PC 的图形界面。 在 linux 中,这个标准输入/输出是通过串口,也就是通过超级终端来实现的。 接着调用 main 函数作为程序入口,main 函数中调用了 printf 打印函数,也就是把其中的 内容打印到超级终端。最后在开发板上运行这个程序的时候,应该会在超级终端中打印“Hello World!”。 3.4 编辑和目录介绍 如下图所示,在 Ubuntu 下建立一个专门的文件夹存放“Linux 系统编程”中的源码和程 序。在目录“/home”下,在 root 用户下,使用命令“mkdir linuxsystemcode”新建目录 “linuxsyetemcode”(用户也可以建立在其它目录下)。 版本号:V2.0 日期:2015-10-2 - 78 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后如下图所示,使用命令“cd linuxsystemcode/”进入目录“linuxsystemcode”, 使用命令“mkdir helloworld”,新建“helloworld”目录,然后使用命令“ cd helloworld/” 进入新建的目录“helloworld”。 代码的编辑可以使用 window 下的编辑器例如“Notepad++”,这个编辑器的用法在入门 教程中已经介绍过,这个软件是免费的,在编辑简单程序的时候,简单高效。 版本号:V2.0 日期:2015-10-2 - 79 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 或者使用编辑器 vi 编辑器或者 vim 编辑器,将“helloworld.c”拷贝到前面新建的 “helloworld”目录下,使用命令“vi helloworld.c”或者“vim helloworld.c”命令(使用 vim 编辑器需要安装,在入门视频中介绍过了这里就不再重复),如下图所示。 版本号:V2.0 日期:2015-10-2 - 80 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 Linux 系统编程中,在后面实验的代码如果没有特殊说明,都会在目录 “/home/linuxsystemcode”下新建目录然后在其中存放代码。 3.5 编译 本节介绍如何编译可以在开发板上运行的应用,编译方法很简单。 首先要确定一下环境变量,如下图所示,使用“cd”命令回到根目录,然后使用命令 “vim .bashrc”打开环境变量文件。 版本号:V2.0 日期:2015-10-2 - 81 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,进入最底行,这里使用的和编译内核的编译器一样就可以。 使用命令“cd /home/linuxsystemcode/helloworld/”回到 “/home/linuxsyetemcode/helloworld”目录中,如下图所示,使用命令 “arm-none-linux-gnueabi-gcc -o helloworld helloworld.c -static”,将当前目录下的 C 文件“helloworld.c ”编译成可执行文件“helloworld”; 版本号:V2.0 日期:2015-10-2 - 82 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 “arm-none-linux-gnueabi-gcc ”表示使用 arm 编译器,对应 iTop4412 开发板; “-static”表示将库也编译进去。 如下图所示,编译成功,生成“helloworld”文件。 版本号:V2.0 日期:2015-10-2 - 83 - www.topeetboard.com 北京迅为电子有限公司 3.5 修改权限和运行-U 盘 iTOP-4412 Linux 系统编程 V2.0 先介绍如何通过 U 盘或者 TF 卡将可执行文件 helloworld 拷贝到开发板。 这里只介绍如何用 U 盘将可执行程序拷贝到开发板。 先将可执行文件 helloworld 拷贝到 U 盘,启动开发板如下图所示。 如下图所示,如果文件系统第一次启动的时候没有/mnt/udisk 目录,所以需要使用命令 “mkdir /mnt/udisk”新建。 然后加载 u 盘,插入 u 盘的时候,被识别为 sda1,使用命令 “mount /dev/sda1 /mnt/udisk”加载 u 盘,如下图所示。 版本号:V2.0 日期:2015-10-2 - 84 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这个时候可以直接在 U 盘中运行,如下图所示,使用命令 “chmod 777 /mnt/udisk/helloworld”修改权限。 然后使用命令“./mnt/udisk/helloworld”运行 helloworld 程序,如下图所示。 也可以将程序拷贝到 bin 目录下,在 linux 系统中一般这个 bin 目录就是放可执行程序的。 使用拷贝命令“cp -r /mnt/udisk/helloworld /bin/”如下图所示。 然后修改一下权限,使用命令“chmod 777 /bin/helloworld”,如下图所示。 版本号:V2.0 日期:2015-10-2 - 85 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 运行 helloworld 程序,使用命令“./bin/helloworld”,如下图所示,运行之后可以看到 有打印信息“Hello World!”。 3.6 修改权限和运行-TF 卡 这一小节介绍最小系统如何挂载 tf 卡,运行程序。 如下图所示,启动开发板。 插入 tf 卡,如下图所示,注意红色椭圆框中的内容,这个是 tf 卡的设备节点。 版本号:V2.0 日期:2015-10-2 - 86 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,使用命令“mkdir /mnt/udisk1”新建/mnt/udisk1 目录。 如下图所示,使用命令“mount /dev/mmcblk1p1 /mnt/udisk1”加载 tf 卡,注意红色 部分是和前面系统自动识别的设备节点对应的。 版本号:V2.0 日期:2015-10-2 - 87 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,使用命令“ls /mnt/udisk1/”可以查看到 helloworld 可执行程序。 如下图所示,使用命令“./mnt/udisk1/helloworld”运行 helloworld,打印出了 Hello World!。 如果提示权限不够,可以使用命令 chmod 修改权限后再运行。 版本号:V2.0 日期:2015-10-2 - 88 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 3.7 将 helloworld 编译进文件系统 可以将程序直接编译进文件系统,这样就可以不用 U 盘或者 TF 卡来拷贝程序了。 如下图所示,使用 cp 命令将编译好的 helloworld 程序赋值到 system 下的 bin 目录。 版本号:V2.0 日期:2015-10-2 - 89 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后编译 system,然后将重新烧写一下“system.img”文件系统,运行方法和 4.5 小节 类似,先是修改权限,然后是运行/bin 目录下的 helloworld 可执行程序。 另外提醒一下,在本小节中,不修改 helloworld 的权限也是可以运行的。 如果不熟悉 linux,在调用一些资源的时候会经常出现“permission denied”,这个时候 需要修改权限不够的资源,这里只是给大家演示一下。 3.8 程序分析 如下图所示,这是 linux 体系结构图,其中应用程序如果想和底层通信,则必须通过系统 接口,在和系统接口通信的时候,中间还可以调用 C Library。 这个简单的 helloworld 程序就是调用了 C 库,完成打印功能。 只要是从事和 linux 编程相关的工作,都会用到 C 库和系统接口(system call interface), 这些都是基础。 版本号:V2.0 日期:2015-10-2 - 90 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 哪怕是驱动工程师,驱动写出来之后也需要写测试程序,测试程序也需要用到很多系统接 口知识和 C 库,所以这是必须学习和熟练掌握的内容。 嵌入式研发工作岗位中唯一不需要掌握这部分知识的工程师,就是做纯界面工程师,像 Android 界面或者 QtE 界面工程师。 3.9 小贴士,关于 linux 命令的一点说明 经过这几个实验,想必大家对于 linux 的基本操作都很熟悉了,例如进入 xx 目录或者打开 xx 文件之类。这些操作在后续的实验中会越来越精简,如果对于 cd 命令,vim 命令,vim 编 辑还不是很熟练,建议回头再练习一下,这些命令都是 linux 中最最基本的知识。 如果我们把篇幅或者精力用在介绍 linux 基本命令上,无论我们介绍的多么详细,视频录 制的多么的生动,大家学习到一定程度或者水平达到一定的阶段,我们都会“挨骂”的。另外 假如大家看到一个视频是全部介绍 linux 命令的,而且打着嵌入式 linux 实验的名号,那么这个 视频可能不是给程序员准备的,而是给 linux 服务器维护工程师学习的。这里只是提醒大家不 要花费过多的精力做这件事,掌握 man 命令或者 help 命令,“百度”或者“Google”用到 的时候就去查。 那么什么样的人需要详细的学习 linux 命令么?Linux 系统维护工程师需要掌握很多 linux 命令。对于我们编程或者做嵌入式的工程师,只需要掌握少许的命令即可。 版本号:V2.0 日期:2015-10-2 - 91 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第四章 linux 用户、用户组、权限等 4.1 本章导读 本章内容概念性的比较多,在学习的时候需要的操作很简单,主要是要理解 linux 中的这 几个概念,心里有这样几个概念,然后在后面学习的过程中逐渐加深印象和理解。 4.1.1 工具 4.1.1.1 硬件工具 开发板 PC 机 U 盘或者 TF 卡 4.1.1.2 软件工具 Ubuntu12.04.2 以及虚拟机 Arm-2009q3 编译器 Notepad++编辑器 超级终端 Vim 编辑器 4.1.2 预备课程 基本开发工具的使用 版本号:V2.0 日期:2015-10-2 - 92 - www.topeetboard.com 常用 linux 命令 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 4.1.3 视频资源 本章配套视频为: “视频 04_01linux 用户” “视频 04_02linux 用户组” “视频 04_03linux 权限” “视频 04_04linux 绝对路径和相对路径” “视频 04_05 代码运行返回信息” 4.2 学习目标 本章需要学习以下内容: 了解 linux 下用户的概念 了解 linux 下用户组概念 理解和掌握 linux 下修改权限的方法 4.3 Linux 用户管理 Linux 中的用户管理与 Windows 中的用户管理很相似,但又很不相同。 两个系统都是多用户系统,基于用户身份来控制他们对资源的访问。两个操作系统都允许 将用户分组管理以简化访问控制,以避免为众多用户分别设置权限。不过,相同之处也仅此而 已。 版本号:V2.0 日期:2015-10-2 - 93 - www.topeetboard.com 4.3.1 超级用户 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 在 Linux 中,超级用户称为 root。root 用户可以控制所有的程序,访问所有文件,使用 系统上的所有功能。对 root 用户来说没有不可以做的事情。就管理的角度而言,root 的权限 是至高无上的。所以,root 帐号一定要通过安全的密码保护起来,这一点非常重要。 其他用户也可以被赋予 root 特权,但一定要谨慎行事。通常您可以配置一些特定的程序 由某些用户以 root 身份去运行,而不必赋予他们 root 权限。 如下图所示,在虚拟机的 Ubuntu 系统下,使用命令“su root”,然后输入密码即可登录 “root”用户。Ubuntu 默认按装之后并没有 root 账户,需要开启 root 用户,具体参考使用 手册 3.3.2 小节 Ubuntu 中启用 root 用户。 4.3.2 创建和删除用户 可以通过 useradd 命令来创建新用户,可以通过 useradd -help 或者 man 学习其用法, 如下图所示。 版本号:V2.0 日期:2015-10-2 - 94 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示。 如下图所示,使用命令“ useradd xunwei”添加用户 xunwei,然后使用命令“cat /etc/passwd”。 版本号:V2.0 日期:2015-10-2 - 95 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,在/etc/passwd 下可以看到/home/xunwei 用户。 使用“userdel xunwei”命令可以删除用户 xunwei。 另外可以在 root 用户下使用 passwd 修改密码。 4.3.3Linux 用户的组织 在 linux 中,所有的用户都存在于“/etc/passwd”中。如下图所示,使用命令“more /etc/passwd”,这个文件的结构非常直观。每一行是一个新用户,参数用冒号隔开。 版本号:V2.0 日期:2015-10-2 - 96 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 用户的组织文件,非常直观,每一行代表一个一个用户,例如超级用户 “root:x:0:0:root:/root:/bin/bash”。 第一列是用户名;第二列是用户的密码;第三列是用户的数字 ID;第四列是用户的主组的 ID;第五列是用户的全名或者是注释;第六列是用户主目录的位置,这个目录通常位于 /home 目录下,目录名与用户 ID 相同;第七列是用户的默认控制台 shell。 上面第二列的 x,并不代表密码就是 x,这里只是隐藏了,另外只有超级用户可以修改其它 用户的密码。 4.4 Linux 组 Linux 中的组与 Windows 中的组很类似。可以创建一个组,然后将成员添加到这个组的 列表中。可以以组为单位来分配资源。隶属于同一个组的成员可以访问同一资源。 版本号:V2.0 日期:2015-10-2 - 97 - www.topeetboard.com 北京迅为电子有限公司 4.4.1 用户组的操作 iTOP-4412 Linux 系统编程 V2.0 使用控制台命令 groupadd 创建组很简单,如下图所示,使用命令“groupadd mygroup” 创建“mygroup”组,然后使用命令“cat /etc/group”查看。 如下图所示,可以看到新建的组 mygroup。 版本号:V2.0 日期:2015-10-2 - 98 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第一列是组的名字。第二列是一个密码。同样,“x”说明真正的密码存放在 /etc/gshadow 映像文件中。第三列是组的一个数字索引。在第三列之后将是以逗号隔开的组的成员的用户 ID。 4.4.2 用户和组的联系 虽然在这里我们不能详尽地论述访问控制,不过您应该对用户和组对文件的访问权限有初 步的了解。如果您以长格式列出一个目录下的文件,您看到的将如下显示。 -rw-r--r-- 1 userid mygroup 703 Jun 23 22:12 myfile 现在暂时忽略其他的列,只去看第三、四和最后一列。第三列是文件主人的名字,userid。 第四列是关联到这个文件的组,mygroup。最后一列是文件名。每个文件只能属于一个主人和 一个组。可以为不能归于这两类的其他用户 (Other)设置权限。可以认为 Other 相当于 Windows 中的 Everyone 组。 一个文件只能属于一个主人,这在操作系统中很常见,但是,文件只能属于一个组,初次 使用这一规则的管理员可能会觉得受到了限制。事实并不如此。由于用户可以同时是多个组的 成员,所以只需要创建新的组就可以安全使用资源。在 Linux 中,往往是基于所需要的资源访 问权限而不是根据业务单位来定义组。如果系统的资源逻辑上是有组织的,那么可以创建更多 的组来更好地控制对资源的访问。 在 Linux 中管理用户和组的方式与 Windows 中本质上是相同的,但是 Linux 中只能有 惟一的组可以关联到一个系统资源。应该这样认识 Linux 中的组管理:不要吝惜对组的使用, 在复杂的环境中,不要害怕创建很多组。应该根据资源访问权限而不是基于业务单位去创建组。 版本号:V2.0 日期:2015-10-2 - 99 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 用户和组信息分别存储在 /etc/passwd 文件和 /etc/group 文件中。您的系统可能还会 有 /etc/shadow 和 /etc/gshadow 文件,它们存储的是为了安全而经过加密的密码。直接编 辑这些文件来管理用户和组不是不可以,但您一定要谨慎行事。 所有的用户和组的管理都可以在控制台中完成,可以写成脚本。也可以使用 Webmin 等 工具以图形化的方式管理用户和组。 4.5 Linux 权限 Linux 的中,每个文件都有文件所有者和所有组以及权限位。 每一个权限位描述了所有者、所属组以及其它人对文件的读、写和执行的权限。这三类每 一个对应 3 个位,共 9 位。 Linux 中一切皆文件,有大家常规理解的文件,后面有一些特殊的文件,所有的文件权限 都是一模一样的。 如下表所示,表示不同用户和组的权限。 位 八进制 文本值 权限 8 400 r 所有者读 7 200 -w 所有者写 6 100 --x 所有者可执行 5 040 ---r 组用户读 4 020 ----w 组用户写 3 010 -----x 组用户可执行 2 004 -------r 所有用户读 版本号:V2.0 日期:2015-10-2 - 100 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 1 002 --------w 所有用户写 0 001 ---------x 所有用户可执行 修改权限的命令是 chmod,下面举个例子。 在 root 用户下,如下图所示,使用命令“vim /home/topeet/testchmod.c”,新建一个 文件“testchmod.c”。 如下图所示,然后保存退出 vim。 版本号:V2.0 日期:2015-10-2 - 101 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后使用命令“ls -al /home/topeet/testchmod.c”查看文件的详细信息,如下图所示, 新建的文件默认权限为“-rw-r--r--”,也就是创建的所有者用户 root 可以读写,然后组用户 和其它用户都只能读。 键盘上使用“Ctrl+Alt+t”,再开一个终端,默认进入的是 topeet 用户,在这个用户下使 用命令“ vim /home/topeet/testchmod.c ”打开文件,如下图所示。 版本号:V2.0 日期:2015-10-2 - 102 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 打开之后,如下图所示,可以看到只能读。 再回到前面的 root 用户,如下图所示,使用命令 “chmod 777 /home/topeet/testchmod.c”。 版本号:V2.0 日期:2015-10-2 - 103 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后再使用命令“ls -al /home/topeet/testchmod.c”查看文件权限。 第一个 7 表示,这对文件所有用户 root 的权限,400+200+100, 第二个 7 表示,这对文件所在组用户的权限,040+020+010, 第三个 7 表示,这对文件所有用户的权限,004+002+001, 用户可以使用其它组合测试,然后使用 ls 命令查看权限。 版本号:V2.0 日期:2015-10-2 - 104 - www.topeetboard.com 北京迅为电子有限公司 4.6 linux 绝对路径和相对路径 iTOP-4412 Linux 系统编程 V2.0 在 linux 中,会经常用到相对路径和绝对路径的概念。 4.6.1 绝对路径 绝对路径是从”/”目录开始的,“/”也称为根目录。 例如在入门实验中,arm-2009q3 编译器的路径就是绝对路径,如下图所示。 另外还可以使用命令 pwd 来查看当前目录的绝对路径,例如在 helloworld 的源码位置, 如下图所示。 版本号:V2.0 日期:2015-10-2 - 105 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 一般性的识别方法是以”/”开头的路径就是绝对路径。 4.6.2 相对路径 相对路径一般是以“.”或者“../”或者“../../”开头的路径,或者路径前没有”/”。表示 在相对于用户的“当前路径”的目录位置。 如下图所示,例如在绝对路径/home/linuxsystemcode 下。 版本号:V2.0 日期:2015-10-2 - 106 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着想进入当前目录下的 helloworld 目录下,可以使用命令“cd helloworld”,如下图 所示。 如下图所示,假如用户在/home/topeet 目录下,想进入 /home/linuxsystemcode/helloworld 目录,则可以使用命令 “cd ../linuxsystemcode/helloworld/”。 版本号:V2.0 日期:2015-10-2 - 107 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里“../”表示当前目录的上一级目录,“../../”表示当前目录的上两级目录,如果不带 任何点点,则表示在当前目录下的目录。 4.7 代码运行返回信息 注意这里的代码运行返回信息,也包括操作系统中代码返回信息。 这部分不要着急去完全搞明白,最重要的是脑子中有这样一些基本概念,在后面的学习中 会逐渐使用到,经过了实际操作慢慢就会明白。 4.7.1 启动信息 开发板启动之后,在控制台会打印系统的信息,包括硬件基本信息,如下图所示,uboot 引导部分会打印硬件信息,如下图所示,内存,各种时钟信息等等大部分都会在 uboot 运行的 时候打印出来。 版本号:V2.0 日期:2015-10-2 - 108 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 引导到内核之后,会打印驱动注册和运行信息,如下图所示,这部分是电源管理驱动的部 分打印。 学习到了一定程度,这些信息会非常重要。特别是在实际开发中,如果你写一个驱动,没 有设计好打印信息,下一个接手的程序员,在运行的过程中出现了 bug,那么下一个程序员需 版本号:V2.0 日期:2015-10-2 - 109 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 要花大量的时间去查找到底 bug 在什么地方。这些基本信息,可以帮助接手的程序员,快速了 解基本功能,以及查找问题。 4.7.2 程序运行错误 在执行程序的时候,大家最常见的是权限错误,除了权限错误以外,还有变量的一些错误。 这部分信息,是系统提供的,虽然程序可以编译通过,但是在实际运行过程中还是会出一 些问题,在后面的视频教程中,给大家现场写代码调试的时候,会出现一些小错误,这些小错 误会引起内存错误。 如下图所示,是运行 helloworld 的权限错误,修改一下权限就可以正常运行了。 在编写和调试程序的时候,如果运行不正常,一定要看程序返回信息。这是一个必经过程, 也是一个良性循环的过程,出了问题,自己能够动手解决了,这样英文进步了,调试程序的能 力提高了,对于易错点有加深了印象。 版本号:V2.0 日期:2015-10-2 - 110 - www.topeetboard.com 北京迅为电子有限公司 4.7.3 函数返回值错误 iTOP-4412 Linux 系统编程 V2.0 函数返回值错误,大家应该不会陌生,在后面的实验中,调用的各种函数一般都会根据返 回值来判断是否出了问题,如果出错打印一段信息,如果没有出错打印一段信息。 这部分是程序员控制的,在 linux 中通常使用 printf 函数来打印,由于在教材后半部分, 大量的用到了这种方法,这里就不再举例。 现在一定要有这样一个概念,否则学习到后面大家会觉得这样会十分啰嗦,但是这样的啰 嗦是在程序中必不可少的。而且实际工作中,调试程序也是通过一行一行的打印信息来修正 Bug 的。 4.7.4 特殊变量错误 当程序运行发生错误的时候,库函数都会设置状态指示符。这些状态指示符,可以被设置 和测试。在头文件“errno.h”中包含一些错误编码,根据错误编码可以了解最近一次出错的信 息,另外在头文件“stdio.h”中定义了错误打印函数 perror。 如下图所示,使用命令“man 3 perror”查看一下打印错误的函数。 版本号:V2.0 日期:2015-10-2 - 111 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,可以看一下 man 文档中关于函数 perror 的使用。 另外 perror 函数还可以以另外一种方式打印。 代码:fprintf(stderr,”%s:%s\n”,s,”error message”) 等同于上面的函数 perror。 版本号:V2.0 日期:2015-10-2 - 112 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 在学习后面的各种接口函数的时候,如果接口函数运行出错,系统都会设置 error,这个 error 可以通过 perror 或者 fprintf 函数打印出来。 关于 perror 这部分内容是属于 C 语言基础的,在和不少用户接触的过程中发现少部分对于 这部分不了解。如果对这部分不太熟悉,可以找一本 C 语言的书籍来看一下。 版本号:V2.0 日期:2015-10-2 - 113 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第五章 专题 文件 IO 5.1 本章导读 对于传统的操作系统来说,普通的 I/O 操作一般会被内核缓存,这种 I/O 被称作缓存 I/O。本文所介绍的文件访问机制不经过操作系统内核的缓存,数据直接在磁盘和应用程序地址 空间进行传输,所以该文件访问的机制称作为直接 I/O。Linux 中就提供了这样一种文件访问 机制,对于那种将 I/O 缓存存放在用户地址空间的应用程序来说,直接 I/O 是一种非常高效 的手段。 “Linux 中一切皆文件”这句话已经不知道说了多少遍了,后面也会提到很多次。那么在 深入学习之前,肯定要掌握对 Linux 文件的各种操作,包括读、写、创建等基本知识。 5.1.1 工具 5.1.1.1 硬件工具 Ubuntu12.04.2 以及虚拟机 Arm-2009q3 编译器 Notepad++编辑器 超级终端 Vim 编辑器 5.1.1.2 软件工具 掌握对文件 IO 的打开、关闭、读、写 版本号:V2.0 日期:2015-10-2 - 114 - www.topeetboard.com 理解文件 IO 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 5.1.2 预备课程 基本开发工具的使用 常用 linux 命令 最小 linux 系统 helloworld 5.1.3 视频资源 本章配套视频为: “视频 05_1 文件 IO 之 open 打开操作” “视频 05_02 文件 IO 之 creat 创建操作” “视频 05_03 文件 IO 之 write 写操作” “视频 05_04 文件 IO 之 read 读操作” 5.2 学习目标 本章需要学习以下内容: 了解 IO 缓存的基本概念 熟练掌握打开、创建、读、写,关闭等操作文件的方法 版本号:V2.0 日期:2015-10-2 - 115 - www.topeetboard.com 北京迅为电子有限公司 5.3 Linux 中 IO 的概念介绍 iTOP-4412 Linux 系统编程 V2.0 所有的 I/O 操作都是通过读文件或者写文件来完成的。在这里,把所有的外围设备,包括 键盘和显示器,都看成是文件系统中的文件。 5.3.1 什么是缓存 I/O 缓存 I/O 又被称作标准 I/O,大多数文件系统的默认 I/O 操作都是缓存 I/O。在 Linux 的 缓存 I/O 机制中,操作系统会将 I/O 的数据缓存在文件系统的页缓存( page cache )中, 也就是说,数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷 贝到应用程序的地址空间。缓存 I/O 有以下这些优点:  缓存 I/O 使用了操作系统内核缓冲区,在一定程度上分离了应用程序空间和实际的物理 设备。  缓存 I/O 可以减少读盘的次数,从而提高性能。 当应用程序尝试读取某块数据的时候,如果这块数据已经存放在了页缓存中,那么这块数 据就可以立即返回给应用程序,而不需要经过实际的物理读盘操作。当然,如果数据在应用程 序读取之前并未被存放在页缓存中,那么就需要先将数据从磁盘读到页缓存中去。对于写操作 来说,应用程序也会将数据先写到页缓存中去,数据是否被立即写到磁盘上去取决于应用程序 所采用的写操作机制:如果用户采用的是同步写机制( synchronous writes ), 那么数据会立 即被写回到磁盘上,应用程序会一直等到数据被写完为止;如果用户采用的是延迟写机制 ( deferred writes ),那么应用程序就完全不需要等到数据全部被写回到磁盘,数据只要被写 到页缓存中去就可以了。在延迟写机制的情况下,操作系统会定期地将放在页缓存中的数据刷 到磁盘上。与异步写机制( asynchronous writes )不同的是,延迟写机制在数据完全写到磁 版本号:V2.0 日期:2015-10-2 - 116 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 盘上的时候不会通知应用程序,而异步写机制在数据完全写到磁盘上的时候是会返回给应用程 序的。所以延迟写机制本身是存在数据丢失的风险的,而异步写机制则不会有这方面的担心。 5.3.2 缓存 I/O 的缺点 在缓存 I/O 机制中,DMA 方式可以将数据直接从磁盘读到页缓存中,或者将数据从页缓 存直接写回到磁盘上,而不能直接在应用程序地址空间和磁盘之间进行数据传输,这样的话, 数据在传输过程中需要在应用程序地址空间和页缓存之间进行多次数据拷贝操作,这些数据拷 贝操作所带来的 CPU 以及内存开销是非常大的。 对于某些特殊的应用程序来说,避开操作系统内核缓冲区而直接在应用程序地址空间和磁 盘之间传输数据会比使用操作系统内核缓冲区获取更好的性能,下边这一小节中提到的自缓存 应用程序就是其中的一种。 5.3.3 小贴士-关于文件的相关知识的一点说明 在 Linux 中,文件非常重要,所以在 linux 系统中提供了丰富的文件操作函数。 在系统编程中,我们只会介绍编程中用到的最终的 API 和必须掌握的知识,还有大量的和 文件相关的知识,例如高级 IO,制作文件系统,虚拟文件系统,文件共享,网络文件系统等等。 如果真是要详细的介绍整个 linux 文件,可能好几千页的书都介绍不完,而且对于大家学 习初期也没有太大的帮助,得不偿失。 手册中还会以其它形式介绍文件相关的知识,有的时候会介绍一步一步介绍如何操作,例 如制作文件系统,NFS 网络启动;有时候会介绍如何使用,例如内核教程中介绍的虚拟文件系 版本号:V2.0 日期:2015-10-2 - 117 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 统等等。大家如果感兴趣,在学习我们教程之外可以通过学习相关知识,去了解更加具体的含 义。 文件对于 linux 实在是太重要了,不过大家学习了本章的知识和实验,了解其他和文件系 统相关的知识,在后面 linux 编程中遇到的问题基本可以自行解决了。 5.3.4 函数头文件简介 在所有的 linux 系统中,如果需要对文件的进行操作,只要包含如下 4 个头文件即可。 #include #include #include #include 上面四个头文件中包含了打开,关闭,创建,读文件,写文件的函数,还有标志位,以及 在不同 32 位以及 64 位系统下数据长度的宏变量定义。 5.4 实验-打开文件函数 open 5.4.1 open 函数例程 使用 open 函数的时候会返回一个文件句柄,文件句柄是文件的唯一识别符 ID。对文件的 操作必须从读取句柄开始。 先来看一下函数 open 的两个原型。 int open(const char *path, int oflags); 版本号:V2.0 日期:2015-10-2 - 118 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 两个参数的 open 函数主要用于创建文件,在 5.5 小节会和创建文件的函数 creat 的同时 介绍具体用法,给出例子。 int open(const char *path, int oflags,mode_t mode); open 函数可以建立一个到文件或者设备的访问路径。在打开或创建文件时可以制定文件 的属性及用户的权限等各种参数。 第一个参数 path 表示:路径名或者文件名。路径名为绝对路径名,例如开发板中的 led 驱动的设备几点/dev/leds。 第二个参数 oflags 表示:打开文件所采取的动作。 下面三个选项是必须选择其中之一的。 O_RDONLY 文件只读 O_WRONLY 文件只写 O_RDWR 文件可读可写 下面是可以任意选择的。 O_APPEND 每次写操作都写入文件的末尾 O_CREAT 如果指定文件不存在,则创建这个文件 O_EXCL 如果要创建的文件已存在,则返回 -1,并且修改 errno 的值 O_TRUNC 如果文件存在,并且以只写/读写方式打开,则清空文件全部内容 O_NOCTTY 如果路径名指向终端设备,不要把这个设备用作控制终端。 O_NONBLOCK 如果路径名指向 FIFO/块文件/字符文件,则把文件的打开和后继 I/O 设置为非阻塞模式(nonblocking mode),后面会介绍什么是阻塞和非阻塞。 版本号:V2.0 日期:2015-10-2 - 119 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 O_NDELAY 和 O_NONBLOCK 功能类似,调用 O_NDELAY 和使用的 O_NONBLOCK 功能是一样的。 第三个参数 mode 表示:设置创建文件的权限。 S_IRUSR,S_IWUSER,S_IXUSR,S_IRGRP,S_IWGRP,S_IXGRP,S_IROTH,S_IWOTH,S_IXOTH. 其中 R:读,W:写,X:执行,USR:文件所属的用户,GRP:文件所属的组,OTH:其 他用户。第三个参数可以直接使用参数代替,参考 4.5 小节 linux 权限。 这个权限看似复杂,其实可以使用字母代替。前面用过的 chmod 0777 helloworld 命令, 其中的含义是一样的,只不过 chmod 是文件创立之后再修改权限。 5.4.2open 函数代码 编写简单的 open.c 文件测试 open 函数。 首先添加头文件,如下图所示。 然后 main 函数如下。 版本号:V2.0 日期:2015-10-2 - 120 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 上图中打开了三个文件分别属于不同的情况。 /dev/leds 已经在开发板中存在,属于驱动的设备节点,在 linux 驱动教程中会具体介绍 /bin/test1 和/bin/test2 都不存在 使用 open 函数调用上面三个文件,如果出错就会打印错误,然后打印句柄。 5.4.3 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/iofile”,使用命令“mkdir iofile”新建 iofile 文件夹,将源码 open.c 拷贝进去,进入新建的文件夹 iofileopen,如下图所示。 版本号:V2.0 日期:2015-10-2 - 121 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用命令“arm-none-linux-gnueabi-gcc -o open open.c -static”编译 open 文件, 如下图所示,使用命令“ls”可以看到生成了 open 可执行文件。 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统,具体方法参考实验 02 将编译成的可执行文件 open,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,运行程 序如下。 版本号:V2.0 日期:2015-10-2 - 122 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,可以看到打开/dev/leds 成功,这个是小灯的内核驱动,调用的时候,还调 用了内核驱动中的函数,这个函数会打印“LEDS_CTL DEBUG:Device Opened Success!”和 “LEDS_CTL DEBUG:Device Opened Success!” 然后打印句柄 ID,/dev/leds fd is 3 调用“/bin/test1”会报错“open /bin/test1 failed”,这种打开文件的方式是 linux 中 标准的用法,几乎所有对文件的 open 操作都会加上出错报警的语句。 创建“/bin/test2”会打印“/bin/test2 fd is 4”,表明创建“/bin/test2 ”成功了。 使用命令“ls /bin/test2”,查看一下对应目录/bin 下应该新建了“test2”,如下图所示。 版本号:V2.0 日期:2015-10-2 - 123 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 另外的“dev/leds”本身就存在,如下图所示,这是驱动的设备节点文件,在后面的实验 会介绍如何操作调用,在 linux 驱动实验中会介绍这个设备节点文件是如何生成的。 版本号:V2.0 日期:2015-10-2 - 124 - www.topeetboard.com 北京迅为电子有限公司 5.5 实验-创建函数 creat 和 open iTOP-4412 Linux 系统编程 V2.0 5.5.1 creat 函数介绍 关于 creat 函数,首先这个单词并不是表示创建的意思,创建的英文单词是“create”, 这是早期的一个小的拼写错误,却一直沿用下来。 在介绍 open 函数的时候,可以看到 open 函数有两种形式,一个是两个参数一个是三个 参数,早期的时候 open 只有三个参数的形式,三个参数的形式会导致 open 函数无法打开一 个未创建的文件,也就是无法建立文件,所以就有了这个 creat 函数。 现在 creat 函数可以完全用 open 替代,考虑到在阅读代码的时候可能会碰到,所以简单 介绍一下。 creat 函数原型如下。 int creat(const char * pathname, mode_t mode); creat 函数只有两个参数,参数的含义和 open 类似。 大家看到这个函数的时候知道它是创建文件的就成,在写代码的时候完全可以用 open 代 替。 5.5.2 creat 函数例程 编写简单的 creat.c 文件测试 creat 函数。 首先添加头文件,如下图所示。 版本号:V2.0 日期:2015-10-2 - 125 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数如下图所示。 版本号:V2.0 日期:2015-10-2 - 126 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图代码所示。 第 22 行、27 行、31,open 可以打开已有的文件,也可以打开不存在的文件,即创建文 件,创建文件的时候需要在参数中添加标志位 O_CREAT。在第 27 行代码中,没有添加标志位, 运行的时候肯定会报错,这么写是希望大家能够记住这个参数。 第 36 行是使用 creat 函数创建文件“test3”,注意一下 creat 函数和 open 函数在创建 文件的时候,参数的区别。 5.5.3 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/iofile”,将源码 creat.c 拷贝进去,如下图所示。 使用命令“arm-none-linux-gnueabi-gcc -o creat creat.c -static”编译 creat.c 文件, 如下图所示,使用命令“ls”可以看到生成了 creat 可执行文件。 版本号:V2.0 日期:2015-10-2 - 127 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统,具体方法参考实验 02 将编译成的可执行文件 creat,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,运行程 序如下。 如上图所示, 打开文件"/dev/leds"成功,这个文件已经存在 打开文件"/bin/test1"失败,因为没有添加参数 O_CREAT,这个文件不存在,新建的时候需 要参数 O_CREAT。 打开文件"/bin/test2"成功,不存在这个文件,创建成功。 版本号:V2.0 日期:2015-10-2 - 128 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 打开文件"/bin/test3"成功,不存在这个文件,使用 creat 新建成功。 如下图所示,使用命令“ls /bin/test* ”在“/bin”目录下可以看到新建的文件 test2 和 test3。 5.6 实验-关闭函数 close 任何一个文件在操作完成之后都需要关闭,这个时候需要调用 close 函数。 5.6.4close 函数介绍 调用 close 函数之后,会取消 open 函数建立的映射关系,句柄将不再有效,占用的空间 将被系统释放。 close 函数在头文件“#include ”中,close 函数的使用和参数都比较简单. int close(int fd); 参数 fd,使用 open 函数打开文件之后返回的句柄。 返回值,一般很少使用 close 的返回值。 版本号:V2.0 日期:2015-10-2 - 129 - www.topeetboard.com 北京迅为电子有限公司 5.6.2close 函数例程 iTOP-4412 Linux 系统编程 V2.0 无。 调用很简单,在下一个实验中会永到 close 函数。 5.7 实验-写函数 write 对文件进行写操作,write 函数使用的比较多。 5.7.1write 函数介绍 write 函数在头文件“#include ”中。 函数原型为 ssize_t write(int fd,const void *buf,size_t count) 参数 fd,使用 open 函数打开文件之后返回的句柄。 参数*buf,需要写入的数据。 参数 count,将参数*buf 中最多 count 个字节写入文件中。 返回值为 ssize 类型,出错会返回-1,其它数值表示实际写入的字节数。 5.7.2write 函数例程 编写简单的 write.c 文件测试 write 函数。 首先添加头文件,如下图所示。 版本号:V2.0 日期:2015-10-2 - 130 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数如下图所示。 如上图代码所示。 在 16 行定义了 buffer_write 字符数组 版本号:V2.0 日期:2015-10-2 - 131 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 在 18 行,进行写操作之前,必须得到文件的句柄,在这一行中使用 open 函数创建和打开 文件“/bin/testwrite"。 在 23 行中会调用 write 函数,将 buffer_write 字符数组中的内容写到新建的文件中。 在 31 行调用 close 函数,将"/bin/testwrite"文件关闭。 后面测试的时候可以在超级终端中,使用 vi 编辑器打开"/bin/testwrite"文件,可以看到这 个文件中有字符 Hello Write Function!. 5.7.3 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/iofile”,将源码 write.c 拷贝进去,如下图所示。 使用命令“arm-none-linux-gnueabi-gcc -o write write.c -static”编译 write.c 文件, 如下图所示,使用命令“ls”可以看到生成了 write 可执行文件。 版本号:V2.0 日期:2015-10-2 - 132 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统,具体方法参考实验 02 将编译成的可执行文件 write,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,运行程 序。如下图所示,打印出了 Write Function OK!。 在代码中定义的文件是"/bin/testwrite",使用 vi 编辑器打开文件,如下图所示,程序执行 运行成功。 版本号:V2.0 日期:2015-10-2 - 133 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 5.8 实验-文件的读 read 函数 对文件进行写操作,read 函数使用的比较多。 5.8.1read 函数介绍 read 函数在头文件“#include ”中。 函数原型为 ssize_t read(int fd,void *buf,size_t len) 参数 fd,使用 open 函数打开文件之后返回的句柄。 参数*buf,读出的数据保存的位置。 参数 len,每次最多读 len 个字节。 版本号:V2.0 日期:2015-10-2 - 134 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 返回值为 ssize 类型,出错会返回-1,其它数值表示实际写入的字节数,返回值大于 0 小 于 len 的数值都是正常的。 5.8.2read 函数例程 编写简单的 read.c 文件测试 read 函数。 首先添加头文件和定义读函数缓冲区为 1000,如下图所示。 然后 main 函数如下图所示。 版本号:V2.0 日期:2015-10-2 - 135 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图代码所示。 在 1-9 行,头文件。 在 20 行,使用 open 函数打开或者新建"/bin/testwrite"文件。 在 23 行,使用 write 函数将 buffer 中的内容写到"/bin/testwrite"文件中。 在 35 行,使用 read 函数,将"/bin/testwrite"文件中的内容读出来。 在 38 行,使用打印函数 printf 打印 read 函数读出的数据。 在 39 行,调用 close 函数关闭打开的文件,程序结束。 最终测试的时候,除了会出现"/bin/testwrite"文件,还会打印 read 函数读取的数据。 版本号:V2.0 日期:2015-10-2 - 136 - www.topeetboard.com 北京迅为电子有限公司 5.8.3 编译运行测试 iTOP-4412 Linux 系统编程 V2.0 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/iofile”,将源码 read.c 拷贝进去,如下图所示。 使用命令“arm-none-linux-gnueabi-gcc -o read read.c -static”编译 read.c 文件,如 下图所示,使用命令“ls”可以看到生成了 read 可执行文件。 版本号:V2.0 日期:2015-10-2 - 137 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统,具体方法参考实验 02 将编译成的可执行文件 read,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,运行程 序。如下图所示,可以看到打印出了“Files Content is Hello Write Function”,使代码中预 期的结果。 版本号:V2.0 日期:2015-10-2 - 138 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第六章 实战 字符设备控制 6.1 本章导读 在 linux 驱动中字符驱动是必须掌握的,本章主要介绍字符设备应用的程序,无论是学习 了后面的知识自己写的字符驱动,还是已有的字符驱动,都需要能够写一些简单的应用程序。 即使从事 linux 驱动的工作,linux 驱动写出来之后,也需要由驱动程序员编写简单的应用 进行测试的。 另外,关于驱动部分,迅为电子有专门的驱动实验教程提供给大家学习,大家有了这些基 础之后再去学习底层的知识就会很容易了。 在使用手册的第八章,大家可以看到这些 c 程序也是可以在 Android 下面运行的,只不过 没有图形界面。 6.1.1 工具 6.1.1.1 硬件工具 开发板 PC 机 U 盘或者 TF 卡 6.1.1.2 软件工具 Ubuntu12.04.2 以及虚拟机 Arm-2009q3 编译器 版本号:V2.0 日期:2015-10-2 - 139 - www.topeetboard.com 北京迅为电子有限公司 Notepad++编辑器 超级终端 Vim 编辑器 最小 linux 系统 iTOP-4412 Linux 系统编程 V2.0 6.1.2 预备课程 基本开发工具的使用 常用 linux 命令 最小 linux 系统 文件 IO 6.1.3 视频资源 本章配套视频为: “视频 06_01 字符设备控制之 main 函数传参数” “视频 06_02 字符设备控制之 led 灯” “视频 06_03 字符设备控制之 buzzer 蜂鸣器” “视频 06_04 字符设备控制之 ADC 模数转换” 6.2 学习目标 本章需要学习以下内容: 熟练掌握 main 函数的用法 版本号:V2.0 日期:2015-10-2 - 140 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 掌握字符设备 led 灯、buzzer 蜂鸣器、ADC 模数转换 6.3 入口 main 函数的参数 在和用户交流的过程中,虽然所有人都学习过 C 语言,但是对 C 语言中的 main 函数的用 法并不是很清楚。 由于后面的实验需要用到这部分知识,这里就占用一个小节,先简单介绍一下 main 函数。 6.3.2 main 函数简介 main 函数作为应用程序的入口,在头文件“#include ”中。 main 函数需要传参数的时候完整的定义为 int main(int argc,char **argv) 参数 argc,表示参数的个数 参数**argv,存储输入字符的数组 argv[0]表示程序名称 argv[1]——argv[n]输入的参数 不传参数的时候定义为 int main(void) 函数 main 的返回值为类型为 int,用于判断程序执行成功还是失败 版本号:V2.0 日期:2015-10-2 - 141 - www.topeetboard.com 北京迅为电子有限公司 6.3.3main 函数例程 编写简单的 argvc.c 文件测试 main 函数。 iTOP-4412 Linux 系统编程 V2.0 如上图所示,将输入的参数第一个和第二个转换成 int 类型,赋值给 i 和 j,最后输出打印。 其中 argv[0]为程序名称,这里就是后面要编译的目标文件“argvc”。 6.3.4 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录“/home/linuxsystemcode/”, 使用命令“mkdir charcontrol”新建 charcontrol 文件夹,将源码 argvc.c 拷贝进去,进入新 建的文件夹 charcontrol,如下图所示。 版本号:V2.0 日期:2015-10-2 - 142 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用命令“arm-none-linux-gnueabi-gcc -o argvc argvc.c -static”编译 argvc 文件, 如下图所示,使用命令“ls”可以看到生成了 argvc 可执行文件。 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统,具体方法参考实验 02 将编译成的可执行文件 argvc,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,运行程 序如下。 版本号:V2.0 日期:2015-10-2 - 143 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,程序成功运行,打印: the Program name is ./mnt/udisk/argvc。因为运行的程序就是“./mnt/udisk/argvc”, 这是第一个参数 The command line has 2 argument: 10,11。输入的参数是 10 和 11,对应 argv[2]和 argv[2]。 6.4 字符类 led 灯 在前面介绍 open 函数的时候,已经提到过如何打开字符类设备,获得句柄的方法和一般 文件都是一样。 Led 灯的设备节点在/dev 目录下,如下图所示,在超级终端可以使用 ls 命令查找。 版本号:V2.0 日期:2015-10-2 - 144 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 由于涉及到硬件知识,这里简单介绍一下硬件原理,如下图所示,led 小灯的硬件原理很 简单。 如上图所示。 给 KP_COL0 和 VDD50_EN 网络高电平,三极管 L9014 就会导通,电源 VSYS 就会将电 压加到电阻 R 和 led 小灯上,小灯就会亮。 版本号:V2.0 日期:2015-10-2 - 145 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 给 KP_COL0 和 VDD50_EN 网络低电平,三极管 L9014 就会截止,形成断路,小灯灭。 在前面介绍过,如果要给文件进行写操作,那么使用的是 write 函数。对于 led 小灯的操 作,使用写函数,理论上也是可以的。但是对于 IO 口(这里的 IO 口指的是硬件上的 IO 口, 不是指 IO 文件)的操作,Linux 专门设计了一个高效的函数 ioctl。 这个函数在头文件#include中。 int ioctl( int fd, int request, int cmd); 参数 fd,函数 open 返回的句柄。 参数 request 和参数 cmd,由内核驱动决定具体操作,例如 request 可以代表那个 IO 口, cmd 代表对 IO 进行什么样的操作,也可以反过来。具体的含义由驱动工程师在驱动中 switch 决定。 返回值:返回 0 成功;返回-1,出错。 6.4.1 小灯测试例程 编写简单的 leds.c 文件测试小灯。 首先添加头文件,如下图所示。 通过 main 参数传过来的参数是 char 字符格式的,如果要传递给 ioctl 函数,需要用到数 值转化函数 atoi,添加了头文件#include 。 接着由于小灯的数量和命令都是 2,所以对小灯数量和操作数进行宏定义#define LED_NUM 2 #define LED_C 2。 版本号:V2.0 日期:2015-10-2 - 146 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数如下图所示。 如上图所示。 版本号:V2.0 日期:2015-10-2 - 147 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第 33 行,调用了 ioctl 函数,将 main 函数的第一个和第二个参数传入驱动。 第 19 行,解释那个参数具体代表什么含义,"argv1 is cmd;argv2 is io”,参数 1 对应命 令,参数 2 对应具体那个 led 灯。 第 36 行,将打开的设备节点"/dev/leds"关闭。 6.4.2 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/charcontrol”,将源码 leds.c 拷贝进去,如下图所示。 使用命令“arm-none-linux-gnueabi-gcc -o leds leds.c -static”编译 leds 文件,如下 图所示,使用命令“ls”可以看到生成了 leds 可执行文件。 版本号:V2.0 日期:2015-10-2 - 148 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统,具体方法参考实验 02 将编译成的可执行文件 open,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,运行程 序如下。 如下图所示,如果不加参数会有提示,然后报错。 版本号:V2.0 日期:2015-10-2 - 149 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,使用命令“./mnt/udisk/leds 0 0”运行,可以看到靠近蜂鸣器的小灯灭了。 所有参数对小灯的控制如下: 版本号:V2.0 日期:2015-10-2 - 150 - www.topeetboard.com 北京迅为电子有限公司 0 0 靠近蜂鸣器的小灯灭; 0 1 靠近按键的小灯灭; 1 0 靠近蜂鸣器的小灯亮; 1 1 靠近按键的小灯亮。 用户可以自行测试一下。 iTOP-4412 Linux 系统编程 V2.0 6.5 字符类 Buzzer 蜂鸣器 和 led 灯类似,蜂鸣器的设备节点也是在/dev 目录下,如下图所示。 蜂鸣器的硬件和 led 灯类似,如下图所示。 版本号:V2.0 日期:2015-10-2 - 151 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示。 原理图很容易理解,如果网络 MOTOR_PWM 为高电平,则 L9014 导通,蜂鸣器响,如 果网络 MOTOR_PWM 为低电平,则 L9014 截止,蜂鸣器则不响。 操作方式和 led 小灯类似。 6.5.1 蜂鸣器测试例程 编写简单的 buzzertest.c 文件测试蜂鸣器。 首先添加头文件,如下图所示,下面新加了几个库文件,一般常用的就是下面几个,写代 码的时候,为了方便,可以直接都添加上。 版本号:V2.0 日期:2015-10-2 - 152 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数如下图所示。 如上图代码所示。 由于只有一个 IO,底层没有做第三个参数的判断,所以无效 版本号:V2.0 日期:2015-10-2 - 153 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第 16-19 行,对参数 argv[1]有个简单的判断,命令只能是 0 或者 1。 第 21-24 行,open 函数打开蜂鸣器设备节点 第 26 行,使用 ioctl 函数操作蜂鸣器。 第 27 行,使用 close 函数关闭设备节点。 6.5.2 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/charcontrol”,将源码 buzzertest.c 拷贝进去,如下图所示。 使用命令“arm-none-linux-gnueabi-gcc -o buzzertest buzzertest.c -static”编译 buzzertest 文件,如下图所示,使用命令“ls”可以看到生成了 buzzertest 可执行文件。 版本号:V2.0 日期:2015-10-2 - 154 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统,具体方法参考实验 02 将编译成的可执行文件 buzzertest,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘, 运行程序如下。 使用参数 1 和 0,蜂鸣器会响。第二个参数实际上并不起作用。 版本号:V2.0 日期:2015-10-2 - 155 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,使用参数 0 和 0,蜂鸣器会停止响。 版本号:V2.0 日期:2015-10-2 - 156 - www.topeetboard.com 北京迅为电子有限公司 6.6 字符类 ADC 模数转换 iTOP-4412 Linux 系统编程 V2.0 和 led 灯类似,数模转换的设备节点也是在/dev 目录下,如下图所示。 模数转换的硬件部分如下图所示。 版本号:V2.0 日期:2015-10-2 - 157 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示。 XadcAIN0 网络可以读取到当前输入电压,滑动变阻器 R 移动的时候,1 和 2 之间的电阻 R12 改变,滑动变阻器最大电阻为 R13,然后电压 Vadc=R12*VDD1V8_EXT/R13 上面公式中 Vadc 可以通过 4412 读取出来,VDD1V8 和 R13 已知,那么就很容易求出 R12 的电阻。 如下图所示,在 4412datasheet 中 ADC 章节中有真实的电阻和电压曲线图。 这里我们将数值做一个简单的换算, 1.8V 对应的是 10K 欧姆,对应的寄存器数值为 0xfff; 0V 对应的是 0 欧姆,对应的寄存器数值为 0x0。 这样我们做一个简单公式,将读取的数值 r 转化为电阻值 R。 R = r*10000/0xfff,即 R = r*10000/4095。 版本号:V2.0 日期:2015-10-2 - 158 - www.topeetboard.com 北京迅为电子有限公司 这个小公式在后面的代码中将会使用到。 6.6.1 模数转换例程 编写简单的 ADC.c 文件测试 adc 的驱动。 首先添加头文件,如下图所示。 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数如下图所示。 版本号:V2.0 日期:2015-10-2 - 159 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图代码所示。 第 14 行,设备节点为 char *adc = "/dev/adc"。 第 21 行,打开设备节点文件。 第 26 行,使用 read 函数,将读取数字赋予 buffer。 第 30 和 31 行,做个简单地换算,将读取的数值转化为电阻值。 6.6.2 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/charcontrol/”将源码 ADC.c 拷贝进去,如下图所示。 版本号:V2.0 日期:2015-10-2 - 160 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用命令“arm-none-linux-gnueabi-gcc -o ADC ADC.c -static”编译 ADC 文件,如 下图所示,使用命令“ls”可以看到生成了 ADC 可执行文件。 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统,具体方法参考实验 02 将编译成的可执行文件 open,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,运行程 序。 版本号:V2.0 日期:2015-10-2 - 161 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,使用命令“./mnt/udisk/ADC”即可检测当前电阻值,中间的大段打印参数 是多次打印寄存器的数值,在驱动实验中再去介绍。 调整滑动电阻器之后,再次使用测试程序,如下图所示,输出数值会有变化。 版本号:V2.0 日期:2015-10-2 - 162 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 滑动变阻器向顺时针旋转,阻值会减小,最小为 0; 滑动变阻器向逆时针旋转,阻值会增大,最大为 10K。 版本号:V2.0 日期:2015-10-2 - 163 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第七章 实战 Linux 串口编程 7.1 本章导读 学习过单片机的用户,对串口不会太陌生,在单片机串口编程中,需要用户直接对寄存器 以及中断进行控制。 而在 linux 串口编程中,无论是从 linux 官方直接下载的原生态内核,还是任何厂家提供的 linux 内核,都会将串口驱动写好,所以对于所有的驱动工程师来说,是完全不需要自己动手写 串口驱动的。 本章介绍的 linux 串口编程,实际上指的是 Linux 串口应用编程,直接使用提供原厂提供 的接口,进行初始化配置以及发送和接收。对于从事 linux 编程的程序员来说,这一部分内容 必须熟练掌握。 7.1.1 工具 7.1.1.1 硬件工具 开发板 PC 机 U 盘或者 TF 卡 7.1.1.2 软件工具 Ubuntu12.04.2 以及虚拟机 Arm-2009q3 编译器 版本号:V2.0 日期:2015-10-2 - 164 - www.topeetboard.com 北京迅为电子有限公司 Notepad++编辑器 超级终端以及串口助手 Vim 编辑器 iTOP-4412 Linux 系统编程 V2.0 7.1.2 预备课程 基本开发工具的使用 常用 linux 命令 最小 linux 系统 文件 IO 7.1.3 视频资源 本章配套视频为: “视频 07_01 串口编程之基本概念以及流程分析” “视频 07_02 串口编程之开机启动运行” “视频 07_03 串口编程之打开串口” “视频 07_04 串口编程之串口初始化” “视频 07_05 串口编程之串口发送” “视频 07_06 串口编程之串口接收” 7.2 学习目标 本章需要学习以下内容: 版本号:V2.0 日期:2015-10-2 - 165 - www.topeetboard.com 北京迅为电子有限公司 串口基本概念 开机启动运行程序 串口的初始化、打开、发送、写等 iTOP-4412 Linux 系统编程 V2.0 7.3 几个关于串口的基本概念 本节先介绍几个和串口有关的基本概念。 7.3.1 什么是串口通信 串口通信是指一次只传送一个数据位。虽然在通信的时候串口有 8 位或者 9 位等,但是在 物理层面传输的时候,它仍然是以单个 bit 的方式传输的。 7.3.2 什么是串口 虽然以太网以及 USB 等等也是以串行的方式发送数据,但是串口一般特指 RS232 标准的 接口。 7.3.3 什么是 RS232 RS-232 是 EIA(Electronic Industries Association)定义的串行通信的电器接口。RS-232 事实上有三种(A,B 和 C),它们分别采用不同的电压来表示 on 和 off。最被广泛使用的是 RS-232C,它将 mark(on)比特的电压定义为-3V 到-12V 之间,而将 space(off)的电压定义到 +3V 到+12V 之间。虽然 RS-232C 标准说信号最远被传输 8m,但事实上你可以使用它传输 更长的距离,直到信号波特率已经小到不行了为止。 RS-232 的连结线中除去用来传入传出数 据的电线,还有一些用来提供时序,状态和握手的电线。 版本号:V2.0 日期:2015-10-2 - 166 - www.topeetboard.com 北京迅为电子有限公司 7.3.4 RS232 的针脚定义 iTOP-4412 Linux 系统编程 V2.0 RS232 有两种标准定义,25 针和 8 针的。不过即使是 8 针,在大多数场合工程师也觉得 太多了,绝大多数情况下都是只使用 TX,RX 针脚发送和接收信号,再加上一个 GND 地脚。 其它定义大家可以通过网络了解一下。 7.3.5 什么是流控 两个串行接口之间的传输数据流通常需要协调一致才行。这可能是由于用以通信的某个串 行接口或者某些存储介质的中间串行通信链路的限制造成的。对于异步数据这里有两个方法做 到这一点。 第一种方法通常被叫做“软件”流控制。这种方法采用特殊字符来开始(XON,DC1,八进 制数 021)或者结束(XOFF,DC3 或者八进制数 023)数据流。而这些字符都在 ASCII 中定义好 了。虽然这些编码对于传输文本信息非常有用,但是它们却不能被用于在特殊程序中的其他类 型的信息。 第二种方法叫做“硬件”流控制。这种方法使用 RS-232 标准的 CTS 和 RTS 信号来取代之 前提到的特殊字符。当准备就绪时,接受一方会将 CTS 信号设置成为 space 电压,而尚未准备 就绪时它会被设置成为 mark 电压。相应得,发送方会在准备就绪的情况下将 RTS 设置成 space 电压。正因为硬件流控制使用了于数据分隔的信号,所以与需要传输特殊字符的软件流控制相 比它的速度很快。但是,并不是所有的硬件和操作系统都支持 CTS/RTS 流控制。 7.4 串口编程的流程分析 在 linux 下串口编程流程比较容易理解,如下图所示。 版本号:V2.0 日期:2015-10-2 - 167 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 打开串口,一般使用 open 函数,打开之后会返回句柄,这个句柄就可以提供给发送和接 收函数使用。串口本质上也是字符设备,但是串口是属于一种比较特殊的字符设备。 初始化串口,串口需要配置波特率,数据位,校验位等等一系列的参数,初始化的过程掌 握了,发送和接收都比较容易实现。虽然初始化比较麻烦,但是无论是在 window 下还是在 linux 下,串口的初始化都是很容易找到例程的。个人建议只要能够读懂代码,根据实际需求进行验 证和配置即可。 发送和接收数据,前面提到过串口是属于字符设备的,可以使用 read 函数和 write 函数实 现。 关闭,使用函数 close 即可关闭串口。 版本号:V2.0 日期:2015-10-2 - 168 - www.topeetboard.com 北京迅为电子有限公司 7.5 实验-开机启动运行 iTOP-4412 Linux 系统编程 V2.0 做串口实验的时候,通过另外的串口读和写,考虑到部分用户可能没有多余的串口或者串 口线,这里简单的做一个开机启动的实验。 一个程序能够开机自动启动运行,那么就能不用超级终端的调试串口也能进行程序的测试 了。 7.5.1 实验例程 如下图所示,使用前面最简单的 helloworld 程序。,前面也编译运行通过了,代码如下。 如上所示,代码非常简单,只是打印“Hello World”。 7.5.2 操作方法 首先确保上面的 helloworld 可执行程序已经在 U 盘中了。开机启动开发板,插入 U 盘, 加载 U 盘。 版本号:V2.0 日期:2015-10-2 - 169 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后如下图所示,使用拷贝命令“cp -r /mnt/udisk/helloworld /bin/”将其拷贝到/bin 目录下,然后使用 ls 命令确认一下。 使用命令“chmod 777 /bin/helloworld”修改权限。 版本号:V2.0 日期:2015-10-2 - 170 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着使用命令“vi /etc/init.d/rcS”打开文件系统的启动文件,如下图所示。 接着进入文件的最后一行,添加“/bin/helloworld &”。 版本号:V2.0 日期:2015-10-2 - 171 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 保存退出。 版本号:V2.0 日期:2015-10-2 - 172 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 为了方便查找打印信息,可以按照前面入门介绍的方法设置一下开机启动 log,我这里的 路径是桌面上的 startlog.log 文件。如下图所示,迅为提供的超级终端设置保存 log 的方法为, “控制”→“日志设置”,然后弹出下图所示的日志配置窗口。 然后重启开发板。 重启开发板之后,其实超级终端中也是会打印信息的,但是启动信息太多,不容易查找。 版本号:V2.0 日期:2015-10-2 - 173 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如果上图中找不到(步骤对了肯定是有的),打开前面设置的 startlog.log 文件,然后在 里面查找关键词“Hello world!”。能够查找到打印的字符,说明开机启动程序正常。 版本号:V2.0 日期:2015-10-2 - 174 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 7.6 实验-打开串口 7.6.1 如何确认设备节点 先来学习一下如何打开串口,在几乎所有的 Linux 系统中,在 dev 目录下都会有 tty*的设 备节点,如下图所示,启动开发板,在超级终端中,进入 dev 目录,输入查找命令“ls tty*”。 版本号:V2.0 日期:2015-10-2 - 175 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,有多种形式的设备节点,在 4412 开发板中,设备节点使用的是 ttySAC*系 列,即 ttySAC0,ttySAC1,ttySAC2,ttySAC3。 4412 开发板可以支持 4 个串口,如下图所示,方便用户使用的除了控制台(超级终端使 用的串口)以外,精英版靠近麦克和耳机的串口,也是可以直接拿来使用的。 版本号:V2.0 日期:2015-10-2 - 176 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 在核心板原理图上,搜索“GPS_TXD”,如下图所示,可以看到这个串口对应的是 XuRXD3, 所以可以确认精英版靠近耳机和麦克的串口对应的设备节点是“ttySAC3”。后面的实验都已 这个操作这个串口为例子来讲解。 7.6.2 串口打开和关闭例程 编写简单的 uartopen.c 文件打开串口设备节点。 首先添加头文件,如下图所示,和 io 文件使用的头文件一样。 版本号:V2.0 日期:2015-10-2 - 177 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数如下图所示。 如上图代码所示。 第 13 行,打开“/dev/ttySAC3”设备节点,方法和 led 等字符的方法类似。 第 14 行,打开不成功则发送“open %s is failed!”。 第 17 行,打开成功则发送“open %s is success!”。 第 20 行,使用 close 函数关闭文件。 版本号:V2.0 日期:2015-10-2 - 178 - www.topeetboard.com 北京迅为电子有限公司 7.6.3 编译运行测试 iTOP-4412 Linux 系统编程 V2.0 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录“/home/linuxsystemcode/”, 使用命令“mkdir uartapp”新建 uartapp 文件夹,将源码 uartopen.c 拷贝进去,进入新建 的文件夹 uartapp,如下图所示。 使用命令“arm-none-linux-gnueabi-gcc -o uartopen uartopen.c -static”编译生成 uartopen 文件,如下图所示,使用命令“ls”可以看到生成了 uartopen 可执行文件。 版本号:V2.0 日期:2015-10-2 - 179 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统,具体方法参考实验 02 将编译成的可执行文件 uartopen,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,运 行程序。 如下图所示,使用命令“./mnt/udisk/uartopen ”运行程序 uartopen,打印出“open /dev/ttySAC3 is success”说明串口打开成功,并没有被其它程序占用。 版本号:V2.0 日期:2015-10-2 - 180 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 7.7 串口初始化参数介绍 串口编程的最大的难度就是初始化,用的参数非常多。 大家可能查看过网上一些关于串口的资料以及历史,由于串口的设计之初太过于复杂了, 但是到了实际应用中,两线的串口(tx/rx)应用却是最广泛的。在实际应用中几乎很少看到有 多线的,即使复杂一点也最多是添加一根流控。 这样会导致一个结果,网上的串口相关教程晦涩难懂,学习的时候不容易抓住重点。 版本号:V2.0 日期:2015-10-2 - 181 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 本节内容将直接介绍应用中最多的一套初始化代码。这套代码尽量贴近实际,大家以后应 用的时候,要是传输的协议一样,可以直接拿来使用,不一样稍微修改一下参数的配置就能够 通信。 7.7.1 串口的初始化结构介绍 如果大家学习过单片机,多半使用过类似如下图所示的串口助手。 如上图所示,在左下角其实就是串口最基本的参数设置,这些配置是最常用的,包括串口 号、波特率、数据位、停止位,校验位、流控。 如下图所示,使用 source insight 打开内核源码,串口的初始化最终要将参数传递到内核 中的,搜索“termios.h”,如下所示。 版本号:V2.0 日期:2015-10-2 - 182 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,打开“arch\arm\include\asm”目录下的“termios.h”头文件。 如下图所示,可以看到这个 termio 结构体的定义。 分析一下上图中几个常用的参数。 成员 tcflag_t c_iflag:输入模式标志 成员 tcflag_t c_oflag:输出模式标志 成员 tcflag_t c_cflag:控制模式标志 版本号:V2.0 日期:2015-10-2 - 183 - www.topeetboard.com 北京迅为电子有限公司 成员 tcflag_t c_lflag:本地模式标志 成员 cc_t c_line:line discipline 成员 cc_t c_cc[NCC]:control characters iTOP-4412 Linux 系统编程 V2.0 7.7.2 串口的初始化常用函数介绍 在介绍了上面的结构体之后,接着看一下初始化的几个函数以及用法。 在给串口初始化之前必须读取串口的句柄,也就是先要使用 open 函数,在前面的实验中 已经测试过,可以正常返回 fd 了。 7.7.2.1 函数 tcgetattr 函数 tcgetattr 用于读取当前串口的参数值,在实际应用中,一般用于先确认该串口是否能 够配置,做检测用。 需要用到头文件 “#include ”和“#include ”。 函数原型为 int tcgetattr(int fd, struct termios *termios_p)。 参数 1:fd 是 open 返回的文件句柄。 参数 2:*termios_p 是前面介绍的结构体。 使用这个函数前可以先定义一个 termios 结构体,用于存储旧的参数。 7.7.2.2 波特率相关的函数 函数 cfsetispeed 和 cfsetospeed 用于修改串口的波特率,函数 cfgetispeed 和 cfgetospeed 可以用于获取当前波特率。在实际应用中,这个经常需要用到,例如修改默认的 波特率。 版本号:V2.0 日期:2015-10-2 - 184 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 波特率相关的函数需要用到头文件 “#include ”和“#include ”。 先介绍设置波特率的函数。 函数原型 int cfsetispeed(struct termios *termios_p, speed_t speed); 参数 1:*termios_p 是前面介绍的结构体。 参数 2:speed 波特率,常用的 B2400,B4800,B9600,B115200,B460800 等等。 执行成功返回 0,失败返回-1 函数原型 int cfsetospeed(struct termios *termios_p, speed_t speed); 参数 1:*termios_p 是前面介绍的结构体。 参数 2:speed 波特率,常用的 B2400,B4800,B9600,B115200,B460800 等等。 执行成功返回 0,失败返回-1 下面介绍获取波特率的函数。 函数原型为 speed_t cfgetispeed(const struct termios *termios_p)。用于读取当前串 口输入的波特率。 参数 1:*termios_p 是前面介绍的结构体。 返回值为 speed_t。 函数 speed_t cfgetospeed(const struct termios *termios_p)。这个函数用于读取当前 输出的波特率。 版本号:V2.0 日期:2015-10-2 - 185 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 参数 1:*termios_p 是前面介绍的结构体。 返回值为 speed_t 类型,当前波特率。 7.7.2.3 函数 tcflush 函数 tcflush 用于清空串口中没有完成的输入或者输出数据。在接收或者发送数据的时候, 串口寄存器会缓存数据,这个函数用于清除这些数据。 原型为 int tcflush(int fd, int queue_selector); 参数 1:fd 是 open 返回的文件句柄。 参数 2:控制 tcflush 的操作。 有三个常用数值,TCIFLUSH 清除正收到的数据,且不会读取出来;TCOFLUSH 清除正 写入的数据,且不会发送至终端;TCIOFLUSH 清除所有正在发生的 I/O 数据。 执行成功返回 0,失败返回-1 7.7.2.4 函数 tcsetattr 前面介绍了读取串口配置参数的函数,tcsetattr 函数是设置参数的函数。 原型为 int tcsetattr(int fd, int optional_actions,const struct termios *termios_p); 参数 1:fd 是 open 返回的文件句柄。 参数 2:optional_actions 是参数生效的时间。 有三个常用的值:TCSANOW:不等数据传输完毕就立即改变属性;TCSADRAIN:等待 所有数据传输结束才改变属性;TCSAFLUSH:清空输入输出缓冲区才改变属性。 参数 3:*termios_p 在旧的参数基础上修改的后的参数。 执行成功返回 0,失败返回-1 一般在初始化最后会使用这个函数。 版本号:V2.0 日期:2015-10-2 - 186 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 7.7.2.5 其它函数的使用 在串口中还有其它的参数需要了解,其它的函数需要学习。 大家在 linux 下使用串口的时候,如果有其它的参数需要配置,可以在网上搜索相关的资 料,那样针对性更强,有的放矢,效率更高。 前面的参数和设置已经可以对付大部分实际应用场景了。 7.7.4 初始化流程分析 如下图所示,是串口初始化的流程图。 如上图所示,这是一个简单的初始化过程,后面初始化代码也会按照这个过程组织。 版本号:V2.0 日期:2015-10-2 - 187 - www.topeetboard.com 北京迅为电子有限公司 7.7.4 例程:串口初始化代码 iTOP-4412 Linux 系统编程 V2.0 下面写一个函数,包括串口的基本的配置,函数里面的参数还可以添加,也可以单独拿出 来配置。 如下图所示,首先定义一个初始化函数 int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)。 然后定义结构体 newtio 和 oldtio。 接着将 newtio 清零和设置标志位 c_cflag。如下图所示。 版本号:V2.0 日期:2015-10-2 - 188 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 上面涉及到的点很多,需要大家具体的了解。 版本号:V2.0 日期:2015-10-2 - 189 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着设置波特率,如下图所示,使用 switch 配置波特率,只有部分常用的波特率,如果有 需要还可以添加。 接着设置停止位,如下图所示。 版本号:V2.0 日期:2015-10-2 - 190 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 最后配置参数,如下图所示。 7.8 实验-串口发送 本节实验演示串口的发送。 这里提醒一下,在学习中用到的超级终端,里面的打印信息,本质上是用于 linux 的调试 的,类似在开发环境的 Ubuntu 下的终端。那个串口已经被内核占用了,不能直接用于本章的 实验的调用,只能作为一个辅助调试的手段。 如果最终的产品串口不够,可以使用 usb 转串口,或者将调试的控制台屏蔽掉即可。分别 参考使用手册第九章 9.4.13 和 9.4.13。内核经过处理之后才能作为串口使用。 版本号:V2.0 日期:2015-10-2 - 191 - www.topeetboard.com 北京迅为电子有限公司 7.8.1 串口发送例程 iTOP-4412 Linux 系统编程 V2.0 串口发送类似文件操作,非常简单。使用 write 函数即可,三个参数分别是句柄,传输的 buffer 以及,传输的长度。这个函数前面介绍文件 IO 的时候已经介绍过了,这里就不再重复。 源码文件名为“uartwrite.c”。 先来看一下代码的头文件,然后引入前面的初始化函数。 将串口参数配置整合为一个函数,主函数就比较简单了,如下图所示。 版本号:V2.0 日期:2015-10-2 - 192 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,运行代码之后,可观察到如下现象。 控制台打印“itop4412 uart3 writetest start”。 控制台打印“open %s is success\n”。 接着打印 i=10 次的"hello world!\n"。 打印的同时控制台会打印“wr_static is %d”。 另外,如果其它打开设备之类的操作出错,会打印对应的错误。 版本号:V2.0 日期:2015-10-2 - 193 - www.topeetboard.com 北京迅为电子有限公司 7.8.2 编译运行测试 iTOP-4412 Linux 系统编程 V2.0 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/uartapp”,将源码 uartwrite.c 拷贝进去,如下图所示。 使用命令“arm-none-linux-gnueabi-gcc -o uartwrite uartwrite.c -static” 编译 uartwrite 文件,如下图所示,使用命令“ls”可以看到生成了 uartwrite 可执行文件。 版本号:V2.0 日期:2015-10-2 - 194 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统,具体方法参考实验 02。 将编译成的可执行文件 uartwrite,拷贝到 U 盘。开发板精英版接两个串口,一个是控制 台的超级终端,另一个是接声卡旁边的串口。 超级终端,如下图所示。 程序控制的串口,使用另外一个串口助手,如下图所示。 版本号:V2.0 日期:2015-10-2 - 195 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 注意上面两个串口号需要和根据实际情况设置串口号,在使用手册的第三章有关于串口软 件基础的介绍,如果不清楚可以再学习一下。 启动开发板,插入 U 盘,加载 U 盘,运行程序如下。 版本号:V2.0 日期:2015-10-2 - 196 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,另外一个终端会打印出设置好的字符,如下图所示,说明串口调用输出成功。 如果用户的串口线不够,没有关系,可以看一下下一节的测试方法,利用开机启动来测试。 版本号:V2.0 日期:2015-10-2 - 197 - www.topeetboard.com 北京迅为电子有限公司 7.8.3 只有一个串口的测试方法 iTOP-4412 Linux 系统编程 V2.0 如果用户只有一个串口,那么可以将这个程序设置为开机启动。 启动开发板,在超级终端控制台中,将 uartwrite 拷贝到/bin 目录,然后修改权限,如下 图所示。 接着修改开机启动脚本文件,在超级终端中使用命令“ vi /etc/init.d/rcS”,如下图所示。 版本号:V2.0 日期:2015-10-2 - 198 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着修改启动脚本。 保存退出,然后关掉开发板。 版本号:V2.0 日期:2015-10-2 - 199 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 因为只有一个串口,那么将唯一的串口接到耳机旁边的串口座子,控制台串口不需要接到 PC 上。 串口接好之后,使用如下图所示的串口助手。 接着开启开发板,过一会就会打印 10 行 hello world!,如下图所示。 版本号:V2.0 日期:2015-10-2 - 200 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里提醒大家一下,串口是不支持热拔插的。如果强行热拔插,容易损坏串口芯片。 7.9 实验-串口接收 串口接收使用 read 函数,在文件 io 中已经介绍过了。 7.9.2 串口接收例程 接收例程命名为“uartread.c”。 来看一下头文件,如下图所示。 版本号:V2.0 日期:2015-10-2 - 201 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着看一下 main 主函数。 如上图所示。 第 17 行:定义一个 buffer 接收数据。 第 18 行:将缓冲器清零。 版本号:V2.0 日期:2015-10-2 - 202 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第 19 行:打开串口。 第 22 行:初始化串口。 第 23 行:串口输出“please input”字符串,提醒可以输入了。 第 25 行-29:循环接收串口发送过来的数据,并发送出去。 7.9.2 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/uartapp”,将源码 uartread.c 拷贝进去,如下图所示。 使用命令“arm-none-linux-gnueabi-gcc -o uartread uartread.c -static” 编译 uartread 文件,如下图所示,使用命令“ls”可以看到生成了 uartread 可执行文件。 版本号:V2.0 日期:2015-10-2 - 203 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统,具体方法参考实验 02 测试方法和串口读函数的例程类似,如果只有一个串口可以参考前面介绍开机启动的方法。 将编译成的可执行文件 uartread,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,运 行程序如下,后台运行注意加“&”。 版本号:V2.0 日期:2015-10-2 - 204 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,运行之后另外一个串口会发送“please input”字符。 小提示:使用清除之后,可以计算到底接收发送了 如上图所示,字符串输入框中可以写入任何字符输如。 上面写得是“helloread”,然后多打击单击发送几次,可以看到发送的字符被发送回来了。 版本号:V2.0 日期:2015-10-2 - 205 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,输入输出会一直相差保持 14,出去启动接收的 please input,表明接收成功。 版本号:V2.0 日期:2015-10-2 - 206 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第八章 TFTP 服务器搭建和测试 8.1 本章导读 在前面的视频中介绍了控制 led 的程序的实现,需要把编译好的 led 可执行文件拷贝到文 件系统里面,用 make_ext4fs 命令重新制作 system.img 文件系统,然后再烧写到 iTOP-4412 开发板,然后再运行 led 可执行文件。这种方式的缺点是每次修改了应用程序,都需要重新制 作文件系统,在重新烧写文件系统,效率很低。 这一章先讲解如何通过 TFTP 来实现在线传输文件,先在虚拟机 Ubuntu 上搭建一个服务 器,并在虚拟机 Ubuntu 上做客户端进行测试。 8.1.1 工具 8.1.1.1 硬件工具 PC 机 8.1.1.2 软件工具 Ubuntu12.04.2 以及虚拟机 Arm-2009q3 编译器 Vim 编辑器 8.1.2 预备课程 基本开发工具的使用 常用 linux 命令 版本号:V2.0 日期:2015-10-2 - 207 - www.topeetboard.com 8.1.3 视频资源 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 本章配套视频为: “视频 08TFTP 服务器搭建和测试” 8.2 学习目标 8.2.1 学习目标 本章需要学习以下内容: 掌握 TFTP 服务器搭建的步骤 掌握 TFTP 服务器测试的方法 8.2.2Linux 网络部分的学习方法 这里并不会费劲的去介绍 TFTP 协议,那个意义不大,主要是教大家如何操作,在这个过 程中进步。 网络协议非常复杂,完整的网络协议一个人将资料看一遍,估计这辈子就过去了。在这个 庞大的网络工程中,不同的工程师分别做不同的工作,作为嵌入式 linux 工程师,要做的就是 拿别人做好的东西移植,在嵌入式上完善功能。 其实嵌入式上的所有功能从最开始,几乎都是从 PC 上移植过来的,很多代码以及软件都 是在 PC 机上实现过,嵌入式 ARM 处理器的发展相对于滞后(ARM 的流行是 2000 年之后的 事情),所以在嵌入式上移植就成了非常重要的一项能力。 版本号:V2.0 日期:2015-10-2 - 208 - www.topeetboard.com 北京迅为电子有限公司 8.3Ubuntu 服务端的搭建 iTOP-4412 Linux 系统编程 V2.0 8.3.1 基本知识介绍 TFTP(Trivial File Transfer Protocol,简单文件传输协议),是一个基于 UDP 协议实现 的用于在客户机和服务器之间进行简单文件传输的协议,适合于开销不大、不复杂的应用场合。 TFTP 协议专门为小文件传输而设计,只能从服务器上获取文件,或者向服务器写入文件,不能 列出目录,也不能进行认证。 根据上面关于 TFTP 的介绍,实现 TFTP 我们需要搭建一个 TFTP 的服务器,iTOP-4412 开发板当做客户端。 使用我们的虚拟机 Ubuntu 来当做服务器,下面我们先讲解一下服务器端的配置。 根据上面关于 TFTP 的介绍,实现 TFTP 最终需要搭建一个 TFTP 的服务器,iTOP-4412 开发板当做客户端。 使用我们的虚拟机 Ubuntu 来当做服务器,下面我们先讲解一下服务器端的配置。 8.3.2 搭建服务器 在我们的虚拟机 Ubuntu 上打开终端,如下图: 版本号:V2.0 日期:2015-10-2 - 209 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 首先输入命令:sudo apt-get install xinetd,安装 xinetd,如下图: 安装完 xinetd,如下图: 版本号:V2.0 日期:2015-10-2 - 210 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接下来输入命令安装 tftp 和 tftpd:sudo apt-get install tftp tftpd,如下图: 安装完成后,如下图: 版本号:V2.0 日期:2015-10-2 - 211 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后建立 TFTP 的配置文件,使用命令:vi /etc/xinetd.d/tftp 建立文件,如下图: 写入下面的内容: service tftp 版本号:V2.0 日期:2015-10-2 - 212 - www.topeetboard.com 北京迅为电子有限公司 { socket_type = dgram protocol = udp wait = yes user = root server = /usr/sbin/in.tftpd server_args = -s /var/tftpboot/ disable = no per_source= 11 cps = 100 2 flags = IPv4 } 如下图: iTOP-4412 Linux 系统编程 V2.0 版本号:V2.0 日期:2015-10-2 - 213 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 注意:如上图所示,这个文件在粘贴内容之后,必须按照上面的格式严格对齐。 退出并保存。其中 server_args 设置的/var/tftpboot 目录是 tftp 服务器的目录,TFTP 客 户端就是从这个目录里面获取服务器上的文件的。使用命令 mkdir /var/tftpboot 建立 tftp 服 务器的目录,如下图: 版本号:V2.0 日期:2015-10-2 - 214 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后设置/var/tftpboot 的访问权限为 777,如下图: 输入:sudo /etc/init.d/xinetd restart 命令重启 xinetd 服务,如下图: 版本号:V2.0 日期:2015-10-2 - 215 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 服务器到这一步就搭建好了,后面来进行测试。 8.4 服务器测试 本机测试:在/var/tftpboot 下面建立一个文件 test,在里面输入 hello world,然后保存该 文件,如下图: 版本号:V2.0 日期:2015-10-2 - 216 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 在启动另外一个终端,如下图: 然后输入:tftp 127.0.0.1,如下图: 版本号:V2.0 日期:2015-10-2 - 217 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 输入 get test 获取 test 文件,如下图: 在上图我们看到获取到 test 的信息 13 字节,然后输入 q 退出 tftp,如下图: 版本号:V2.0 日期:2015-10-2 - 218 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后我们输入 ls 查看当前目录下是否有 test 文件了,通过查看,发现当前目录下应经有 test 文件了,这就是/var/tftpboot 目录下的那个 test 文件,如下图: 我们使用 cat 命令查看一下 test 文件的内容,如下图: 版本号:V2.0 日期:2015-10-2 - 219 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 通过上面的截图,我们看到 test 文件里面的内容是 hello world,与/var/tftpboot 目录的 test 是一样的,至此我们的 TFTP 服务器端的配置和测试就完成了。 版本号:V2.0 日期:2015-10-2 - 220 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第九章 开发板实现 TFTP 文件传输 9.1 本章导读 本章介绍如何使用 TFTP 服务器在开发板和虚拟机的 Ubuntu 进行传文件。 9.1.1 工具 9.1.1.1 硬件工具 开发板 PC 机 U 盘或者 TF 卡 9.1.1.2 软件工具 Ubuntu12.04.2 以及虚拟机 Arm-2009q3 编译器 Notepad++编辑器 超级终端 Vim 编辑器 TFTP 服务器 9.1.2 预备课程 基本开发工具的使用 版本号:V2.0 日期:2015-10-2 - 221 - www.topeetboard.com 北京迅为电子有限公司 常用 linux 命令 最小 linux 系统 TFTP 服务器搭建和测试 iTOP-4412 Linux 系统编程 V2.0 9.1.3 视频资源 本章配套视频为: “视频 09_01 同一网段的概念” “视频 09_02 开发板实现 TFTP 文件传输” 9.2 学习目标 本章需要学习以下内容: TFTP 文件的传输 9.3 同一网段的概念 在不少实验中,都会需要用到局域网的一些基础知识,在技术支持的过程中,发现不少用 户对于这个概念非常模糊,导致 IP 地址或者网络环境稍微有点变化,就无法实现实验。如果没 有接触过这个概念,建议将这一小节好好看一下,最好手动计算并验证两个 IP 地址是不是在同 一网段。 局域网通信中会经常用到“同一网段”的概念。要弄明白这个概念需要结合 IP 地址以及子 网掩码。 版本号:V2.0 日期:2015-10-2 - 222 - www.topeetboard.com 9.3.1IP 地址 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 关于 IP 地址的理论知识,网络上有大量的文章。 这里主要是介绍和开发板有关系需要注意的 IP 地址。 如下图所示,使用 ifconfig,可以查看 Ubuntu 系统下的 IP,下图表面 Ubuntu 的 IP 地址 是 192.168.0.226。 我们在使用 SSH 软件和 Ubuntu 连通传文件,就需要先在 Ubuntu 下查看 IP 地址。 再来看一下开发板的 IP,如下图所示,在查看最小文件系统的 etc 文件可以看到默认的 IP 地址为 192.168.1.230。 版本号:V2.0 日期:2015-10-2 - 223 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 上图是没有打包编译的最小系统,如下图所示,是运行着的最小 linux 系统,也是可以查 询和修改 IP 地址的。 最小系统在开发板上运行的时候,也可以使用 vi 命令来修改 IP 地址。 版本号:V2.0 日期:2015-10-2 - 224 - www.topeetboard.com 9.3.2 子网掩码 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 子网掩码的查询和 IP 的查询方式一模一样。 如下图所示,使用 ifconfig,可以查看 Ubuntu 系统下的子网掩码,下图表面 Ubuntu 的 子网掩码是 255.255.255.0。 再来看一下开发板的子网掩码,如下图所示,在查看最小文件系统的 etc/eth0-setting 文 件可以看到默认的子网掩码。 版本号:V2.0 日期:2015-10-2 - 225 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 上图是没有打包编译的最小系统,如下图所示,是运行着的最小 linux 系统,也是可以查 询和修改子网掩码。 最小系统在开发板上运行的时候,也可以使用 vi 命令来修改 IP 地址。 版本号:V2.0 日期:2015-10-2 - 226 - www.topeetboard.com 北京迅为电子有限公司 9.3.3 确认 IP 在同一网段 iTOP-4412 Linux 系统编程 V2.0 本小节主要介绍如何确认两个 IP 是不是在同一网段。 如果大家计算发现 Ubuntu 系统的 IP 和开发板的 IP 不在同一网段,则需要修改开发板的 IP。 单纯的两个 IP 不能直接拿来确认是不是在同一网段,必须结合子网掩码经过计算才能得出 结论。 计算方法是:两个 IP 分别和相应的子网掩码做与运算,得出的结果相等则表明在同一网段。 这里以 9.2.1 和 9.2.2 小节开发板和 Ubuntu 系统中的 IP 和子网掩码来做演示。 Ubuntu 系统的 IP 和子网掩码分别是:192.168.0.226 和 255.255.255.0 开发板的 IP 地址和子网掩码分别是:192.168.1.230 和 255.255.255.0 进行与运算需要转换为二进制 Ubuntu 系统: IP:11000000 10101000 00000000 11100010 MASK:11111111 11111111 11111111 00000000 Result 二进制:11000000 10101000 00000000 00000000 Result 十六进制:192.168.0.0 开发板: IP:11000000 10101000 00000001 11100110 MASK:11111111 11111111 11111111 00000000 版本号:V2.0 日期:2015-10-2 - 227 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 Result 二进制:11000000 10101000 00000001 00000000 Result 十六进制:192.168.1.0 对比上面两个十六进制结果,可以发现这两个例子中的 IP 地址并不在同一个网段。开发板 需要重新根据路由器或者交换机来修改 IP。 9.3.4 根据实际情况修改 IP 和子网掩码 如下图所示,作者的路由器地址为 192.168.0.1,大家根据实际情况登陆路由器,路由器背 面一般都有这个地址,如果没有查一下路由器的手册。 注意上图中 WAN 设置界面中的网关是 192.168.1.1,这个是广域网的网关,我们实验中使 用的是局域网的网关,需要选择“LAN 口设置”再查找网关。 如下图所示,选择 DHCP 服务器,这里会有一个分配局域网中的 IP 区间。也就是说 IP 可 以设置为 192.168.0.220 到 192.168.0.250 这个区间。 版本号:V2.0 日期:2015-10-2 - 228 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,选择“LAN 口设置”再查找,子网掩码为 255.255.255.0。 另外在后面的 NFS 文件系统实验的时候需要上面的 192.168.0.1 这个地址,可以把这个地 址看成局域网的网关,而不能使用 WAN 中的网关! 版本号:V2.0 日期:2015-10-2 - 229 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 了解了 IP 地址,子网掩码,查看了路由器设置之后,首先可以确定子网掩码为 255.255.255.0,然后 IP 地址可以处于 192.168.0.220 到 192.168.0.250 这个区间。大家可以 在这个区间取一个地址来计算。 最后根据大家的实际情况,确认了 IP 地址和 MASK 地址之后,修改最小 linux 系统中的 etc/eth0-setting 文件,将它们的 IP 设置到同一网段! 弄明白“同一网段”的概念之后,后面和网络相关的实验会简单很多。 9.4 配置 注意: 搭建最小 linux 文件系统的目录是在“/home/minilinux”上,用户只要在对应的目录下 修改即可。学习到这里,大家对于 linux 的目录应该是搞得清楚了,不会成为大家学习的障碍。 iTOP-4412 开发板我们制作的 linux 文件系统已经支持 TFTP 客户端命令了,编译 Busybox 时默认是支持该命令的,linux 文件系统在启动的时候我们通过脚本设置了以太网的 IP 地址是 192.168.1.230,这个脚本是在文件系统的 etc/eth0-setting 文件,打开这个文件,如下图: 版本号:V2.0 日期:2015-10-2 - 230 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如果我们想修改默认的 IP,子网掩码,网关,DNS,MAC 就编辑这个文件对应的选项就 可以了。 9.5 客户端的测试 现在我们在 iTOP-4412 上获取 TFTP 服务器上的文件,首先我们先看一下 TFTP 服务器的 IP 地址,如下图: 版本号:V2.0 日期:2015-10-2 - 231 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 通过上面的截图我们可以知道 TFTP 虚拟机的 IP 地址是 192.168.1.109,我们的开发板的 默认 IP 是 192.168.1.230,它们在同一个网段,如果不在同意个网段需要修改我们的开发板的 IP 地址,修改方法就是前面介绍的 etc 目录下的 eth0-setting 文件。 连接开发板的网口到路由器上,然后输入 ping 命令确认开发板和 TFTP 服务器是连通的, 如下图: 版本号:V2.0 日期:2015-10-2 - 232 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如果返回上面的信息就表示开发板和 TFTP 服务器是连通的,现在我们获取 TFTP 上的文件, 在开发板的串口输入:tftp -g -l test -r test 192.168.1.109,如下图: 执行完上面的命令,已经把 TFTP 上的 test 文件下载到开发板的当前目录下了,使用 cat 查看当前目录下 test 文件中的内容,如下图: 版本号:V2.0 日期:2015-10-2 - 233 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 通过上面的截图,我们可以看到文件的内容和 TFTP 上的文件内容是一样的,至此我们的 TFTP 搭建完成了,大家以后再调试程序的时候可以用 TFTP,这样就避免了每次都要生成镜像, 烧写景象了。 9.6TFTP 传输应用程序 下面给大家演示一下调试应用程序的方法,在虚拟机的 Ubuntu 上编写过一个输出 helloworld 的小程序,然后我通过交叉编译器编译这个程序生成了可执行文件 helloworld,我 通过 cp 命令把这个可执行程序 helloworld 拷贝到了/var/tftpboot 目录下面,接下来我要在 开发板端把 hello 文件下载到开发板上,我需要在开发板的串口上执行:tftp -g -l helloworld -r helloworld 192.168.1.109,如下图: 版本号:V2.0 日期:2015-10-2 - 234 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后我们输入 ls 命令查看一下当前目录,可以看到已经有 helloworld 这个文件了,如下 图,使用命令“./helloworld”运行程序,提示没有权限。 因为 helloworld 这个文件现在没有执行权限,所以我们需要输入 chmod 777 helloworld 命令来修改下 helloworld 的权限,然后运行 helloworld,如下图。 版本号:V2.0 日期:2015-10-2 - 235 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 我们可以看到程序输出:“hello world!”了。通过 TFTP 这种方式可以提高我们调试程 序的效率。 版本号:V2.0 日期:2015-10-2 - 236 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第十章 实现 NFS 网络文件系统 10.1 本章导读 除了前面介绍的 TFTP 网络可以方便学习之外,还有一种方法 NFS 网络文件系统,可以通 过网络启动文件系统。 如果是 Android 或者 Qt 的文件系统就太大了,启动速度慢,这么做也就没有什么意义了。 但是最小 linux 文件相对其它操作系统小很多,所以使用网络文件系统,可以方便的用户调试。 10.1.1 工具 10.1.1.1 硬件工具 开发板 PC 机 10.1.1.2 软件工具 Ubuntu12.04.2 以及虚拟机 Arm-2009q3 编译器 Notepad++编辑器 超级终端 Vim 编辑器 版本号:V2.0 日期:2015-10-2 - 237 - www.topeetboard.com 10.1.2 预备课程 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 基本开发工具的使用 常用 linux 命令 最小 linux 系统 10.1.3 视频资源 本节配套视频为: “视频 10_01 搭建和测试 NFS 服务器” “视频 10_02 配置内核”01 “视频 10_02 配置内核”02 10.2 学习目标 本章需要学习以下内容: 掌握 NFS 挂载文件系统的方法和步骤 10.3 基本环境介绍 使用的软硬件环境是:一台 PC,上面运行虚拟机 Ubuntu,iTOP-4412 开发板一块,PC 机和 iTOP-4412 开发板通过网线连接到路由器上面,路由器分配的网段是 192.168.1.x 的 ip 地址,默认网关是路由器的 ip 地址,即 192.168.1.1。PC 机的 ip 地址是 192.168.1.103, iTOP-4412 开发板的 ip 地址是 192.168.1.230,网段的子网掩码是 255.255.255.0。这几个 ip 版本号:V2.0 日期:2015-10-2 - 238 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 地址在后面配置 iTOP-4412 开发板内核 nfs 的时候会用到,大家需要根据自己使用的网络环境 来设置这几个 ip 地址,设置的原则是确保 PC 的 ip 和 iTOP4412 开发板的 ip 在同一个网段。 NFS 是 Network FileSystem 的缩写,是由 SUN 公司研制的 UNIX 表示层协议 (pressentation layer protocol),NFS 是基于 UDP/IP 协议的应用。它的最大功能就是可以 通过网络让不同的机器,不通的操作系统彼此共享文件,可以通过 NFS 挂载远程主机的目录, 访问该目录就像访问本地目录一样,所以也可以简单的将它看做一个文件服务器。通过 NFS 服 务,我们可以实现在线调试文件系统或应用程序,而不用像传统的方式生成文件系统镜像,然 后烧写到 iTOP-4412 的 eMMC 里,在启动开发板。通过 NFS 服务可以提高我们的调试效率。 10.4 搭建 NFS 服务器 实现 NFS,我们需要一个主机作为 NFS 服务器,我们选择我们的虚拟机 Ubuntu 作为主 机。首先我们需要在虚拟机的 Ubuntu 上安装 Ubuntu NFS 服务,这是一个软件包,我们可以 使用 apt 命令下载,(下载前请确认你的虚拟机可以上网)。首先登录到虚拟机上,使用快捷 键 Ctrl+Alt+t 组合按键打开终端如下图: 版本号:V2.0 日期:2015-10-2 - 239 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 输入 su root 命令切换到 root 用户,如下图: 输入 apt-get install nfs-kernel-server 命令安装 Ubuntu NFS 服务,如下图: 版本号:V2.0 日期:2015-10-2 - 240 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 在安装的过程中会提示“是否继续安装”的信息,如下图: 我们输入“Y”,如下图: 版本号:V2.0 日期:2015-10-2 - 241 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后按回车,会继续安装,如下图: 安装完成,如下图: 版本号:V2.0 日期:2015-10-2 - 242 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接下来需要配置/etc/exports,使用 vi 命令打开/etc/export,如下图: 在/etc/export 文件的最后一行添加: /home/topeet/linux/ *(rw,sync,no_root_squash),如下图: 版本号:V2.0 日期:2015-10-2 - 243 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 下面讲解一下上面输入的内容都代表什么意思: /home/topeet/linux:是要共享的目录; *:代表允许所有的网络段访问; rw:是可读写权限; sync:是资料同步写入内存和硬盘; no_root_squash:是 Ubuntu nfs 客户端分享目录使用者的权限,如果客户端使用的是 root 用户,那么对于该共享目录而言,该客户端就具有 root 权限; 其他 Ubuntu nfs 常用的参数有: ro:只读访问 async :nfs 在写入数据前可以相应请求 secure: nfs 通过以下的安全 TCP/IP 端口发送 insecure: nfs 通过 1024 以上的端口发送 版本号:V2.0 日期:2015-10-2 - 244 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 wdelay:如果多个用户要写入 NFS 目录,则归组(默认) no_wdelay:如果多个用户要写入 NFS 目录,则立即写入,当使用 async 时,无需此设置 hide:在 nfs 共享目录中不共享妻子目录 no_hide:共享 nfs 目录的子目录 subtree_check:如果共享/usr/bin 之类的子目录时,强制 nfs 检查父目录的权限(默认 ) no_subtree_check:和上面相对,不检查父目录权限 all_squash:共享文件的 UID 和 GID 映射匿名用户 anonymous,适合公用目录 no_all_squash:保留共享文件的 UID 和 GID(默认) root_squash root:用户的所有请求映射成如 anonymous 用户一样的权限(默认) no_root_squash root:用户具有根目录的完全管理访问权限 anonuid=xxx:指定 nfs 服务器/etc/passwd 文件中匿名用户多的 UID anongid=xxx:指定 nfs 服务器/etc/passwd 文件中匿名用户的 GID 接下来重启 portmap 服务,输入/etc/init.d/portmap restart 命令,如下图: 版本号:V2.0 日期:2015-10-2 - 245 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 运行结果如下图: 然后重启 nfs 服务,输入/etc/init.d/nfs-kernel-server restart 命令,如下图: 版本号:V2.0 日期:2015-10-2 - 246 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 运行结果如下图: 现在 Ubuntu nfs 服务器端的配置就完成了, 版本号:V2.0 日期:2015-10-2 - 247 - www.topeetboard.com 北京迅为电子有限公司 10.5 测试 NFS 服务器 iTOP-4412 Linux 系统编程 V2.0 完成前面的搭建工作之后,就可以在虚拟机 Ubuntu 本机上验证一下,例如我们把 /home/minilinux/system 挂载到/mnt 目录下,需要输入 mount -t nfs localhost:/home/minilinux/system /mnt 命令,如下图: 执行完上面的命令,可以使用 df 命令查看是否挂载成功,如下图: 版本号:V2.0 日期:2015-10-2 - 248 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 我们可以看到上图中高亮的那一行就是我们挂载的 nfs 文件系统,这说明我们的 Ubuntu nfs 服务器端搭建成功了。 本章节我们用前面章节制作的做小 linux 系统为例,通过 nfs 来挂载它。我们把 linux 最小 文件系统放到虚拟机 Ubuntu 的/home/minilinux/system 目录下,如下图: 实现 nfs 文件系统我们需要修改 linux 最小文件系统的 etc/init.d/ifconfig-eth0 文件,如 下图: 版本号:V2.0 日期:2015-10-2 - 249 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用 vi 命令修改第八行,修改为:if grep -q nfs /proc/mounts ; then,修改后如下图: 修改完成后保存并退出。 版本号:V2.0 日期:2015-10-2 - 250 - www.topeetboard.com 10.7 配置内核 1 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 下面我们开始配置 iTOP-4412 开发板的内核。要实现 nfs 功能,需要修改内核配置来支持, 打开内核源码,输入 cp config_for_linux .config 命令生成支持 linux 最小文件系统的内核配 置文件,如下图: 然后输入 make menuconfig 命令进入 linux 配置界面,如下图: 版本号:V2.0 日期:2015-10-2 - 251 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 选中“Networking support”,如下图: 然后按回车进入 Networking support 配置界面,如下图: 版本号:V2.0 日期:2015-10-2 - 252 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 选中“Networking options”选项,如上图所示,然后按回车进入 Networking options 配置界面,如下图: 在 Networking options 配置界面,选中“IP: kernel level autoconfiguration”,如下 图: 版本号:V2.0 日期:2015-10-2 - 253 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后返回到 make menuconfig 的初始界面,如下图: 然后选择“File systems”选项,如下图: 版本号:V2.0 日期:2015-10-2 - 254 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后输入回车,进入 File systems 配置界面,如下图: 选中“Network File Systems”选项,如下图: 版本号:V2.0 日期:2015-10-2 - 255 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后输入回车,进入 Network File Systems 配置界面,如下图: 版本号:V2.0 日期:2015-10-2 - 256 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 选中“NFS client support”,“NFS client support for NFS version 3”,“NFS client support for the NFSv3 ACL protocol extension”,“NFS client support for NFS version 4”,“NFS client support for NFSv4.1”,“Root file system on NFS”,如下图: 然后返回到 make menuconfig 的初始配置界面,如下图: 版本号:V2.0 日期:2015-10-2 - 257 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后在初始配置界面选中“Boot options”,如下图: 按回车进入 Boot options 配置界面,然后再 Default kernel command 里面输入: 版本号:V2.0 日期:2015-10-2 - 258 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 root=/dev/nfs rw nfsroot=192.168.1.103:/home/topeet/linux/app/system ip=192.168.1.230:192.168.1.103:192.168.1.1:255.255.255.0:iTOP:eth0:off rootfstype=ext4 init=/linuxrc console=ttySAC2,115200",如下图: 下面讲解一下上面输入命令的命令里面的几个参数: root=/dev/nfs rw nfsroot=192.168.1.103:/home/minilinux/system 表示挂载的 nfs 服 务器 ip 是 192.168.1.103,挂载的目录是/home/minilinux/system,(注意:/home/minilinux/ 是前面我们搭建 nfs 服务器设置的) ip=192.168.1.230:192.168.1.103:192.168.1.1:255.255.255.0:iTOP:eth0:off 这里面,第 一个 ip192.168.1.230 是我们开发板的 ip 地址,第二个 ip192.168.1.103 是 nfd 服务器的 ip, 第三个 ip192.168.1.1 是开发板的网关,255.255.255.0 是子网掩码,iTOP 是开发主机的名字 (一般无关紧要,可以随便填写),eth0 是网卡设备的名称。 版本号:V2.0 日期:2015-10-2 - 259 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 至此,linux 内核的配置就完成了,退出 make menuconfig 配置,会弹出保存窗口,如下 图: 使用键盘的左右方向键,选中上图的”Yes“,然后输入回车,退出保存配置,如下图: 然后输入 make 命令开始编译内核,如下图: 版本号:V2.0 日期:2015-10-2 - 260 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 编译过程如下图: 编译完成,如下图: 版本号:V2.0 日期:2015-10-2 - 261 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 至此,linux 内核支持 nfs 制作完成了。 将新生成的内核烧写到开发板,然后重启开发板,就可以使用 NFS 文件系统了。 10.7 配置内核 2 如果使用的是从 github 上下载的内核,那么除了需要严格按照 10.6 小节中步骤配置以外, 还需要简单的修改一下内核源码,屏蔽其中的调试信息。这部分需要先学习怎么使用 github 下载和编译,具体参考使用手册的附录。 版本号:V2.0 日期:2015-10-2 - 262 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,使用命令“find ./ -name dm9620.c”查找网卡的驱动源码。 如上图所示,dm9620 网卡驱动路径为“drivers/net/usb/dm9620.c”。使用 vim 编辑 器打开,如下图所示。 版本号:V2.0 日期:2015-10-2 - 263 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,在文件中查找关键词“LEN_PLOAD”。 如下图所示,将红色框中的代码注释掉。 版本号:V2.0 日期:2015-10-2 - 264 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 注释后如下图所示。 保存退出,然后重新编译,内核在有线网通信的就不会一直打印调试信息了。 版本号:V2.0 日期:2015-10-2 - 265 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第十一章 以 NFS 方式调试应用以及最小网络 11.1 本章导读 本章介绍一下通过 NFS 网络文件系统来调试我们的应用程序,我们这里以 linux qt 系统为 例。 在最小 linux 系统上调试应用的时候,首先是在虚拟机 Ubuntu 上通过交叉编译生成可执 行的二进制文件,然后把生成的二进制文件拷贝到文件系统里面,然后用命令重新生成 system.img,然后烧写 system.img 到开发板,然后启动开发板运行我们的程序,或者是通过 tftp 把执行文件下载到开发板上。 上面说的这两种方式操作起来都很麻烦,利用 NFS 调试程序非常方便。 11.1.1 工具 11.1.1.1 硬件工具 开发板 PC 机 U 盘或者 TF 卡 11.1.1.2 软件工具 Ubuntu12.04.2 以及虚拟机 Arm-2009q3 编译器 Notepad++编辑器 版本号:V2.0 日期:2015-10-2 - 266 - www.topeetboard.com 超级终端 Vim 编辑器 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 11.1.2 预备课程 基本开发工具的使用 常用 linux 命令 最小 linux 系统 helloworld 实现 NFS 网络文件系统 11.1.3 视频资源 本章配套视频为: “视频 11_01 以 NFS 方式调试应用” “视频 11_02 最小局域网实现 tftp 和 NFS” 11.2 学习目标 本章需要学习以下内容: 以 NFS 方式调试应用 11.3 利用 NFS 调试程序 首先我的 NFS 挂载的目录是“/home/minilinux”(如何搭建 NFS,可以参考我们的前一 章节专题-实现 NFS 网络文件系统)。 版本号:V2.0 日期:2015-10-2 - 267 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后以 helloword 程序为例来实现,helloword 保存在 “/home/linuxsystemcode/helloworld/”目录,如下图所示: 使用 vim 编辑器命令,打开 helloword.c,如下图所示。 版本号:V2.0 日期:2015-10-2 - 268 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 可以看到打开里面就一条打印语句,输出“Hello World!”,如下图所示。 接下来在虚拟机的终端将 helloworld 可执行文件拷贝到/home/minilinux/system/bin 目 录下,如下图所示。 版本号:V2.0 日期:2015-10-2 - 269 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接下来我们启动开发板,需要使用 NFS 文件系统启动开发板,串口打印信息如下图所示: 通过上面的图片我们可以看到挂载的 NFS 的信息。 版本号:V2.0 日期:2015-10-2 - 270 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接下来我们在超级终端中输入“ls /bin/”命令,可以查看根文件系统下的文件,如下图所 示: 下翻显示窗口,如下图所示可以看到 helloworld。 接下来在串口输入”./bin/helloword“命令运行”helloword“,运行结果如下图所示: 版本号:V2.0 日期:2015-10-2 - 271 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 我们可以看到串口打印“Hello World!” 了。 如下图所示,键入运行程序提示“ Permission denied”没有权限,则需要使用 chmod 命令来修改权限。 版本号:V2.0 日期:2015-10-2 - 272 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,修改文件权限,在运行 helloworld。 通过上面的步骤就可以使用 NFS 很方便的调试程序了。 11.4 最小局域网实现 tftp 和 NFS 这是一个暴露年龄的小技能,在网络不是很发达的时代,要是想联网玩游戏,会把两台电 脑直接用网线连接在一起,通过设置 IPV4,这两台机器就组成了局域网,然后可以开始愉快的 玩耍了。 部分学生用户,由于没有路由器和交换机,或者部分网络绑定了 IP 和 MAC 地址,无法分 配 IP 地址。但是教程中不少实验都需要将开发板和 Ubuntu 设置在同一网段,也就是处于同一 个局域网中。这时用户可以直接将将 PC 机的网口和开发板的网口用网线直连,它们在物理层 上就已经处在局域网中,然后经过简单的网络配置就可以实现和局域网一模一样功能。 版本号:V2.0 日期:2015-10-2 - 273 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 另外网上说的需要交叉网线,其实这个交叉网线是更早的技术了,现在几乎所有的网络都 支持网线的翻转,软件会自动识别和匹配,大家只要使用一根标准的网线就可以了,不需要关 心这个问题。 11.4.1PC 网络配置 进入 PC 机的网络和共享中心,win7 如下图所示,其它系统可以网上查找具体路径,单击 进入“网络和共享中心”。 如下图所示,单击选择本地连接。 版本号:V2.0 日期:2015-10-2 - 274 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如果拔掉网线后,网络设置则如下图所示。 如下图所示,单击“本地连接”。 版本号:V2.0 日期:2015-10-2 - 275 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,弹出本地连接对话框之后,然后选择单击“属性”。 弹出本地连接属性对话框。这里需要配置 IPV4,单击 IPV4 的设置。 版本号:V2.0 日期:2015-10-2 - 276 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,弹出 IPV4 设置的对话框。 版本号:V2.0 日期:2015-10-2 - 277 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后强制设置两台机器在同一网段。 如下图所示,选择“使用下面的 IP 地址”然后设置 IP 和子网掩码以及网关。 IP 地址:192.168.0.10 子网掩码:255.255.255.0 默认网关:192.168.0.1 版本号:V2.0 日期:2015-10-2 - 278 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 单击确定,保存退出。 11.4.4 修改开发板设置并测试 设置好之后需要将开发板的网络配置文件修改一下才能实现 tftp 传输文件。 IP 地址设置为:192.168.0.11 子网掩码 Mask 设置为:255.255.255.0 网关 Gateway 设置为:192.168.0.1 修改之后,如下图所示。 版本号:V2.0 日期:2015-10-2 - 279 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 修改之后,将开发板和 PC 的网口用一根网线连接,重启开发板,测试网络是否通畅。 如下图所示,启动最小 linux 系统,使用 ping 命令测试。 这里 PC 机的 IP 是 192.168.0.10,开发板的 IP 是 192.168.0.11 版本号:V2.0 日期:2015-10-2 - 280 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,可以看到有数据返回,表明开发板和 PC 机的网络已经设置好了。 11.4.2 虚拟机的设置 虚拟机的网络模式需要设置为“桥接模式”。 如下图所示。 设置后启动 Ubuntu。 Ubuntu 开启之后,如果使用 ifconfig 查看的 ip 地址和前面 PC 的 IP 不在同一网段,可以 手动设置 IP 地址,如下图所示。 单击右上角的上传下传的图标。 版本号:V2.0 日期:2015-10-2 - 281 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,在弹出框中单击“Edit Connnections...” 如下图所示,单击选择“Edit...” 版本号:V2.0 日期:2015-10-2 - 282 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,选择“IPv4 Settings”,Method 选择“Manual”,单击 Add。 添加 IP 地址:192.168.0.12 子网掩码:255.255.255.0 网关:192.168.0.1 保存退出配置界面。 版本号:V2.0 日期:2015-10-2 - 283 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 完成之后 Ubuntu 终端中使用命令 ifconfig 命令查看网络,如下图所示。 11.4.3 测试三者之间网络 前面分别设置了 PC 机、开发板、Ubuntu 的网络。 开启虚拟机,用网线将开发板和 PC 连接起来。 首先测试虚拟机 Ubuntu 和 PC 之间的网络,如下图所示,在 Ubuntu 终端中输入命令“ping 192.168.0.10”,Ctrl+c 可以结束。 这里特别注意,测试 Ubuntu 和 PC 之间的通信,需要用网线将开发板和 PC 连接起来,否 则将无法 ping 通。 版本号:V2.0 日期:2015-10-2 - 284 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着测试开发板和 Ubuntu 之间的网络,使用命令“ping 192.168.0.11”如下图所示。 通过了三者之间的测试,局域网就搭建起来了,可以在这个局域网中间进行 tftp 和 nfs 实 验了。 版本号:V2.0 日期:2015-10-2 - 285 - www.topeetboard.com 北京迅为电子有限公司 11.4.4 实现 tftp 下载功能 iTOP-4412 Linux 系统编程 V2.0 在最小局域网中,可以实现 tftp 快速下载。 如下图所示,在开发板中使用命令“tftp -g -l test -r test 192.168.0.12”可以下载 Ubuntu 系统中的 test 文件。 如下图所示,使用命令“cat test”可以看到 test 文件中的内容是 hello world,表明文件 一模一样。 版本号:V2.0 日期:2015-10-2 - 286 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着下载 helloworld,使用命令“tftp -g -l helloworld -r helloworld 192.168.0.12”, 如下图所示。 接着使用命令“chmod 777 helloworld”修改权限,然后使用命令“./helloworld”运行 可执行程序,如下图所示,可以看到打印出了“Hello World!”。 版本号:V2.0 日期:2015-10-2 - 287 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 11.4.5 修改内核配置实现 NFS 除去下面的设置,其它所有的设置都和前面使用交换机的设置方法一模一样。 这里在如下图所示的 menuconfig 的 Default kernel command 界面输入以下内容。 root=/dev/nfs rw nfsroot=192.168.0.12:/home/minilinux/system ip=192.168.0.11:192.168.0.12:192.168.0.1:255.255.255.0:iTOP:eth0:off rootfstype=ext4 init=/linuxrc console=ttySAC2,115200 如果没有完全按照手册设置 PC 机的 IP 和子网掩码,则需要根据实际情况将其设置到同一 网段。 设置后将内核烧写到开发板,然后就可以使用 nfs 网络文件系统了。 版本号:V2.0 日期:2015-10-2 - 288 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第十二章 专题实战延时 12.1 本章导读 本章介绍的延时函数,使用起来非常简单,但是却会经常用到的,所以单独作为一个专题 来介绍。 本章中除了介绍系统编程中的延时函数,还会介绍到内核中的延时函数,它们的使用方法 多是类似的,在驱动专题中大家可以使用,本章就不提供具体的例子了,只介绍函数调用。 12.1.1 工具 12.1.1.1 硬件工具 开发板 PC 机 U 盘或者 TF 卡或者 NFS 网络 12.1.1.2 软件工具 Ubuntu12.04.2 以及虚拟机 Arm-2009q3 编译器 Notepad++编辑器 超级终端 Vim 编辑器 版本号:V2.0 日期:2015-10-2 - 289 - www.topeetboard.com 12.1.2 预备课程 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 基本开发工具的使用 常用 linux 命令 最小 linux 系统 12.1.3 视频资源 本章配套视频为 “视频 12_01 延时之基本知识介绍” “视频 12_02 延时之延时实验” 12.2 学习目标 本章需要学习以下内容: linux 应用中延时函数的调用 12.3linux 中的延时函数介绍 这里要注意的是,不同的操作系统下,延时函数是不一样的,由具体系统决定的。 Linux 中常用的函数有以下函数 sleep、usleep、ndelay、udelay、mdelay 等 Linux 系统编程下用到的延时函数在头文件“#include ”中,包括函数 sleep、 usleep。 Linux 内核中用到的延时函数在“#include ”中,包括函数 ndelay、 udelay、mdelay。 版本号:V2.0 日期:2015-10-2 - 290 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 12.3.1 函数 sleep 简介 函数 sleep 是秒延时。函数原型如下: unsigned int sleep(unsigned int seconds); 例如:sleep(1),即延时一秒。 返回无符号的整形数值,如果延时成功则返回 0,如果延时过程中被打断,则返回剩余的 秒数。例如 sleep(5),返回值为 3,那么实际延时就是 5-3=2 秒。 12.3.2 函数 usleep 简介 函数 usleep 是微妙延时。函数原型如下: int usleep(useconds_t usec); Useconds 需要小于 1000000 例如:usleep(10),表示延时 10 微秒。 延时成功则返回 0,失败则返回-1 12.3.3 函数 delay 系列简介 函数 delay 系列是在 Linux 内核中用的,也就是在 linux 驱动中,我们会用到。 函数 mdelay 是毫秒延时,函数原型如下: void mdelay(unsigned long msecs); 例如:mdelay(10),表示延时 10 毫秒。 函数 udelay 是微秒延时,函数原型如下: void udelay(unsigned long usecs); 例如:udelay(5),表示延时 5 微秒。 版本号:V2.0 日期:2015-10-2 - 291 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 函数 ndelay 是纳秒延时,函数原型如下: void ndelay(unsigned long nsecs); 例如:ndelay(3),表示延时 3 纳秒。 再提醒一下,这里的 delay 函数只是在内核中使用的,sleep 是在系统编程中使用的。要 注意区分。 12.5 实验 Linux 应用中的延时 本实验先介绍简单的延时应用,在学习了后面时间管理之后,再对这些延时函数的进度进 行测试,虽然函数看起来类似,但是实现的原理不一样,精度不同,导致应用的场合也会不同。 12.5.1 函数代码 linux 系统编程中使用的是 sleep 和 usleep 函数。 编写简单的 sleep.c 文件测试 sleep 函数。 首先添加头文件,如下图所示。 然后 main 函数如下图所示。 版本号:V2.0 日期:2015-10-2 - 292 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图代码所示。 使用 sleep 和 usleep 函数分别延时 2 秒和 1 秒,然后循环打印信息。 12.5.2 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录“/home/linuxsystemcode/”, 使用命令“mkdir sleep”新建 sleep 文件夹,将源码 sleep.c 拷贝进去。 进入新建的文件夹 sleep,如下图所示。 版本号:V2.0 日期:2015-10-2 - 293 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用命令“arm-none-linux-gnueabi-gcc -o sleep sleep.c -static”编译 sleep 文件, 如下图所示,使用命令“ls”可以看到生成了 sleep 可执行文件。 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统,具体方法参考实验 02 将编译成的可执行文件 sleep,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,运行程 序如下。 版本号:V2.0 日期:2015-10-2 - 294 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,运行之后会打印“sleep 2!”和“usleep 1000000!”。 退出可以使用键盘输入“Ctrl+c” 12.6Linux 内核驱动中的延时 Linux 内核中使用 delay 系列函数,在后面驱动的学习中,再去测试 delay 函数,用起来 比较简单。 先要调用头文件“#include ”,然后就可以使用 delay 系列的函数,在驱 动做做延时操作了。 常用的地方,例如在驱动对硬件进行初始化的时候,例如芯片有上电时序,那么这个时候 就需要用到延时函数,直接调用 delay 即可。 版本号:V2.0 日期:2015-10-2 - 295 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第十三章 专题实战时间 13.1 本章导读 在编程中,时间的调用会经常用到,例如: 程序员想检测机器性能,那么需要运行一段代码,提取时间。 程序员需要在 log 文件中记录一些特殊时间,例如怀疑某个驱动出现了 bug,就需要写个 demon 来多次测试重启机器,并且测试驱动是否运转正常,这里就需要用到时间。 定时的应用,在某个事件之后,经过多长时间来进行某项操作。 …… 无论在任何操作系统中编程,都需要学习时间的编程,本章详细介绍 Linux 常用的时间结 构体和 API 以及提供几个常用的例程。 13.1.1 工具 13.1.1.1 硬件工具 开发板 PC 机 U 盘或者 TF 卡 13.1.1.2 软件工具 Ubuntu12.04.2 以及虚拟机 Arm-2009q3 编译器 版本号:V2.0 日期:2015-10-2 - 296 - www.topeetboard.com 北京迅为电子有限公司 Notepad++编辑器 超级终端 Vim 编辑器 13.1.2 预备课程 基本开发工具的使用 常用 linux 命令 最小 linux 系统 helloworld 13.1.3 视频资源 本节配套视频为: “视频 13_01 时间之基本概念” “视频 13_02 时间之时间调用” “视频 13_03 时间之时间转换” “视频 13_04 时间之处理器性能测试” 13.2 学习目标 本章需要学习以下内容: 了解 linux 中时间的基本概念 掌握最基础的时间编程方法 iTOP-4412 Linux 系统编程 V2.0 版本号:V2.0 日期:2015-10-2 - 297 - www.topeetboard.com 北京迅为电子有限公司 13.3Linux 中时间的几个基本概念 iTOP-4412 Linux 系统编程 V2.0 13.3.1 什么是 UTC 时间? 世界统一时间,世界各地的时间以这个为基准 。 13.3.2 什么是 UNIX 纪元时间? Unix time 是指从 1970 年 1 月 1 日 00:00:00 UTC 开始所经过的秒数。 在 linux 中时间日期会以这种方式存储时间,有效位是秒。例如经过了 1 分钟,这个数值 会变大 60 秒。 13.3.3 什么是格林尼治标准时(GMT)时间? GMT 是指太阳经过英国格林尼治的时间。在英国很 NX 的时候,以格林尼治为 0 度经线, 将世界分为 24 个时区。 北京时间指的是东八区的时间,和格林尼治时间相差 8 个小时。 13.3.4 什么是机器日历时间 对于 Linux 来说,机器日历时间是 UNIX 纪元时间。 13.4 实验-时间的调用 13.4.1 时间调用函数 本小节介绍常用的 Linux 时间函数 time。 函数 time_t time(time_t *t)在头文件“#include ”中。 版本号:V2.0 日期:2015-10-2 - 298 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 参数 1:time_t 类型,以秒为单位,如果有参数则数据传送到 time_t *t 中。 返回值:如果参数为 NULL 会返回 time_t 类型;出现错误返回-1. 其中的时间类型 time_t,它是一个 long 类型,及其机器日历时间,在头文件 time.h 中定 义。 13.4.2 函数代码 编写简单的 gettime.c 文件测试 gettime 函数。 首先添加头文件,如下图所示。 然后 main 函数如下图所示。 如上图代码所示。 版本号:V2.0 日期:2015-10-2 - 299 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用了两种方式返回时间,一种写入参数,一种写入 NULL。 13.4.3 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录“/home/linuxsystemcode/”, 使用命令“mkdir time”新建 time 文件夹,将源码 gettime.c 拷贝进去,进入新建的文件夹 time,如下图所示。 使用命令“arm-none-linux-gnueabi-gcc -o gettime gettime.c -static”编译 open 文 件,如下图所示,使用命令“ls”可以看到生成了 gettime 可执行文件。 版本号:V2.0 日期:2015-10-2 - 300 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统,具体方法参考实验 02 将编译成的可执行文件 gettime,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,运 行程序如下。 版本号:V2.0 日期:2015-10-2 - 301 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,运行两次程序,两次运行有几秒间隔,那么得到的时间就会不同。 13.5 实验-时间的转换 如上面的实验所示,类似的 0x 进制数对于人类来说太不容易知道具体含义了,需要将时间 转化为群众喜闻乐见的年月日时分秒的形式。这部分内容就涉及到本节介绍的时间格式转换问 题。 13.5.1 时间转换的函数 下面先介绍常用时间 tm 结构体,如下所示。 struct tm{ int tm_sec; int tm_min; int tm_hour;int tm_mday; int tm_mon; int tm_year; int tm_wday;int tm_yday; int tm_isdst; }; 其中的成员如下: int tm_sec; 秒 – 取值区间为[0,59]。 int tm_min; 分 - 取值区间为[0,59]。 int tm_hour; 时 - 取值区间为[0,23]。 int tm_mday;一个月中的日期 - 取值区间为[1,31]。 版本号:V2.0 日期:2015-10-2 - 302 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 int tm_mon;月份(从一月开始,0 代表一月) - 取值区间为[0,11]。 int tm_year;年份,其值等于实际年份减去 1900。 int tm_wday;星期 – 取值区间为[0,6],其中 0 代表星期天,1 代表星期一,以此类推 。 int tm_yday;从每年的 1 月 1 日开始的天数 – 取值区间为[0,365],其中 0 代表 1 月 1 日, 1 代表 1 月 2 日,以此类推。 int tm_isdst; 夏令时标识符,实行夏令时的时候,tm_isdst 为正。不实行夏令时的进候, tm_isdst 为 0;不了解情况时,tm_isdst()为负。 如果使用 time_t 类型的时间人类是无法识别,Linux 中提供了几个时间转换函数。 函数 ctime:将时间转化为字符串格式。 char *ctime(const time_t *timep); 函数 gmtime:将时间转化为格林威治时间,以 tm 结构存储。 struct tm *gmtime(const time_t *timep); 函数 asctime:将时间转换为字符格式,注意这个函数的参数是 tm 结构的。 char *asctime(const struct tm *tm); 函数 localtime:将时间转化为本地时间。 struct tm *localtime(const time_t *clock); 需要注意的是,上面几个函数的参数和以及返回值是不同的。 13.5.2 函数代码 编写简单的 exchangtime.c 文件测试 exchangtime 函数。 版本号:V2.0 日期:2015-10-2 - 303 - www.topeetboard.com 北京迅为电子有限公司 首先添加头文件,如下图所示。 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数如下图所示。 如上图代码所示。 函数 time 用于获取当前时间。 函数 ctime 将时间转为字符串。 函数 localtime 将时间转化为本地时间。 函数 gmtime 将时间转换为格林威治时间。 函数 asctime 将时间转化为本地时间。 版本号:V2.0 日期:2015-10-2 - 304 - www.topeetboard.com 北京迅为电子有限公司 13.5.3 编译运行测试 iTOP-4412 Linux 系统编程 V2.0 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/time”,将源码 exchangtime.c 拷贝进去,进入新建的文件夹 time,如下图所示。 使用命令“arm-none-linux-gnueabi-gcc -o exchangtime exchangtime.c -static”编 译 exchangtime 文件,如下图所示,使用命令“ls”可以看到生成了 exchangtime 可执行文 件。 版本号:V2.0 日期:2015-10-2 - 305 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统,具体方法参考实验 02 将编译成的可执行文件 exchangtime,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘, 运行程序如下。 如上图所示,打印出字符串形式的时间。 版本号:V2.0 日期:2015-10-2 - 306 - www.topeetboard.com 13.5.3 小提示 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 在实际中,linux 单调的时间显示方式在很多场合显然不合适。这个时候用户可以将时间提 取出来,自定义输出。 例如只想输出当前的时间或者当前的日期之类的。 这个步骤很简单就不再列举例程了,只需要提取时间,做个简单的处理就可以了。 13.6 实验-处理器性能的测试 测试性能以秒为单位明显不够,提高精度则需要本节介绍的函数。本节实验稍微修改一下 就可以作为拿到任何开发板之后的测试例程。 13.6.1 高精度时间函数 函数 gettimeofday 在头文件“”中。 接着介绍精度高一点的设置时间函数和读取时间函数。 int gettimeofday(struct timeval *tv, struct timezone *tz); int settimeofday(const struct timeval *tv, const struct timezone *tz); 上面两个时间函数在头文件“#include ”中。 先来介绍一下参数中的两个结构体。 struct timeval { time_t tv_sec;/* seconds */ suseconds_t tv_usec;/* microseconds */ 版本号:V2.0 日期:2015-10-2 - 307 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 }; struct timezone { int tz_minuteswest;/* minutes west of Greenwich,格林威治时间的 时差 */ int tz_dsttime;/* type of DST correction,时间修正的方式 */ }; 如上所示,介绍一下参数。 参数 tv:用于保存获取的时间。 参数 tz:可以缺省,传入 NULL。 上面获取的时间精度达到了微妙,比 time 函数获取的时间精度要高 6 个数量级。这个精 度就可以用于计算代码执行时间了。 13.6.2 实验代码 编写简单的 precisiontime.c 文件测试 gettimeofday 和 settimeofday 函数。 首先添加头文件,如下图所示。 然后看一下耗时的函数,比较简单就是一个循环。 版本号:V2.0 日期:2015-10-2 - 308 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数如下图所示。 如上图代码所示。 通过 gettimeofday 获取两次当前时间,运行耗时函数之后计算差值,最后将耗时计算出 来。 版本号:V2.0 日期:2015-10-2 - 309 - www.topeetboard.com 北京迅为电子有限公司 13.6.3 编译运行测试 iTOP-4412 Linux 系统编程 V2.0 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/time,将源码 precisiontime.c 拷贝进文件夹 time,如下图所示。 使用命令“arm-none-linux-gnueabi-gcc -o precisiontime precisiontime.c -static” 编译 precisiontime 文件,如下图所示,使用命令“ls”可以看到生成了 precisiontime 可执行 文件。 版本号:V2.0 日期:2015-10-2 - 310 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统,具体方法参考实验 02。 将编译成的可执行文件 precisiontime,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘, 运行程序如下。 版本号:V2.0 日期:2015-10-2 - 311 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,可以看到这个循环耗时为 0.088172 秒。 版本号:V2.0 日期:2015-10-2 - 312 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第十四章 Linux 编程中 man 命令的使用 14.1 本章导读 在开发板的使用手册中,简单的介绍过使用 man 查找 linux 的命令,但是强大的 man 命 令不止查找命令这一个简单的功能。还可以查找各种 API 函数,想要学会 linux 编程,这个 man 命令一定要非常熟练度的掌握。 man 命令熟悉之后,很多东西就可以不用教程,不用手册,可以自己进行学习了。将来大 家独立做实际项目或者学习的时候,会经常用到 man 命令的。 14.1.1 工具 14.1.1.1 硬件工具 PC 机 14.1.1.2 软件工具 Ubuntu12.04.2 以及虚拟机 Vim 编辑器 14.1.2 预备课程 常用 linux 命令 版本号:V2.0 日期:2015-10-2 - 313 - www.topeetboard.com 14.1.3 视频资源 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 本章配套视频为: “视频 14Linux 编程中 man 命令的使用” 14.2 学习目标 本章需要学习以下内容: 熟练掌握和运用 man 命令 14.3 关于英语 在做技术支持的时候,很多同学问到如何学习英语。 我的回答很简单“看到不会的单词,记下来,有空的时候看一下,直到记住为止”。 工作中用到的专业英语,没有捷径,只有一遍一遍的记,一个一个的记。 在这件事情上,对所有人都是公平公正的,一份耕耘一份收获! 14.4man 命令简介 14.4.1man 命令简介 大多数用户学习这里,会感到一点迷茫或者吃力。觉得那么多函数,那么多头文件,怎么 记得住! 事实上,学习到一个阶段之后,就需要自学了,那么到了什么程度可以开始自学?怎么自 学呢? 版本号:V2.0 日期:2015-10-2 - 314 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 利用我们提供的教程,对 linux 的整个知识框架有较全面的了解之后,如果自己感觉对某 一个知识点不了解,可以看一下网上对应的文章,这里强烈建议大家使用 Google 去学习。 另外就是看官方的手册,学习 window 或者 Android 的开发,都是学习开发文档,开发文 档中提供了详细学习和编程资料。在 linux 下编程,用的最多的就是 man 命令,man 命令就 类似 window 和 Android 下的开发文档,极其强大。 其实使用 man 命令可以很容易查到最权威的头文件,函数定义,函数参数,函数描述等等。 前面介绍 man 命令,只是针对 linux 命令简单的介绍了一下,本章给大家介绍如何使用 man 命令查找资料,以及资料的结构。 14.4.2man 系统 先来学习一下 man 系统的信息,man 命令本身也是一个阅读文档的小程序,man 也是属 于 linux 命令,那么使用 man 命令是可以查询 linux 命令的,根据慢查阅的语法就可以使用“man man”查找 man 相关的文档资料(很绕口,可以看下面的例子)。 如下图所示,在 Ubuntu 系统下使用命令“man man”,来查阅一下 man 本身。 版本号:V2.0 日期:2015-10-2 - 315 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,是 man 命令相关的资料文档。 如下图所示,man 命令文档非常多,在 Ubuntu12.04.2 上有 700 多页(注意不同的 linux 系统下,因为版本不同 man 命令稍微会有点区别的,不过大概的用法都是类似) 版本号:V2.0 日期:2015-10-2 - 316 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 14.4.2man 的分页 通常情况下,UNIX 系统上的所有软件(包括每个命令行实用程序、每个系统调用、编程 库中每个可调用的函数和每种文件格式)都包含一个手册页。实际上,在构建新软件时编写并 提供手册页被认为是一种必要的 “礼节”。 在以前,手册页存储库曾经放在 /usr/man。最近,存储位置已经改为 /usr/share/man, 但是具体位置因 UNIX 版本而异。另外,软件包经常把它的手册页放在自己的根目录的子目录 中。例如,MySQL 数据库引擎的一些版本把手册页存储在 /usr/local/mysql/man 中。这些 策略都是允许的,但是,如果手册页分散在许多存储库中,就需要一些额外的配置。 如下图所示,是打开 man 文档之后的截图,红色箭头指的 man 后面有个 版本号:V2.0 日期:2015-10-2 - 317 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 无论它的位置在哪里,每个存储库都划分为一个或多个部分。每个部分实现为一个独立的 子目录。每个部分按惯例命名为 man1、man2 直到 man8,分别包含一类命令的手册页。 表 1 列出部分名及其内容。 man 手册分页的标准内容。 man1 一般命令。这个部分中的命令通常不需要超级用户(即管理员)特权。ls、 cat 和 passwd 放在这里,还有 shell。例如,请试试 man bash。 man2 用来访问 UNIX 内核提供的服务的系统调用或函数。例如 fork 系统,它 从一个现有的进程生成一个新进程。输入 man fork 显示它的手册页。使 用系统软件的程序员常常参考这个部分。 man3 C 库函数。许多软件包提供功能丰富的代码库,让开发人员可以创建新软件 来补充现有的特性或开发全新的特性。每个库通常有一个手册页;一些库(比 如系统的 libc)太大了,所以各个函数或一组相关函数有单独的文档。 man4 特殊文件,比如设备和驱动程序。 版本号:V2.0 日期:2015-10-2 - 318 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 man5 文件格式。UNIX 几乎完全使用文本配置文件定制系统的操作。有大量配置 文件,包括网络服务的列表 (/etc/services) 和可用的 shell 列表 (/etc/shells) 等等。 man6 游戏和屏幕保护程序。 man7 杂类文件。这是一个包罗万象的类别。在传统的系统上,可以了解 glob 操 作符、正则表达式等方面的信息。 man8 系统管理命令,超级用户很可能要使用它们。 上面的 8 种 man 命令,通常我们使用的 man1、man2 和 man3 比较多,而且并不是所 有的都有上面八种文档,有的只有一种,或者两种文档。 可能前面“man man”大家还是不太容易理解。后面举几个容易理解的例子,大家稍微加 把劲,很快就能熟练应用了。 14.4.3 手册页的框架 尽管各个命令的选项差异很大,但是手册页的内容相当有规律。实际上,手册页之所以是 宝贵的参考资料,就是因为它们符合惯例。阅读一小段文字之后,您很快就能够跳到文档的正 确部分,找到您要找的信息。 最简单的手册页包含五个部分:名称、大纲、描述、一些示例和其他相关资料的引用。 name(名称)给出命令、函数或文件格式的名称,以及对软件作用的单行的准确描述。 版本号:V2.0 日期:2015-10-2 - 319 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 synopsis(大纲)简要描述如何使用这个软件。如果手册页的主题是命令,那么这个部分 显示必需的和可选的选项、参数的格式和参数次序。如果主题是系统调用或库函数,那么这个 部分显示函数的形式参数以及使用函数所需的头文件(如果有的话)。 例如,下面是 BSD UNIX 上 du 命令的大纲。 du [-H | -L | -P] [-a | -s | -d depth] [-c] [-h | -k | -m | -g] [-x] [-I mask] [file ...] 命令大纲中使用的表示法是手册系统中有帮助的惯例之一(一些建模实用程序提供的使用 方法提示借鉴了这种表示法)。这里的大纲的意思是,“输入 du;可选地输入 -H、-L 或 -P 选项之一;然后,可选地输入 -a、-s 或 -d 之一,但是如果使用最后一个选项,还要指定一 个深度(depth);指定 -c,也可以不指定;可选地输入 -h、-k、-m 或 -g 之一;指定 -x, 也可以不指定;指定 -I 和一个掩码,也可以不指定;最后,提供一个或多个文件名。省略号 (...) 表示多于一个。 分组在一起的选项(比如第一组 -H、-L 和 -P)的关系就像是图形用户界面 (GUI) 中的 单选按钮:只能选择其中一个。独立的选项(比如 -c 和 -x)就像是复选框:可以打开或关闭。 这种表示法很容易阅读,很快就可以按照它输入命令。 下面是 open() 系统调用的大纲: #include int open(const char *path, int oflag, ...); 这个大纲表明,需要头文件 fcntl.h,open() 返回一个整数,必须指定要打开的文件的路 径和一组决定模式(只读、读/写、打开并截断等等)的标志。 版本号:V2.0 日期:2015-10-2 - 320 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 description(描述)部分讨论特性、使用方法和命令行上可以使用的所有选项。如果想知 道 du -H 的作用,可以阅读描述中的文本。 examples(示例)部分给出实用程序的一般用途、常见的特殊情况和解释。 最后一部分 See Also(参见)提供相关资料的引用,比如其他相关命令、重要的系统文件、 行业标准规范等等。 除了前面提到的几个部分,在手册页中可能还有其他特殊部分。一个重要的部分是 “Environment(环境)”。可以设置它列出的环境变量来影响实用程序的操作。例如,man 的手册页列出 10 个多环境变量,可以通过修改它们定制 man。其中之一是 MANPATH,它 指定寻找手册页时要搜索的目录。 14.4.4linux 命令手册页举例 1 下面给大家看一下 sleep 命令,如下图所示,使用命令“man sleep”,先不带页。 版本号:V2.0 日期:2015-10-2 - 321 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,可以看到 NAME,DESCRIPTION,AUTHOR。 NAME 中描述了函数名是 sheep,以及基本功能是延时一段时间 SYNOPSIS 描述了如何使用这个程序,sleep 后面加数字 number。 AUTHOR 是作者,也就是谁写的这个文档。 DESCRIPTION 是描述这个程序特性、使用方法以及可以使用的选项。 如下图所示,向下翻。 版本号:V2.0 日期:2015-10-2 - 322 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,可以看到 REPORTING BUGS、COPYRIGHT、SEE ALSO REPORTING BUGS 如果发现使用的时候发现了 BUG,可以怎么提交报告。 COPYRIGHT 版权,版权要遵循一系列的 GPL 协议,在后面驱动教程中会介绍 GPL 协议。 SEE ALSO 参见,提供引用的相关资料。sleep(3)这个要注意,也就是说这个 sleep 在 C 库页部分,可以使用“man 3 sleep”。 使用命令“man 1 sleep”,那么查找的就是函数 sleep 的命令,本小节的是 sleep(1), 使用命令“man 3 sleep”,查找的就是 c 库中的用法了。 还会提示可以使用其它的页。 14.4.4linux 命令手册页举例 2 接着看一下“man 3 sleep”命令,如下图所示。 版本号:V2.0 日期:2015-10-2 - 323 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示。 如上图所示,有 NAME,SYNOPSIS,DESCRIPTION,RETURN VALUE,CONFORMING TO,BUGS 等 可以看到地方 sleep 只能延时秒了,前面 sleep 命令是可以延时天和小时的。这里作为 c 的库文件,介绍了头文件以及函数原型,返回值等等 版本号:V2.0 日期:2015-10-2 - 324 - www.topeetboard.com 北京迅为电子有限公司 前面一张图下翻,如下图所示。 iTOP-4412 Linux 系统编程 V2.0 如上图所示,特别要注意上面的 SEE ALSO,它会介绍相关的函数,也就是在某些场合的 应用有相关性的函数,这里有 alarm,nanosleep,signal,signal,因为这几个函数都可以实 现延时功能,不过属于不同的方式。 另外 alarm(2),括号的 2 表示可以使用“man 2 sleep”查看它。 前面介绍的专题延时、专题时间管理以及后面要介绍的专题,大家在使用我们的实验手册 之余,可以使用 man 命令参考着学习! 这个 man 命令易学,容易上手,虽然初期需要花习惯使用英文,但是一旦大家习惯了,对 大家后面的发展会有很大的帮助的。 这个过程非常重要,我们介绍的东西,只是其中的一部分。如果大家将来需要用到其它部 分,那么还是需要使用 man 命令来查找相关文档的。 版本号:V2.0 日期:2015-10-2 - 325 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第十五章 专题 管理文件和目录 15.1 本章导读 “Linux 中一切皆文件”,好吧,这句话已经提到了无数次了,前面介绍的只是文件 IO, 只是属于 linux 文件中知识体系中很一小部分的内容,还有字符驱动也是以文件的样子呈现在 程序员眼中。 本章介绍的目录,也是在 linux 文件的基础上来做的的,只不过操作和 API 函数由于不同 的文件稍微有点不同。 除了文件和目录,还会介绍一下硬链接,硬链接也是一种特殊的文件,如果大家在前面编 译过 qt,使用 ln 命令就是创建链接文件,如果没有做,也没有关系,硬链接部分看了这个专题 之后,就能很快理解和掌握了。 另外,本章知识非常杂,非常琐碎,如果记不住也没关系,有这么一个印象,到实际应用 的时候,可以通过 man 命令查找用法。 本章大部分知识点会通过 linux 的 man 给大家讲解,一方面学习本章知识,另一方面帮助 大家更好的掌握 man 命令。 还有两点要注意的是: 要留意一些低版本的函数和系统函数,能用高版本的就用高版本的。 能用 c 库中的函数就用 c 库中的函数,而不要用系统的函数和接口,c 的移植性更强,任 何系统函数换了平台都可能无法使用了,但是绝大多数平台都可以支持 c 库,包括 Android, QtE 等等平台。 版本号:V2.0 日期:2015-10-2 - 326 - www.topeetboard.com 15.1.1 工具 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 15.1.1.1 硬件工具 开发板 PC 机 U 盘或者 TF 卡或者 NFS 15.1.1.2 软件工具 Ubuntu12.04.2 以及虚拟机 Arm-2009q3 编译器 Notepad++编辑器 超级终端 Vim 编辑器 15.1.2 预备课程 基本开发工具的使用 常用 linux 命令 最小 linux 系统 helloworld 文件 IO 15.1.3 视频资源 本章配套视频为: 版本号:V2.0 日期:2015-10-2 - 327 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 “视频 15_01 管理文件和目录之基本概念” “视频 15_02 管理文件和目录之 stat 函数组” “视频 15_03 管理文件和目录之 chmod 权限” “视频 15_04 管理文件和目录之 getcwd 获取当前目录” “视频 15_05 管理文件和目录之 mkdir 创建目录” “视频 15_06 管理文件和目录之 rmdir 删除目录” “视频 15_07 管理文件和目录之 chdir 改变当前目录” “视频 15_08 管理文件和目录之 opendir 和 closedir 目录” “视频 15_09 管理文件和目录之 readdir 读取目录信息” “视频 15_10 管理文件和目录之链接以及基础知识” “视频 15_11 管理文件和目录之硬链接 link” “视频 15_12 管理文件和目录之符号链接 symlink” “视频 15_13 管理文件和目录之解除链接 unlink” “视频 15_14 管理文件和目录之拷贝文件” “视频 15_15 管理文件和目录之移动文件” 15.2 学习目标 本章需要学习以下内容: 强化 man 命令的使用 强化 man 文档的使用 掌握管理文件和目录的方法 版本号:V2.0 日期:2015-10-2 - 328 - www.topeetboard.com 北京迅为电子有限公司 15.3 文件元数据以及基础知识 iTOP-4412 Linux 系统编程 V2.0 每一个文件都有一个索引节点 inode,inode 是由文件系统提供的唯一数值编址,这个数 值称为 inode 编号。索引节点是唯一的,同一个系统下,每一个索引节点对应一个文件(目录 也可以当做文件),inode 中存储了与文件相关的元数据,例如访问权限,访问时间,所有者, 用户组,大小以及文件数据存储位置。 如下图所示,在虚拟机的 Ubuntu 系统下使用命令“ls -i”,可以看到文件和目录的 inode。 另外在启动开发板,在超级终端中也可以使用这个命令,如下图所示。 版本号:V2.0 日期:2015-10-2 - 329 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,可以看到各种不同的索引节点。不知道大家发现没有目录 proc 和 sys 的索引 节点是一样的,这两个其实都是指向同一个文件,就像一个人有小名和学名一样,指的都是同 一个人。这种情况是属于 linux 文件中的硬链接,在后面会介绍到。 15.4 实验-stat 函数组 从这个实验开始,会更多的使用 man 来学习各种函数和 API 接口。 本节会介绍详细一些,这个过程大家好掌握,后面的实验就很直接的给出截图和分析函数 的使用了。如果觉得掌握的不够,自己看几页 man 的文档也花不了多长时间,毕竟它是如此重 要的知识点。 15.4.1 使用 man 学习 stat 函数组 如下图所示,使用命令“man stat”查看 stat 函数组的文档。 版本号:V2.0 日期:2015-10-2 - 330 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 打开之后如下图所示,stat(1)是属于 linux 命令的知识,如果想学习可以看一下,不是我 们需要的 stat 函数用法。 下翻到“SEE ALSO”,如下图所示,可以看到有 stat(2)也,(2)表示内核提供的服务调 用或者函数,是我们需要的。 版本号:V2.0 日期:2015-10-2 - 331 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 退出后,然后使用命令“man 2 stat”,如下图所示。 如下图所示,可以看到函数的头文件以及函数组。 版本号:V2.0 日期:2015-10-2 - 332 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,可以看到保存文件的结构体 struct stat,如下图所示,可以看到非常详细的 结构成员注释。 下翻一下,可以看到很多的宏定义解释,这些具体用到的时候可以来查阅,如下图所示, 是结构成员 st_mode 的参数。 版本号:V2.0 日期:2015-10-2 - 333 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 在学习函数的调用前,最后看一下“SEE ALSO”,如下图所示。 如上图所示,可以看到和 stat 函数组相关的一些函数,相关的函数后面大部分会介绍到。 回到 man 文档的最顶行,如下图所示,介绍一下这几个函数的用法。 版本号:V2.0 日期:2015-10-2 - 334 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 其实下面对于系统函数或者 API 的介绍,在 man 文档中都有介绍,大家可以自己尝试着 看一下部分英文的内容。 函数 int stat(const char *path, struct stat *buf); 参数*path:文件路径。 参数*buf:文件信息。 返回值:成功为 0,否则为-1。 函数 int fstat(int fd, struct stat *buf); 参数 fd:文件描述符。 参数*buf:文件信息 返回值:成功为 0,否则为-1。 函数 int lstat(const char *path, struct stat *buf); 版本号:V2.0 日期:2015-10-2 - 335 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 参数*path:文件路径。 参数*buf:返回文件的信息,针对符号链接,lstat 返回链接本身,而不是而非目标文件; stat 返回的是目标文件。链接可以类比 window 下的快捷方式。 返回值:成功为 0,否则为-1。 15.4.2stat 函数组例程 新建文件 stat.c,用于学习 stat 函数组。 首先添加头文件,如下图所示。 然后 main 函数如下图所示,先编写测试 stat 函数的代码。 版本号:V2.0 日期:2015-10-2 - 336 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 编写测试 fstat 函数的代码。 编写测试 lstat 函数的代码。 如上图代码所示。 版本号:V2.0 日期:2015-10-2 - 337 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第 10 行:通过 main 函数可以传参数,也就是文件的路径。 第 15-18 行:检测是否有传入参数。 第 21-25 行:使用 stat 读取文件的信息,如果路径不对则打印提示信息。 第 26 行:打印文件的 inode 信息。 第 29-34 行:使用 open 函数获取文件句柄。 第 35-39 行:使用 fstat 读取文件的信息,如果路径不对则打印提示信息。 第 40 行:打印文件的 inode 信息。 第 43-47 行:使用 lstat 读取文件的信息,如果路径不对则打印提示信息。 第 48 行:打印文件的 inode 信息。 返回的其它信息,大家也可以打印出来,方法类似。 15.4.3 编译运行测试 如下图所示,进入“/home/linuxsystemcode”目录,使用命令“mkdir CatlogFile”, 进入新建的 CatlogFile 目录,如下图所示。 版本号:V2.0 日期:2015-10-2 - 338 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后将源码 stat.c 拷贝到该目录下,使用命令 “arm-none-linux-gnueabi-gcc -o stat stat.c -static”编译,生成文件“stat”,如下 图所示。 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 版本号:V2.0 日期:2015-10-2 - 339 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 将编译成的可执行文件 stat 以及 stat .c(用来测试)文件,拷贝到 U 盘,启动开发板,插 入 U 盘,加载 U 盘之后,运行程序如下。 15.5 实验-chmod 权限函数 前面介绍过使用 chmod 命令修改权限,本节介绍 chmod 修改文件权限的函数。 15.5.1 使用 man 学习 chmod 函数 如下图所示,使用命令“man 2 chmod”。 版本号:V2.0 日期:2015-10-2 - 340 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,有 chmod 和 fchmod 两个函数。 再看一下相关函数,如下图所示。 版本号:V2.0 日期:2015-10-2 - 341 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着介绍一下 chmod 和 fchmod 的用法。 int chmod(const char *path, mode_t mode); 参数*path:文件路径。 参数 mode:直接使用数字即可。和前面命令中 chmod 777 xxx 中的 777 这个参数含义 类似,也可以使用文档中的组合值。 返回值:成功返回 0,错误返回-1。 int fchmod(int fd, mode_t mode); 参数 fd:文件描述符。 参数:直接使用数字即可。和前面命令中 chmod 777 xxx 中的 777 这个参数含义类似, 也可以使用文档中的组合值。 返回值:成功返回 0,错误返回-1。 版本号:V2.0 日期:2015-10-2 - 342 - www.topeetboard.com 北京迅为电子有限公司 15.5.2chmod 函数例程 iTOP-4412 Linux 系统编程 V2.0 编写简单的 chmod.c 文件测试 chmod 和 fchmod 函数。 首先添加头文件,如下图所示。 main 函数,chmod 函数测试部分,如下图所示。 main 函数,fchmod 函数测试部分,如下图所示。 版本号:V2.0 日期:2015-10-2 - 343 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图代码所示。 第 7 行:通过 main 函数可以传参数,也就是文件的路径,需要传两个路径。 第 11-14 行:检测是否有传入参数。 第 17-22 行:将第一个参数指向的文件的权限修改为 0777。 第 25-30 行:使用 open 函数获取文件句柄。 第 31-36 行:将第二个参数指向的文件的权限修改为 0555。 也可以修改为其它的权限,参数 0777 和 0555 也可以使用组合的宏定义。 15.5.3 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/CatlogFile”,将源码 chmod.c 拷贝进去,进入文件夹 CatlogFile, 如下图所示。 版本号:V2.0 日期:2015-10-2 - 344 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用命令“arm-none-linux-gnueabi-gcc -o chmod chmod.c -static”编译 chmod 文 件,如下图所示,使用命令“ls”可以看到生成了 chmod 可执行文件。 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 将编译成的可执行文件 chmod,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,使用 命令“./mnt/udisk/chmod ./mnt/udisk/stat /mnt/udisk/stat.c”运行程序如下。 版本号:V2.0 日期:2015-10-2 - 345 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,将./mnt/udisk 中的 stat 和 stat.c 文件权限修改,然后使用命令“ls -l”查 看权限,可以看到修改成功。 15.6 目录以及基础知识 在 linux 中,文件目录包含文件名列表,每一个文件名对应一个 inode 编号。 目录中还能包含其它子目录,在 linux 中所有的目录和文件都是以树形结构组织的。 既然是树形结构,那么肯定就有一个根,在 linux 下有一个根 root 目录,如下图所示,使 用命令“cd /”就可以进入 root 目录。 版本号:V2.0 日期:2015-10-2 - 346 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 root 目录指的是根目录。另外有一个 root 用户的概念,一个是目录中的概念,一个是 linux 用户中的概念,不要混淆。 在接下来的小节中会学习到当前工作目录,创建目录,删除目录,读取目录内容等。 15.7 实验-getcwd 函数 在很多情况下都会用到当前目录,linux 命令中,使用 pwd 可以查看到当前目录,本节介 绍如何使用代码获取当前目录。 15.7.1 使用 man 学习 getcwd 函数 如下图所示,使用命令“man 3 getcwd”。 版本号:V2.0 日期:2015-10-2 - 347 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,有三个类似的函数 getcwd,getwd,get_current_dir_name。 接着注意一下相关的函数,如下图所示。 版本号:V2.0 日期:2015-10-2 - 348 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着介绍一下 getcwd、getwd 和 get_current_dir_name 的用法。 char *getcwd(char *buf, size_t size); 参数*buf:保存当前目录的缓冲区。 参数 size:在现代 linux 中,buf 的长度至少可以为 255 字节。 返回值:成功返回指向当前目录的指针,和 buf 的值一样,错误返回 NULL。 char *getwd(char *buf);该函数已经过时,使用的时候会有警告。 参数*buf:保存当前目录的缓冲区。 返回值:成功返回指向当前目录的指针,和 buf 的值一样,错误返回 NULL。 char *get_current_dir_name(void); 参数:无 返回值:成功返回指向当前目录的指针,错误返回 NULL。 版本号:V2.0 日期:2015-10-2 - 349 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 关于这个函数,给大家再介绍一点额外的知识。 打开头文件“/usr/include/unistd.h”,如下图所示。 如下图所示,找到函数定义。 如上图所示,必须定义“__USE_GNU”才能使用 get_current_dir_name 函数。 版本号:V2.0 日期:2015-10-2 - 350 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 另外经过测试发现,getwd 函数,无论定义不定义条件,都会警告这个函数已经过时,虽 然可以使用。 15.7.2getcwd 函数例程 编写简单的 getcwd.c 文件测试 getcwd 函数。 首先添加头文件,如下图所示。 然后是 main 函数,getcwd 函数的测试,如下图所示。 然后 getwd 函数测试和 get_current_dir_name 函数测试 ,如下图所示。 版本号:V2.0 日期:2015-10-2 - 351 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图代码所示。 第 4 行:定义“__USE_GNU”会让 get_current_dir_name 正常使用。 第 13-17 行:使用 getcwd 函数获取当前目录并打印。 第 19-25 行:使用 getwd 函数获取当前目录并打印。 第 27-32 行:使用 get_current_dir_name 函数获取当前目录并打印。 15.7.3 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/CatlogFile”,将源码 getcwd.c 拷贝进去,进入新建的文件夹 CatlogFile,如下图所示。 版本号:V2.0 日期:2015-10-2 - 352 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用命令“arm-none-linux-gnueabi-gcc -o getcwd getcwd.c -static”编译 getwd 文 件,如下图所示,使用命令“ls”可以看到生成了 getcwd 可执行文件。 如上图所示,编译的过程中会有警告,因为 getwd 函数是很老的版本才支持的,提醒程序 员使用新的 getcwd 函数,能够通过则表明暂时不影响使用。 版本号:V2.0 日期:2015-10-2 - 353 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 将编译成的可执行文件 getcwd,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,运行 程序如下。 如上图所示,由于作者运行程序的当前目录是 linux 的“/”,所示显示是“/”。大家可以 在其它目录下运行,看一下效果。 15.8 实验-mkdir 函数 在介绍 linux 命令的时候,介绍过在 linux 终端下使用 mkdir 命令新建目录,本节介绍如 何使用代码新建目录。 版本号:V2.0 日期:2015-10-2 - 354 - www.topeetboard.com 北京迅为电子有限公司 15.8.1 使用 man 学习 mkdir 函数 如下图所示,使用命令“man 2 mkdir”。 iTOP-4412 Linux 系统编程 V2.0 如下图所示,函数 mkdir。 接着注意一下相关的函数,如下图所示。 版本号:V2.0 日期:2015-10-2 - 355 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着介绍一下 mkdir 的用法。 int mkdir(const char *pathname, mode_t mode); 参数:文件路径 参数 mode:直接使用数字即可。和前面命令中 chmod 777 xxx 中的 777 这个参数含义 类似,也可以使用文档中的组合值。 返回值:成功返回 0,错误返回-1。 15.8.2mkdir 函数例程 编写简单的 mkdir.c 文件测试 mkdir 函数。 首先添加头文件,如下图所示。 版本号:V2.0 日期:2015-10-2 - 356 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数如下图所示。 如上图代码所示。 第 10-14 行:检测 main 函数是否有参数传入。 第 15-21 行:使用 mkdir 函数建立新目录,权限是 0777. 版本号:V2.0 日期:2015-10-2 - 357 - www.topeetboard.com 北京迅为电子有限公司 15.8.3 编译运行测试 iTOP-4412 Linux 系统编程 V2.0 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/CatlogFile”,将源码 mkdir.c 拷贝进去,进入文件夹 CatlogFile, 如下图所示。 使用命令“arm-none-linux-gnueabi-gcc -o mkdir mkdir.c -static”编译 mkdir 文件, 如下图所示,使用命令“ls”可以看到生成了 mkdir 可执行文件。 版本号:V2.0 日期:2015-10-2 - 358 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 将编译成的可执行文件 mkdir,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,运行 程序如下。使用命令“ ./mnt/udisk/mkdir /test”表示在当前目录下新建“test”目录。 版本号:V2.0 日期:2015-10-2 - 359 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,接着使用 ls 命令查看,可以发现新建了一个 test 目录。 15.9 实验-rmdir 函数 本节介绍如何使用代码删除目录。 15.9.1 使用 man 学习 rmdir 函数 如下图所示,使用命令“man 2 rmdir”。 版本号:V2.0 日期:2015-10-2 - 360 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,函数 rmdir。 接着注意一下相关的函数,如下图所示。 版本号:V2.0 日期:2015-10-2 - 361 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着介绍一下 rmdir 的用法。 int rmdir(const char *pathname); 参数*pathname:文件和目录的路径。 返回值:成功返回 0,错误返回-1。 15.9.2rmdir 函数例程 编写简单的 rmdir.c 文件测试 rmdir 函数。 首先添加头文件,如下图所示。 然后 main 函数如下图所示。 版本号:V2.0 日期:2015-10-2 - 362 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图代码所示。 第 9-13 行:检测参数是否传入。 第 14-20 行:根据传入的参数 argv[1],使用 rmdir 函数删除目录。 15.9.3 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/CatlogFile”,将源码 rmdir.c 拷贝进去,进入文件夹 CatlogFile, 如下图所示。 版本号:V2.0 日期:2015-10-2 - 363 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用命令“arm-none-linux-gnueabi-gcc -o rmdir rmdir.c -static”编译 rmdir 文件, 如下图所示,使用命令“ls”可以看到生成了 rmdir 可执行文件。 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 将编译成的可执行文件 rmdir,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,使用命 令“./mnt/udisk/rmdir /test/ ”运行程序如下。 版本号:V2.0 日期:2015-10-2 - 364 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,删除的是前面一个实验 mkdir 程序新建的 test 目录,如果再次使用 ls 命令 查看,将会发现这个 test 目录被删除了。 15.10 实验-chdir 函数 本节实验介绍如何使用代码改变当前工作目录。 在实际应用中,代码可能需要从当前目录中进到其它目录,这个时候首先需要使用 getcwd 函数获取当前目录,保存起来,然后使用 chdir 跳到其它目录,完成操作,然后再使用 chdir 回到最初保存的目录。 15.10.1 使用 man 学习 chdir 函数 如下图所示,使用命令“man 2 chdir”。 版本号:V2.0 日期:2015-10-2 - 365 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,有两个类似的函数 chdir,fchdir。 接着注意一下相关的函数,如下图所示。 版本号:V2.0 日期:2015-10-2 - 366 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着介绍一下 chdir 和 fchdir 的用法。 int chdir(const char *path); 参数 *path:文件路径 返回值:成功返回 0,错误返回-1。 int fchdir(int fd); 参数 fd:open 函数返回的句柄,文件描述符。 返回值:成功返回 0,错误返回-1。 15.10.2chdir 函数例程 编写简单的 chdir.c 文件测试 chdir 函数。 首先添加头文件,如下图所示。 版本号:V2.0 日期:2015-10-2 - 367 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数,如下图所示,检测参数,以及使用 getcwd 获得当前目录。 然后 main 函数,如下图所示,转移到其它目录,完成任务。 版本号:V2.0 日期:2015-10-2 - 368 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数,如下图所示,最后再返回前面保存的目录。 如上图代码所示。 第 21-26 行:getcwd 函数用于保存程序运行时候目录。 第 28-34 行:使用 chdir 跳转到的目录“argv[1]”。 第 36-43 行:在目录“argv[1]”下,做一个小操作,将目录“argv[2]”删除掉(前提是 argv[1]目录下必须有 argv[2]目录,运行前新建一个即可) 版本号:V2.0 日期:2015-10-2 - 369 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第 45-51 行:调用 chdir 函数,返回 pwd 保存的目录。 15.10.3 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/CatlogFile”,将源码 chdir.c 拷贝进去,进入文件夹 CatlogFile, 如下图所示。 使用命令“arm-none-linux-gnueabi-gcc -o chdir chdir.c -static”编译 chdir 文件,如 下图所示,使用命令“ls”可以看到生成了 chdir 可执行文件。 版本号:V2.0 日期:2015-10-2 - 370 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 将编译成的可执行文件 chdir,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘。 运行程序前,使用使用命令“mkdir /mnt/test”在/mnt 目录下新建一个 test 目录,如下 图所示,“/mnt”目录将作为一个参数传递给 chdir 程序,另一个参数“/mnt/test”也会传 递过去,这个“/mnt/test”目录将会被删除。 版本号:V2.0 日期:2015-10-2 - 371 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 运行程序如下图所示。 版本号:V2.0 日期:2015-10-2 - 372 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,程序运行之后,再次使用 ls 命令查看,会发现“mnt”目录下的“test”已 经被删除了。 15.11 实验-opendir 和 closedir 函数 前面介绍的 open 函数和 close 函数可以用于读取文件的内容,这里介绍 opendir 和 closedir 用于读取目录的内容,相当于命令中的 ls 命令。 15.11.1 使用 man 学习 opendir 和 closedir 函数 如下图所示,使用命令“man 3 opendir”。 版本号:V2.0 日期:2015-10-2 - 373 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,有两个类似的函数 opendir 和 fdopendir,fdopendir 不是标准的函数,不 建议使用,移植性不太好,这里也直接使用 opendir。 接着注意一下相关的函数,如下图所示。 版本号:V2.0 日期:2015-10-2 - 374 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着介绍一下 opendir、closedir 的用法。 DIR *opendir(const char *name); 参数:目录的路径。 返回值:成功返回指向目录流的指针,错误返回 NULL。 int closedir(DIR *dirp); 参数:opendir 返回的 dir 指针。 返回值:成功返回 0, 失败返回-1. 15.11.2opendir 和 closedir 函数例程 编写简单的 opendir.c 文件测试 opendir 和 closedir 函数。 首先添加头文件,如下图所示。 版本号:V2.0 日期:2015-10-2 - 375 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数如下图所示。 然后 main 函数如下图所示。 如上图代码所示 第 11-15 行:检测 main 参数是否传入。 第 16-22 行:使用 opendir 打开目录。 版本号:V2.0 日期:2015-10-2 - 376 - www.topeetboard.com 北京迅为电子有限公司 第 23-24 行:使用 closedir 关闭目录。 iTOP-4412 Linux 系统编程 V2.0 15.11.3 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/CatlogFile”,将源码 opendir.c 拷贝进去,进入文件夹 CatlogFile,如下图所示。 使用命令“arm-none-linux-gnueabi-gcc -o opendir opendir.c -static”编译 opendir 文件,如下图所示,使用命令“ls”可以看到生成了 opendir 可执行文件。 版本号:V2.0 日期:2015-10-2 - 377 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 将编译成的可执行文件 opendir,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,使 用“./mnt/udisk/opendir /mnt”运行程序如下。 版本号:V2.0 日期:2015-10-2 - 378 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,可以看到在程序中打开了目录“mnt”。 15.12 实验-readdir 函数 15.12.1 使用 man 学习 readdir 函数 如下图所示,使用命令“man 3 readdir”。 版本号:V2.0 日期:2015-10-2 - 379 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,有 readdir 和 readdir_r 两个函数,这里只介绍 readdir。 接着注意一下相关的函数,如下图所示。 版本号:V2.0 日期:2015-10-2 - 380 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 看一下参数的结构体 dirent,如下图所示。 如上图所示,各个参数的解释还是很清楚明了的。 struct dirent *readdir(DIR *dirp); 参数 dirp:opendir 函数打开目录后返回的文件指针。 返回值:成功返回指向 dirp 的指针 dirent ,错误返回 NULL。 版本号:V2.0 日期:2015-10-2 - 381 - www.topeetboard.com 北京迅为电子有限公司 15.12.2readdir 函数例程 编写简单的 readdir.c 文件测试 readdir 函数。 首先添加头文件,如下图所示。 iTOP-4412 Linux 系统编程 V2.0 main 主程序部分代码,如下图所示。 main 主程序部分代码,如下图所示。 版本号:V2.0 日期:2015-10-2 - 382 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图代码所示。 第 11-15 行:检测 main 的参数。 第 16-22 行:获取目录的 dir。 第 23-29 行:使用 readdir 函数读取目录,然后打印文件的 inode。 第 30-31 行:关闭目录。 15.12..3 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/CatlogFile”,将源码 readdir.c 拷贝进去,进入文件夹 CatlogFile, 如下图所示。 版本号:V2.0 日期:2015-10-2 - 383 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用命令“arm-none-linux-gnueabi-gcc -o readdir readdir.c -static”编译 readdir 文 件,如下图所示,使用命令“ls”可以看到生成了 readdir 可执行文件。 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 将编译成的可执行文件 readdir,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,运行 程序如下。 版本号:V2.0 日期:2015-10-2 - 384 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,这里只是读取了文件许多参数中的 d_ino,其它参数用户可以自己写小程序 打印出来。 15.13 链接以及基础知识 本章导读中给大家稍微提了一下的是硬链接,在介绍前面 stat 函数提到过符号链接,不过 这硬链接,符号链接和链接完全不是一回事。 在 linux 中,文件目录包含文件名列表,每一个文件名对应一个 inode 编号。每个文件名 叫目录项,每个名字到 inode 的映射叫链接。 类似 windows 下的快捷方式叫做符号链接和硬链接。虽然有点绕口,但是在 linux 编程的 书籍在最开始就是这么翻译过来的,能够理解就行了。 版本号:V2.0 日期:2015-10-2 - 385 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 前面强调过在 linux 系统中每一个 inode 都是唯一的,但是我们发现,如下图所示,在最 小系统下使用命令“ls -i”,会发现两个相同的 inode。 其实这就是硬链接,硬链接的个数可以是多个。 和硬链接对应的是软链接,也可以叫符号链接或者 symlinks,软连接不是文件系统的文件 名和 inode 的映射,而是一种指针,在运行的时候解释。 前面介绍的 linux 命令中,有 ln 命令可以创建链接,如下图所示,使用“man ln”查看一 下。 版本号:V2.0 日期:2015-10-2 - 386 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,可以看到关于 ln 的功能描述。它是用来创建一个 TARGET 到真实的文件的 link (链接)。这也算是 linux 中一种特殊的文件,就像 windows 下的快捷方式,也属于 window 下的文件。 15.14 实验-硬链接 link 15.14.1 使用 man 学习 link 函数 如下图所示,使用命令“man 2 link”。 版本号:V2.0 日期:2015-10-2 - 387 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,函数 link。 接着注意一下相关的函数,如下图所示。 版本号:V2.0 日期:2015-10-2 - 388 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 最后介绍一下 link 函数。 int link(const char *oldpath, const char *newpath); 参数*oldpath:已有的文件路径。 参数*newpath:新建的硬链接文件路径。 返回值:成功返回 0,错误返回-1。 15.14.2link 函数例程 编写简单的 link.c 文件测试 link 函数。 首先添加头文件,如下图所示。 版本号:V2.0 日期:2015-10-2 - 389 - www.topeetboard.com 北京迅为电子有限公司 main 函数部分代码如,下图所示。 iTOP-4412 Linux 系统编程 V2.0 main 函数部分代码,如下图所示。 如上图代码所示。 第 9-12 行:测试 main 函数传递的参数。 第 14-21 行:使用函数 link,给 argv[1]和 argv[2]建立 link 硬链接。 版本号:V2.0 日期:2015-10-2 - 390 - www.topeetboard.com 北京迅为电子有限公司 15.14.3 编译运行测试 iTOP-4412 Linux 系统编程 V2.0 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/CatlogFile”,将源码 link.c 拷贝进去,进入文件夹 CatlogFile, 如下图所示。 使用命令“arm-none-linux-gnueabi-gcc -o link link.c -static”编译 link 文件,如下图 所示,使用命令“ls”可以看到生成了 link 可执行文件。 版本号:V2.0 日期:2015-10-2 - 391 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 将编译成的可执行文件 link,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘。 如下图所示,使用 vi 编辑器新建一个 linktest.c 文件。 版本号:V2.0 日期:2015-10-2 - 392 - www.topeetboard.com 北京迅为电子有限公司 如下图所示,文件中内容为“hello linux link!” iTOP-4412 Linux 系统编程 V2.0 保存退出。 接着运行程序,如下图所示。 版本号:V2.0 日期:2015-10-2 - 393 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后使用 ls 命令查看,如下图所示。 如上图所示,可以看到硬链接建立的完全一样的文件,inode 是相同的。 版本号:V2.0 日期:2015-10-2 - 394 - www.topeetboard.com 北京迅为电子有限公司 使用 vi 命令打开 linktest,查看其中的内容。 iTOP-4412 Linux 系统编程 V2.0 如下图所示,一模一样。 版本号:V2.0 日期:2015-10-2 - 395 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 15.15 实验-符号链接 symlink 15.15.1 使用 man 学习 symlink 函数 如下图所示,使用命令“man 2 symlink”。 如下图所示,函数 symlink 和 link 函数用法差不多。 版本号:V2.0 日期:2015-10-2 - 396 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着注意一下相关的函数,如下图所示。 接着介绍一下 symlink 的用法。 int symlink(const char *oldpath, const char *newpath); 参数*oldpath:已有的文件路径。 参数*newpath:新建的符号链接文件路径。 版本号:V2.0 日期:2015-10-2 - 397 - www.topeetboard.com 北京迅为电子有限公司 返回值:成功返回 0,错误返回-1。 iTOP-4412 Linux 系统编程 V2.0 15.15.2symlink 函数例程 编写简单的 symlink.c 文件测试 symlink 函数。 首先添加头文件,如下图所示。 main 函数部分代码如下图所示。 main 函数部分代码如下图所示。 版本号:V2.0 日期:2015-10-2 - 398 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图代码所示。 第 9-11 行:测试 main 函数的参数。 第 14-21 行:使用 symlink 函数给 argv[1],argv[2]建立符号连接(软连接)。 15.15.3 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/CatlogFile”,将源码 symlink.c 拷贝进去,进入文件夹 CatlogFile,如下图所示。 版本号:V2.0 日期:2015-10-2 - 399 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用命令“arm-none-linux-gnueabi-gcc -o symlink symlink.c -static”编译 symlink 文件,如下图所示,使用命令“ls”可以看到生成了 symlink 可执行文件。 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 将编译成的可执行文件 symlink,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘。 使用程序给前一个实验中 linktest.c 文件建立软连接,如下图所示。 运行程序如下。 版本号:V2.0 日期:2015-10-2 - 400 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,使用 ls 命令查看新建的软连接文件,可以发现和之前的并不是同一个文件, inode 不一样,说明是不同的文件。 打开之后也是显示同样的内容,如下图所示。 版本号:V2.0 日期:2015-10-2 - 401 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 其中链接到 linktest.c 的软链接文件 symlink.c 之后显示的也是同样的内容。 版本号:V2.0 日期:2015-10-2 - 402 - www.topeetboard.com 北京迅为电子有限公司 15.16 实验-解除链接 unlink 15.16.1 使用 man 学习 unlink 函数 如下图所示,使用命令“ man 2 unlink”。 iTOP-4412 Linux 系统编程 V2.0 如下图所示,函数 unlink。 版本号:V2.0 日期:2015-10-2 - 403 - www.topeetboard.com 北京迅为电子有限公司 接着注意一下相关的函数,如下图所示。 iTOP-4412 Linux 系统编程 V2.0 接着介绍一下 unlinke 的用法。 int unlink(const char *pathname);参数: 参数*pathname:链接文件的路径。 返回值:成功返回 0,错误返回-1。 当 unlink 指向的是软链接,则会删除软链接,不会删除目标文件。 当 unlink 指向的是硬链接,如果,如果是最后一个链接,则就相当于删除了文件。 另外还有一个 remove 函数,可以直接用来删除 path。 如果 path 是目录则 remove 调用 rmdir。 如果 path 是文件则 remove 调用 unlink。 用法很简单,可以自己学习然后写个测试程序。 版本号:V2.0 日期:2015-10-2 - 404 - www.topeetboard.com 北京迅为电子有限公司 15.16.2unlink 函数例程 编写简单的 unlink.c 文件测试 unlink 函数。 首先添加头文件,如下图所示。 iTOP-4412 Linux 系统编程 V2.0 main 函数部分代码,如下图所示。 main 函数部分代码,如下图所示。 版本号:V2.0 日期:2015-10-2 - 405 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图代码所示。 第 9-12 行:测试 main 函数的参数。 第 14-21 行:使用 unlink 函数将 argv[1]文件的软连接或者硬链接取消 15.16.3 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/CatlogFile”,将源码 unlink.c 拷贝进去,进入文件夹 CatlogFile, 如下图所示。 使用命令“arm-none-linux-gnueabi-gcc -o unlink unlink.c -static”编译 unlink 文件, 如下图所示,使用命令“ls”可以看到生成了 unlink 可执行文件。 版本号:V2.0 日期:2015-10-2 - 406 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 将编译成的可执行文件 unlink,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘。 使用命令“./mnt/udisk/unlink symlink.c”运行程序如下所示,这里取消了前一个实验建 立的软连接文件。 版本号:V2.0 日期:2015-10-2 - 407 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着使用 ls 命令查看链接文件,已经消失了。 版本号:V2.0 日期:2015-10-2 - 408 - www.topeetboard.com 北京迅为电子有限公司 15.17 拷贝和移动文件 iTOP-4412 Linux 系统编程 V2.0 文件处理中拷贝和移动文件是最基本的操作。 可以通过 cp 命令和 mv 命令实现。mv 可以理解为“重命名”;cp 拷贝要注意和创建硬 链接区分开来,硬链接的 inode 是相同,它们是同一个文件,但是 cp 拷贝之后,inode 索引 节点是不同的,它们是不同的文件。 15.18 实验-拷贝 15.18.1 拷贝简介 Linux 下并没有专门的拷贝函数和接口,需要通过 open,read,wite 等文件操作函数实 现。 如下图所示,是 linux 下拷贝的流程图。 一般步骤是 open 之后将数据读至内存,然后写入新的文件。 版本号:V2.0 日期:2015-10-2 - 409 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 15.18.2 拷贝例程 编写简单的 cpfile.c 文件完成拷贝功能。 首先添加头文件,如下图所示。 版本号:V2.0 日期:2015-10-2 - 410 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 main 函数部分代码。如下图所示。 main 函数部分代码。如下图所示。 版本号:V2.0 日期:2015-10-2 - 411 - www.topeetboard.com 北京迅为电子有限公司 main 函数部分代码。如下图所示。 iTOP-4412 Linux 系统编程 V2.0 如上图代码所示。 第 17-23 行:将 main 参数传递给 main 内部变量,然后检测参数是否输入。 第 25-39 行:打开新旧文件路径。如果文件 fdt 不存在则新建。 第 41-43 行:从 fds 文件中读取内容,然后写入 fdt 文件中。 第 46-48 行:关闭打开的文件。 第 50-52 行:打印结束信息。 15.18.3 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/CatlogFile”,将源码 cpfile.c 拷贝进去,进入文件夹 CatlogFile, 如下图所示。 版本号:V2.0 日期:2015-10-2 - 412 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用命令“arm-none-linux-gnueabi-gcc -o cpfile cpfile.c -static”编译 cpfile 文件, 如下图所示,使用命令“ls”可以看到生成了 cpfile 可执行文件。 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 将编译成的可执行文件 cpfile,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘。 版本号:V2.0 日期:2015-10-2 - 413 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用命令“./mnt/udisk/cpfile linktest.c cptest ”,运行程序如下图所示,用到了前面 实验建立的 linktest.c 文件。 接着查看一下 cptest 文件,和原来的 linktest.c 不是同一个文件。 版本号:V2.0 日期:2015-10-2 - 414 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 打开复制生成的 cptest 文件,内容没变,如下图所示。 版本号:V2.0 日期:2015-10-2 - 415 - www.topeetboard.com 15.19 实验-移动 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 15.19.1 使用 man 学习 rename 函数 Linux 下移动文件可以使用 rename 实现。 如下图所示,使用命令“man 2 rename”,查看 rename 文档。 如下图所示 rename 函数。 版本号:V2.0 日期:2015-10-2 - 416 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 最后看一下相关的函数,如下图所示。 最后介绍一下 rename 函数。 int rename(const char *oldpath, const char *newpath); 参数*oldpath:旧的文件路径。 参数*newpath:新的文件路径。 版本号:V2.0 日期:2015-10-2 - 417 - www.topeetboard.com 北京迅为电子有限公司 返回值:成功返回 0,错误返回-1。 iTOP-4412 Linux 系统编程 V2.0 15.19.2rename 文件例程 编写简单的 rename.c 文件测试 rename 函数。 首先添加头文件,如下图所示。 main 函数代码,如下图所示。 如上图代码所示。 第 13-16 行:检查 main 函数是否有参数传入。 版本号:V2.0 日期:2015-10-2 - 418 - www.topeetboard.com 北京迅为电子有限公司 第 17-19 行:使用 rename 移动文件。 iTOP-4412 Linux 系统编程 V2.0 15.19.3 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “ /home/linuxsystemcode/CatlogFile/”,将源码 rename.c 拷贝进去,进入文件夹 CatlogFile,如下图所示。 使用命令“arm-none-linux-gnueabi-gcc -o rename rename.c -static”编译 rename 文件,如下图所示,使用命令“ls”可以看到生成了 rename 可执行文件。 版本号:V2.0 日期:2015-10-2 - 419 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 将编译成的可执行文件 rename,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘。 使用命令“./mnt/udisk/rename cptest renametest”,运行程序如下。 版本号:V2.0 日期:2015-10-2 - 420 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着使用 ls 命令查看,有新的 renametest 文件,原来的文件 cptes 消失了。 本章小结 在 linux 中,文件是在太重要了!所以作者写了这么多的小实验程序,帮助大家理解和使 用 linux 中的文件。 其实是在和大家沟通的时候,我发现“很多同学都不习惯使用官方文档”“不去使用英文”。 所以本章在内容上做了更深入的引导,尽管刚开始大家按照这个思路学习不太习惯,不过这是 一条必经之路,现在不折腾自己,将来社会折腾自己的! 当然本章更加重要的是手把手教大家使用 man 去学习各种函数和系统 API,去学会使用文 档。 版本号:V2.0 日期:2015-10-2 - 421 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 还有一项能力就是阅读英文文档!有了这个能力之后,很多事情都会迎刃而解。 “冰冻三尺,非一日之寒”,“革命尚未成功,通知仍需努力”,给大家强调这些基本的 功底,我这里也只能做引导,没法代替大家做读文档,去记单词,大家多多加油,记住“一分 耕耘一分收获”。 版本号:V2.0 日期:2015-10-2 - 422 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第十六章 专题 Linux 的进程 16.1 本章导读 在 linux 中“文件”应该是最重要的抽象概念,从前面给大家准备的例程就可以看出来, 非常的多。 仅次于“文件”的概念就是 linux 进程,16 章节介绍进程的一些基础概念以及简单的小例 程。 16.1.1 工具 16.1.1.1 硬件工具 开发板 PC 机 U 盘或者 TF 卡或者 NFS 16.1.1.2 软件工具 Ubuntu12.04.2 以及虚拟机 Arm-2009q3 编译器 Notepad++编辑器 超级终端 Vim 编辑器 版本号:V2.0 日期:2015-10-2 - 423 - www.topeetboard.com 16.1.2 预备课程 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 基本开发工具的使用 常用 linux 命令 最小 linux 系统 helloworld 16.1.3 视频资源 本章配套视频为: “视频 16_01linux 进程之进程基本概念” “视频 16_02linux 进程之进程 ID” “视频 16_03linux 进程之 exec 函数族” “视频 16_04linux 进程之 fork 创建新进程” “视频 16_05linux 进程之综合例程” 16.2 学习目标 本章需要学习以下内容: 了解进程基本概念 掌握获取进程 id 的方法 掌握函数族 exec 的用法 掌握函数 fork 创建新进程的方法 掌握函数 fork 和 exec 函数族结合应用的方法 版本号:V2.0 日期:2015-10-2 - 424 - www.topeetboard.com 北京迅为电子有限公司 16.3 进程的基本概念 iTOP-4412 Linux 系统编程 V2.0 本节介绍一些基本的概念,以及对大家学习有帮助的一些思想。 16.3.1 嵌入式 linux 和嵌入式单片机最重要区别 相信大多数人学习嵌入式都是从单片机开始学起的,有些单片机教程不严谨,给大家灌输 一些偏颇的概念“单片机和 arm 一样”“学习了单片机编程,操作系统也是一样的”等等。 其实完全不一样! 中间隔了一层操作系统,也就是一层软件,嵌入式 linux 系统很少需要开发者直接对寄存 器操作,即使对寄存器的操作,也是移植,不会让你配置很多的寄存器。这部分可以理解为驱 动移植就是类似对硬件的操作,但是思路完全不一样了。 有了操作系统之后,那么就提供了很多直接调用的软件资源,操作系统中的很多资源和硬 件完全无关~如果非要较劲,软件也是在硬件上跑的,那也没有办法,你就只能自己琢磨去了, 帮不了你了~更好的理解是,操作系统提供了很多现成的资源,例如本章要介绍的进程,这个 是在单片机上完全接触不到的东西,如果在单片机上跑多个程序,不知道多麻烦,但是有了操 作系统,简单的几个接口和函数调用就可以实现。 从单片机过来的学习者,经常“犯浑”,“我一定要都搞明白”,“你的系统从什么地方 开始运行的”“申请内存是怎么实现的”,如果把操作系统类比为一辆车,那么我们其实就是 个开车的!最多偶尔修一下车,再多的也做不了了。 那么谁是造车的?我想造车呢?举个例子吧,arm 公司招 linux 程序员,基本工作年限是 8 年以上!大家刚刚开始学习嵌入式操作系统,人家造车的工作,最基本的是 8 年 linux 工作经 验,那是另外一个长远的目标了,我们的实验教程也不可能把大家的水平教的那么高。大家的 版本号:V2.0 日期:2015-10-2 - 425 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 目标就是从事 linux 编程工作,linux 编程的工作内容主要包括应用和驱动移植,其实就是开车 的! 16.3.2 几个基本概念 程序,前面给大家跑的例程就是程序,科学的定义就是编译过的,可执行的二进制代码, 这个很好理解。如果程序很大,可以叫做应用,实验教程中介绍的例程,这里提到的程序以及 应用都是类似的概念。 进程是指正在运行的程序,一个程序中可以包含多个进程;一个进程可能包含一个或者多 个线程。 如下图所示,使用命令“top”。 接着看一下 x86-Ubuntu 系统的,下面的 pid 会不时的刷新变化。 版本号:V2.0 日期:2015-10-2 - 426 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,是开发板最小系统的进程。 16.4 实验-进程 ID 16.4.1 进程 id 基本概念 每一个进程都有一个唯一的标识符,进程 ID 简称 pid。 版本号:V2.0 日期:2015-10-2 - 427 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 进程的 ID 在一个固定的时刻是唯一的,需要注意的是,假如你在 s 秒的时候有一个进程 ID 是 1000,在另外一个时刻 s+n,另一个进程 ID 也有可能是 1000。 另外内核运行的第一个进程是 1,也就是内核的 init 程序,这个是唯一的。 进程 id 一般默认的最大值为 32768,不过也是可以修改的,当然一般情况下不需要这么做。 如果当前进程是 1000,那么下一个分配的进程就是 1001,它是严格线性分配的。直到 pid 到 了最大值,才重新分配已经用过的进程 ID,当然这些进程都是已经死亡的进程。 除了 init 进程,其它进程都是由其它进程创立的。创立新进程的进程叫父进程,新进程叫 子进程。 16.4.2 使用 man 学习 getpid 和 getppid 如下图所示,使用命令“man 2 getpid”。 版本号:V2.0 日期:2015-10-2 - 428 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,有两个类似的函数 getpid 和 getppid。 接着注意一下相关的函数,如下图所示,下面红框中的函数部分会在教程中介绍。 接着介绍一下 getpid 和 getppid 的用法。 pid_t getpid(void); 参数:无。 版本号:V2.0 日期:2015-10-2 - 429 - www.topeetboard.com 北京迅为电子有限公司 返回值:成功返回进程号。 iTOP-4412 Linux 系统编程 V2.0 pid_t getppid(void); 参数:无。 返回值:成功返回父进程。 16.4.3 例程 编写简单的 getpid.c 文件测试 getpid 和 getppid 函数。 首先添加头文件,如下图所示。 然后 main 函数如下图所示。 版本号:V2.0 日期:2015-10-2 - 430 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图代码所示。 第 10-12 行:获取子进程,没有则为 0。 第 13-16 行:获取父进程,前面提到过除了内核中 init 进程,其它进程都有父进程。 16.4.4 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录“/home/linuxsystemcode”, 使用命令“mkdir pid”新建 pid 文件夹,将源码 getpid.c 拷贝进去,进入新建的文件夹 pid, 如下图所示。 使用命令“arm-none-linux-gnueabi-gcc -o getpid getpid.c -static”编译 getpid 文 件,如下图所示,使用命令“ls”可以看到生成了 getpid 可执行文件。 版本号:V2.0 日期:2015-10-2 - 431 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等。 将编译成的可执行文件 getpid,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,运行 程序如下。 如上图所示,pid927 是当前程序的进程号,pid1209 是当前进程的父进程。 版本号:V2.0 日期:2015-10-2 - 432 - www.topeetboard.com 北京迅为电子有限公司 小贴士-如何查看当前程序的进程 iTOP-4412 Linux 系统编程 V2.0 Linux 中有进程配套的命令 ps 个 kill,可以查看和终止进程。 如下图所示,ps 命令查看进程号。 如果是一个循环程序,执行到 while(1),运行的时候可以在执行命令后面添加&,后台运行, 然后使用 ps 查询 id 号,使用 kill 命令结束进程。 16.5 执行新程序-exec 函数族一 在学习创建进程之前,先来学习一下 linux 中重要的 exec 函数族。在 linux 中,exec 函数 族是把程序直接载入内存,而不是在一个程序中运行多个进程。 版本号:V2.0 日期:2015-10-2 - 433 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,最简单直白的解释就是 exec 函数族调用成功之后,会在内存中执行一个新的 程序。在 linux 中要运行多任务需要使用 exec 函数族和 fork 进程(下一小节的内容)。 16.5.1 使用 man 学习 exec 函数 如下图所示,使用命令“man 3 exec”。 版本号:V2.0 日期:2015-10-2 - 434 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,有六个类似的函数 execl, execlp, execle, execv, execvp, execvpe 。 接着注意一下相关的函数,如下图所示。其中 fork 进程调用函数也是非常重要的,将在下 一小节介绍。 版本号:V2.0 日期:2015-10-2 - 435 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 exec 函数族比较多,但是却很容易记忆和区分的,下面给大家总结一下它们的区别。 如上图所示,首先函数族都是以 exec+xx 的方式命名的。 “l”和“v”表示参数是以列表还是以数组的方式提供的。 “p”表示这个函数的第一个参数是*path,就是以绝对路径来提供程序的路径,也可以以 当前目录作为目标。 版本号:V2.0 日期:2015-10-2 - 436 - www.topeetboard.com 北京迅为电子有限公司 “e”表示为程序提供新的环境变量。 15.2exec 函数族例程 编写简单的 exec.c 文件测试 exec 函数。 首先添加头文件,如下图所示。 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数如下图所示。 如上图代码所示。 第 1-4 行:头文件 第 8-12 行:使用 execl 函数执行“/mnt/udisk/”目录下的 helloexec 程序,传递参数 helloexec 和 execl。 第 13-15 行:运行成功则不会执行,不正常则打印 execl error!。 版本号:V2.0 日期:2015-10-2 - 437 - www.topeetboard.com 北京迅为电子有限公司 接着编写简单的 helloexec.c 文件,如下图所示。 iTOP-4412 Linux 系统编程 V2.0 如上图所示,main 函数的第二个参数传递进入之后,argv[1]将被打印出来,如果正常执 行则会打印“Hello execl!”。 5.4.3 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录“/home/linuxsystemcode”, 使用命令“mkdir exe”新建 exe 文件夹,将源码 execl.c 和 helloexec.c 拷贝进去,进入新建 的文件夹 exe,如下图所示。 版本号:V2.0 日期:2015-10-2 - 438 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用命令“arm-none-linux-gnueabi-gcc -o execl execl.c -static”和 “arm-none-linux-gnueabi-gcc -o helloexec helloexec.c -static”编译 execl 和 helloexec 文件,如下图所示,使用命令“ls”可以看到生成了 helloexec 和 execl 可执行文件。 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 将编译成的可执行文件 execl 和 helloexec,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,运行程序如下。 版本号:V2.0 日期:2015-10-2 - 439 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,可以看到执行了 helloexec 的打印函数,调用成功。 16.6 实验-fork 创建新进程 在 linux 中可以使用 fork 创建和当前进程一样的进程,新的进程叫子进程,原来的进程叫 父进程。 16.5.1 使用 man 学习 fork 进程 如下图所示,使用命令“man 2 fork”。 版本号:V2.0 日期:2015-10-2 - 440 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,函数 fork。 接着注意一下相关的函数,如下图所示。 版本号:V2.0 日期:2015-10-2 - 441 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着介绍一下 fork 的用法。 pid_t fork(void); 参数:无 返回值:执行成功,子进程 pid 返回给父进程,0 返回给子进程;出现错误-1,返回给父 进程。执行失败的唯一情况是内存不够或者 id 号用尽,不过这种情况几乎很少发生。 进程函数 fork 的返回值 系统函数 fork 调用成功,会创建一个新的进程,它几乎会调用差不多完全一样的 fork 进 程。 子进程的 pid 和父进程不一样,是新分配的。 子进程的 ppid 会设置为父进程的 pid,也就是说子进程和父进程各自的“父进程”不一样。 子进程中的资源统计信息会清零。 挂起的信号会被清除,也不会被继承(后面章节进程通信中会介绍信号)。 版本号:V2.0 日期:2015-10-2 - 442 - www.topeetboard.com 北京迅为电子有限公司 所有文件锁也不会被子进程继承。 iTOP-4412 Linux 系统编程 V2.0 这里有一个很难理解的地方是,fork 函数的返回值问题。 fork 函数执行成功,子进程 pid 返回给父进程,0 返回给子进程; 出现错误-1,返回给父进程。执行失败的唯一情况是内存不够或者 id 号用尽,不过这种 情况几乎很少发生。 16.5.2 函数例程 编写简单的 fork.c 文件测试 fork 函数。 首先添加头文件,如下图所示。 main 函数,部分代码如下图所示。 main 函数,如下图所示。 版本号:V2.0 日期:2015-10-2 - 443 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图代码所示。 第 1-4 行:头文件。 第 6-9 行:定义变量。 第 10-27 行:调用 fork 函数。如果出错返回-1,打印 fork failed!;如果成功,则给父进 程返回子进程号,同时给子进程返回父进程号。 16.5.3 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/exe”,将源码 fork.c 拷贝进去,如下图所示。 版本号:V2.0 日期:2015-10-2 - 444 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用命令“arm-none-linux-gnueabi-gcc -o fork fork.c -static”编译 fork 文件,如下 图所示,使用命令“ls”可以看到生成了 fork 可执行文件。 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 将编译成的可执行文件 fork,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,运行程 序如下。 版本号:V2.0 日期:2015-10-2 - 445 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,可以看到打印的父进程和子进程号,然后其中打印的 i 都是一样的。子进程 可以使用父进程中定义的变量,和父进程中的变量却是不同的变量。 15.4 关于如何理解进程的调用 我也想过很多办法,如何介绍可以让更多的用户去理解进程到底是怎么回事。不过怎样努 力,始终有一部分人无法理解。 网上关于进程这部分的博文,也有很多人提出疑问,如下图所示。 版本号:V2.0 日期:2015-10-2 - 446 - www.topeetboard.com 北京迅为电子有限公司 还有类似下面疑惑。 iTOP-4412 Linux 系统编程 V2.0 其实在介绍很多知识点的时候,用单片机或者裸机的概念去理解都是没有太多问题的,但 是到了这里,很容易出现一些无法理解的情况。 这就是单片机以及裸机思维带的后遗症,很多人单片机玩的转,编写操作系统的程序就出 问题。假如实在接受不了各种各样的解释,什么内存分配,什么资源分配,什么共享存储数据, 什么共享代码……这些你都觉得无法理解,那么你就把这个 fork 函数以及 vfork 函数当做一个 工具。 你要将钉子打进木头里,需要锤子;你想要一个程序里面执行多个任务,那么就使用 fork 函数。先知道怎么调用,函数用着用着,即使不理解,也不影响开发,不影响我们写代码,我 们毕竟是工程师程序员,不是计算机科学家,把东西做出来实现出来即可。 唯一不能接受的就是用裸机的思维方式去理解和分析操作系统,在技术支持的过程中,怎 么解释都无济于事,不起任何作用。就像科幻小说《三体》中的描述的,低纬度是无法理解高 维度的。那么,我就直接告诉你,在高纬度中我们通过这种工具来实现这种功能,先模仿,在 学习理解,将自己置于高维度的状态,做高维度的事情,慢慢领会高维度。 16.6 进程终止 exit 这个函数大家肯定已经用过很多次了,就是 exit,在 main 函数的结尾会使用 return 或者 exit 结束程序。当使用 exit 的时候,就是使用的进程终止函数 exit。 版本号:V2.0 日期:2015-10-2 - 447 - www.topeetboard.com 北京迅为电子有限公司 16.6.1 使用 man 学习 exit 函数 如下图所示,使用命令“man 2 exit”。 iTOP-4412 Linux 系统编程 V2.0 如下图所示,有一些相关的函数 execve(2), exit_group(2), fork(2), kill(2), wait(2)等等。 接着介绍一下 void exit(int status)的用法。 版本号:V2.0 日期:2015-10-2 - 448 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 void exit(int status) 参数:返回给父进程的参数。 返回值:无。 函数_exit 和 exit 没什么区别,不需要花太多时间去追究。 创建进程还有一个 vfork 函数,感兴趣的可以通过网络找个例子实现以下,vfork 的使用会 产生很多新问题,使用 vfork 创建的进程结束需要调用_exit。 小贴士:linux 命令的本质 在这一段时间的学习中,linux 命令大家肯定用的比较熟练了,不会再有陌生的感觉了。 其实这些命令都是一些小程序,大家感兴趣也可以看看这些小程序的源码。 exec 函数族可以执行新程序,那么肯定也能运行这些“linux 命令”小程序。 16.7 exec 函数族+fork 进程+linux 命令+linux 时间函数例程 有了 exec 函数族基础知识,为了加深大家对 linux 命令和 exec 函数族的理解,结合起来 给大家提供一个小例程。 16.7.1 例程 编写简单的 execls.c 文件。 首先添加头文件,如下图所示。 版本号:V2.0 日期:2015-10-2 - 449 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 main 函数部分代码,如下图所示。 main 函数部分代码,如下图所示。 main 函数部分代码,如下图所示。 版本号:V2.0 日期:2015-10-2 - 450 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 main 函数部分代码,如下图所示。 main 函数部分代码,如下图所示。 版本号:V2.0 日期:2015-10-2 - 451 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图代码所示。 第 1-5 行:头文件 第 6-76 行:分别使用 exec 函数族实现运行 ls 命令的功能 16.7.2 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/exe”,将源码 execls.c 拷贝进去,进入新建的文件夹 exe,如下 图所示。 版本号:V2.0 日期:2015-10-2 - 452 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用命令“arm-none-linux-gnueabi-gcc -o execls execls.c -static”编译 execls 文件, 如下图所示,使用命令“ls”可以看到生成了 open 可执行文件。 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 将编译成的可执行文件 execls,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,运行 程序如下。 版本号:V2.0 日期:2015-10-2 - 453 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 先把 execls 文件拷贝到当前目录下,使用 ls 命令,查看当前目录,便于和后面执行程序之 后对比。 运行后部分结果如下图所示。 版本号:V2.0 日期:2015-10-2 - 454 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,可以和前面执行 ls 命令之后对比。 版本号:V2.0 日期:2015-10-2 - 455 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第十七章 专题 实战 Linux 进程间通信 17.1 本章导读 进程间通信在实际项目中多多少少都会使用到,本章介绍最常用的无名管道,有名管道, 消息队列,信号,信号量,共享内存等进程间的通信方式。其实后面网络通信套字节 socket 的方式也可以归为进程通行。 这些进程通信相关概念和手段在 linux 驱动中也会用到,虽然在驱动中稍微有一点点不同, 名称不同,接口函数略微不一样,但是思想和手段都是差不多。 希望大家能够好好掌握和理解本章知识,实验本身的难度不大,因为已经有了详细的代码 注释,详细的过程分析。但是还有一些理论的知识,在实验手册中介绍到的不太多,大家可以 通过使用网络去看一些纯理论的东西,这个有助于理论知识的提高,会有助于后面的自学。 17.1.1 工具 17.1.1.1 硬件工具 开发板 PC 机 U 盘或者 TF 卡或者 NFS 17.1.1.2 软件工具 Ubuntu12.04.2 以及虚拟机 Arm-2009q3 编译器 版本号:V2.0 日期:2015-10-2 - 456 - www.topeetboard.com 北京迅为电子有限公司 Notepad++编辑器 超级终端 Vim 编辑器 17.1.2 预备课程 基本开发工具的使用 常用 linux 命令 最小 linux 系统 helloworld Linux 的进程 17.1.3 视频资源 本章配套视频为: “视频 17_01 进程通信之无名管道” “视频 17_02 进程通信之有名管道” “视频 17_03 进程通信之消息队列” “视频 17_04 进程通信之信号” “视频 17_05 进程通信之信号量” “视频 17_06 进程通信之共享内存” iTOP-4412 Linux 系统编程 V2.0 版本号:V2.0 日期:2015-10-2 - 457 - www.topeetboard.com 17.2 学习目标 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 本章需要学习以下内容: 掌握无名管道 pipe 的编程 掌握有名管道 fifo 的编程 掌握消息队列的编程 掌握信号的编程 掌握信号量的编程 掌握共享内存的编程 17.3 无名管道 pipe 从 UNIX 系统开始,无名管道的通信方式就存在,有点类似硬件中的串口,从最初的设计 者定型之后,这种模型就一直延续到今天,说明无名管道当初设计的就极具科学性。 不过无名管道有一定的局限性。 第一:它是属于半双工的通信方式; 第二:只有具有“亲缘关系”的的进程才能使用这种通信方式,也就是父进程和子进程之 间。 17.3.1 使用 man 学习 pipe 函数 无名管道通信首先需要使用 pipe 函数创建管道之后,两个进程之间才能通信。 如下图所示,使用命令“man 2 pipe”。 版本号:V2.0 日期:2015-10-2 - 458 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,有两个类似的函数 pipe,pipe2。这里再次提醒一句,教程中有些函数并没 有介绍到,作者对这些接口的介绍,有一个挑选的原则,如果标准 C 能够支持,那么肯定是介 绍标准 C,因为学习之后在任何系统中都可以使用,移植也方便,然后就是 GNU 的高级版本 支持的,最后尽量不会介绍淘汰的接口和函数。 接着看一下相关的函数,如下图所示。 版本号:V2.0 日期:2015-10-2 - 459 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着介绍一下 pipe 函数。 int pipe(int pipefd[2]) 参数 pipefd[0]:用于读管道。 参数 pipefd[1]:用于写管道。 返回值:执行成功返回 0,失败返回-1。 如果觉得管道难于理解,可以看一下对 pipe 的描述。 版本号:V2.0 日期:2015-10-2 - 460 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如果看了这段描述之后,还是难于理解,可以使用“man 7 pipe”,里面有更多的介绍, 如下图所示。 对于这种难度较大的接口,文档中还会提供例程,如下图所示,这个是“man 2 pipe”下 的。 版本号:V2.0 日期:2015-10-2 - 461 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,经典的例程,大家也可以尝试编译运行一下。 17.3.2pipe 函数例程 编写简单的 pipe.c 文件测试 pipe 函数。 首先添加头文件和定义读函数和写函数,如下图所示。 然后 main 函数如下图所示。 版本号:V2.0 日期:2015-10-2 - 462 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,进程读函数。 版本号:V2.0 日期:2015-10-2 - 463 - www.topeetboard.com 北京迅为电子有限公司 如下图所示,进程写函数。 iTOP-4412 Linux 系统编程 V2.0 如上图代码所示。 第 1-11 行:头文件以及定义读函数和写函数。 第 17-21 行:创建管道,两个进程通过这个管道通信。 第 23-33 行:在父进程和子进程分别调用读函数和写函数,使用管道来通信。 第 37-52 行:读函数,从管道读取数据,然后使用函数 putchar 打印。 第 54-73 行:写函数,从终端输入数据,然后将数据写入管道。 版本号:V2.0 日期:2015-10-2 - 464 - www.topeetboard.com 北京迅为电子有限公司 17.3.3 编译运行测试 iTOP-4412 Linux 系统编程 V2.0 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录“/home/linuxsystemcode”, 使用命令“mkdir pc”新建 pc 文件夹,将源码 pipe.c 拷贝进去,进入新建的文件夹 pc,如下 图所示。 使用命令“arm-none-linux-gnueabi-gcc -o pipe pipe.c -static”编译 open 文件,如 下图所示,使用命令“ls”可以看到生成了 pipe 可执行文件。 版本号:V2.0 日期:2015-10-2 - 465 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 将编译成的可执行文件 pipe,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,使用命 令“./mnt/udisk/pipe”运行程序如下。 版本号:V2.0 日期:2015-10-2 - 466 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,运行之后,getchar 函数会接收从超级终端中输入的字符,接收的函数 getchar 在 write_data 函数中,属于 17.4 有名管道 fifo 无名管道只能用于有亲缘进程之间的通信,有名管道可以实现无亲缘关系的通信。 有名管道 fifo 给文件系统提供一个路径,这个路径和管道关联,只要知道这个管道路径, 就可以进行文件访问,fifo 是指先进先出,也就是先写入的数据,先读出来。 17.4.1 使用 man 学习 mkfifo 函数 如下图所示,使用命令“man 3 mkfifo”。 版本号:V2.0 日期:2015-10-2 - 467 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,mkfifo 函数。 接着注意一下相关的函数,如下图所示,可以发现下面的相关函数大多数都已经学习过了。 版本号:V2.0 日期:2015-10-2 - 468 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着介绍一下 mkfifo 的用法。 int mkfifo(const char *pathname, mode_t mode); 参数*pathname:路径名,管道名称。 参数 mode:管道的权限。 返回值:成功返回 0,错误返回-1。 17.4.2mkfifo 函数例程 编写简单的 creatc.c 文件测试 mkfifo 函数。 首先添加头文件,如下图所示。 版本号:V2.0 日期:2015-10-2 - 469 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 creatc.c 文件的 main 函数如下图所示。 接着看一下 filecopy 函数。 版本号:V2.0 日期:2015-10-2 - 470 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图代码所示。 第 1-9 行:头文件,定义 filecopy 函数。 第 19-23 行:打开文件 file1,如果没有则新建。调用 filecopy 函数。 第 32-43 行:调用 filecopy 将数据写入 file1 文件中。 编写简单的 readpipe.c 文件测试对有名管道的读。 首先看一下头文件,如下图所示。 版本号:V2.0 日期:2015-10-2 - 471 - www.topeetboard.com 北京迅为电子有限公司 接着看一下 main 函数,如下图所示。 iTOP-4412 Linux 系统编程 V2.0 函数 main 的剩余部分,如下图所示。 函数 main 的剩余部分,如下图所示。 版本号:V2.0 日期:2015-10-2 - 472 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 函数 main 的剩余部分,如下图所示。 如上图代码所示。 第 1-9 行:头文件。 第 17 行:PIPE_BUF 是固定值,在系统中固定的。 第 21 行:使用 memset 清空 buffer,为传递数据做准备。 第 30-43 行:读取 FIFO 中的数据,并把它保存在文件 DataFormFIFO.txt 文件中 版本号:V2.0 日期:2015-10-2 - 473 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 编写简单的 writepipe.c 文件测试对有名管道的写。 首先添加头文件,如下图所示。 然后 main 函数如下图所示。 然后 main 函数剩余部分,如下图所示。 版本号:V2.0 日期:2015-10-2 - 474 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图代码所示。 第 1-9 行:头文件。 第 21-31 行:如果管道不存在则新建有名管道。 第 34-36 行:以阻塞方式打开 FIFO 文件,以只读的方式打开数据文件。 第 39-63 行:读取文件之后,像管道中写入数据。 17.4.3 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/pc”,将源码 creatc.c,readpipe.c,writepipe.c 拷贝进去,如 下图所示。 版本号:V2.0 日期:2015-10-2 - 475 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用命令 “arm-none-linux-gnueabi-gcc -o creatc creatc.c -static”编译 creatc 文件, “arm-none-linux-gnueabi-gcc -o readpipe readpipe.c -static”编译 readpipe 文件, “arm-none-linux-gnueabi-gcc -o writepipe writepipe.c -static”编译 writepipe 文 件, 如下图所示,使用命令“ls”可以看到生成了 creatc,readpipe,writepipe 可执行文件。 版本号:V2.0 日期:2015-10-2 - 476 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等。 将编译成的可执行文件 creatc,readpipe,writepipe,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,运行程序如下。先使用“./mnt/udisk/creatc ”命令,创建文本文件。 版本号:V2.0 日期:2015-10-2 - 477 - www.topeetboard.com 北京迅为电子有限公司 如下图所示,多了 data.txt 文本。 iTOP-4412 Linux 系统编程 V2.0 接着看一下新建的 data.txt 文件,其实是重复的“I want to study Linux!”。 版本号:V2.0 日期:2015-10-2 - 478 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示,其中有 100000 行,管道一次传输不了这么多数据。 退出如上图所示的 vi 文本编辑器,使用命令“./mnt/udisk/writepipe &”后台运行管道 写的程序 writepipe。 接着如下图所示,使用 linux 命令“jobs”查看程序是否在运行。 版本号:V2.0 日期:2015-10-2 - 479 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着 5 秒延时看看这个 writepipe 是不是执行完了,使用 linux 命令“jobs;sleep 5;jobs”。 运行中需要等待 5 秒,如下图所示。 如上图所示,5 秒之后这个程序仍然在执行,说明是阻塞在管道写哪里,没有读就处于阻 塞状态。如下图所示,可以看到 my_fifo 管道被创立了。 版本号:V2.0 日期:2015-10-2 - 480 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着使用命令“time ./mnt/udisk/readpipe”运行并计时从管道读数据需要多长时间。 如上图所示,可以看到一共花费时间 0.26 秒。 接着使用命令“jobs”,写程序已经结束。 接着使用命令“ls -la”,如下图所示,可以看到通过 FIFO 管道的数据大小为 2.3M。 版本号:V2.0 日期:2015-10-2 - 481 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 结合整个运行过程,2.3M 除于 0.26S,接近 10M/s。可见通过有名管道实现进程的通信 速度非常快。 17.5 消息队列 msg 消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优 先级。对消息队列有写权限的进程可以向其中按照一定的规则添加新消息;对消息队列有读权 限的进程则可以从消息队列中读走消息。 17.5.1 使用 man 学习 msgget 等函数 消息队列主要有两个函数 msgrcv 和 msgsnd,一个接收一个发送。 使用命令“man 2 msgrcv”,如下图所示。 版本号:V2.0 日期:2015-10-2 - 482 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着看一下相关函数,如下图所示。 分析一下 msgrcv 和 msgsnd 函数。 函数 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); 参数 msqid:消息队列的标识码。 版本号:V2.0 日期:2015-10-2 - 483 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 参数*msgp:指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息,是一个用 户可定义的通用结构。 参数 msgsz:消息的长短。 参数 msgflg:标志位。 返回值:成功返回 0,错误返回-1。 函数 ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg); 参数 msqid:消息队列的标识码。 参数*msgp:指向消息缓冲区的指针。 参数 msgsz:消息的长短 参数 msgflg:标志位。 返回值:成功返回数据长度,错误返回-1。 结构体 msgp,是一个标准的通用结构,如下所示。 struct msgstru{ long mtype; //大于 0 char mtext[nbyte]; }; 还有一个函数 msgget 需要介绍,用来获取与某个键“key”关联的消息队列标识。 函数 int msgget(key_t key, int msgflg): 版本号:V2.0 日期:2015-10-2 - 484 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 参数“key”:消息队列关联的键。 参数“msgflg”:消息队列的建立标志和存取权限。IPC_CREAT 如果内核中没有此队列, 则创建它;IPC_EXCL 当和 IPC_CREAT 一起使用时,如果队列已经存在,则失败。 返回值:执行成功则返回消息队列的标识符,否则返回-1。 17.5.2msgget 函数例程 编写简单的 msgsend.c 和 msgreceive.c 文件实现消息队列。 文件 msgsend.c,首先添加头文件,如下图所示。 然后 main 函数部分代码,如下图所示。 版本号:V2.0 日期:2015-10-2 - 485 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数部分代码,如下图所示。 如上图代码所示。 第 1-12 行:头文件,以及定义 msg_st 结构。 第 22-28 行:使用函数 msgget 建立消息队列。 第 30-48 行:向消息队列汇总输入数据,直到写入 end 结束。 版本号:V2.0 日期:2015-10-2 - 486 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 文件 msgreceive.c,首先添加头文件,如下图所示。 然后 main 函数部分代码,如下图所示。 然后 main 函数部分代码,如下图所示。 版本号:V2.0 日期:2015-10-2 - 487 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图代码所示。 第 1-13 行:头文件,定义 msg_st 结构。 第 23-29 行:建立消息队列。 第 30-42 行:从队列中获取消息,直到遇到 end 消息为止。 第 43-48 行:接收完毕之后,删除队列。 17.5.3 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/pc”,将源码 msgsend.c 和 msgreceive.c 拷贝进去,如下图所 示。 版本号:V2.0 日期:2015-10-2 - 488 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用命令 “arm-none-linux-gnueabi-gcc -o msgsend msgsend.c -static”编译 msgsend 文件, “arm-none-linux-gnueabi-gcc -o msgreceive msgreceive.c -static”编译 msgreceive 文件, 如下图所示,使用命令“ls”可以看到生成了 msgsend 和 msgreceive 可执行文件。 版本号:V2.0 日期:2015-10-2 - 489 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 将编译成的可执行文件 msgsend 和 msgreceive,拷贝到 U 盘,启动开发板,插入 U 盘, 加载 U 盘,运行程序如下。 先在后台运行接收程序 msgreceive,如下图所示。 接着运行发送程序 msgsend,如下图所示。 版本号:V2.0 日期:2015-10-2 - 490 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,运行发送程序,提醒用户输入字符。输入除 end 以外其他任意字符串,都会 接着提示继续输入,最后输入 end,两个程序都结束。 接着使用命令“jobs”,如下图所示,程序已经结束。 版本号:V2.0 日期:2015-10-2 - 491 - www.topeetboard.com 17.6 信号 signal 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 信号用于处理异步事件,信号的通信方式理解起来还是有一定难度的。它既可以在一个进 程内进行通信,发送信号给进程,又可以用于不同进程间的通信。 信号在驱动中应用比较广泛,在应用中用到的多半是一些 linux 命令操作。 17.6.1 使用 man 学习 signal 等函数 函数 alarm,使用命令“man 2 alarm”如下图所示。 看一下相关函数,如下图所示。 版本号:V2.0 日期:2015-10-2 - 492 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 函数 signal,使用命令“man 2 signal”,如下图所示。 看一下相关函数,如下图所示。 版本号:V2.0 日期:2015-10-2 - 493 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着介绍一下 alarm 和 signal 的用法。 unsigned int alarm(unsigned int seconds); 参数 seconds:闹钟的时间,单位为秒。 返回值:成功返回 0 或者返回剩余时间;错误返回-1。 sighandler_t signal(int signum, sighandler_t handler); 参数 signum:等待的信号。 参数 handler:信号到来之后,触发的处理方式。 返回值:成功返回 0,错误返回-1。 17.6.2signal 例程 1 编写简单的 sig_hello.c 文件测试信号函数 signal 以及闹钟 alarm 函数。 首先添加头文件以及定义信号产生之后的操作,如下图所示。 版本号:V2.0 日期:2015-10-2 - 494 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数如下图所示。 如上图代码所示。 第 1-9 行:头文件以及信号产生之后的操作函数 handler。 第 13-14 行:让系统做好准备,接收到信号,就执行 handler;设置闹钟。 第 16-19 行:延时,直到闹钟信号发出。 版本号:V2.0 日期:2015-10-2 - 495 - www.topeetboard.com 北京迅为电子有限公司 17.6.3 编译运行测试 iTOP-4412 Linux 系统编程 V2.0 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/pc”,将源码 sig_hello.c 拷贝进去,如下图所示。 使用命令“arm-none-linux-gnueabi-gcc -o sig_hello sig_hello.c -static”编译 sig_hello 文件,如下图所示,使用命令“ls”可以看到生成了 sig_hello 可执行文件。 版本号:V2.0 日期:2015-10-2 - 496 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 将编译成的可执行文件 sig_hello,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,使 用命令“./mnt/udisk/sig_hello”运行程序如下。 17.6.4signal 例程 2 除了闹钟可以产生信号之外,在终端输入“Ctrl+c”也会产生信号。 编写简单的 sigset.c 文件测试终端产生的信号。 首先添加头文件,如下图所示。 然后 main 函数如下图所示。 版本号:V2.0 日期:2015-10-2 - 497 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数如下图所示。 版本号:V2.0 日期:2015-10-2 - 498 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数如下图所示。 如上图代码所示。 第 1-10 行:头文件以及信号产生之后的操作函数 handler。 第 18-31 行:初始化信号集,然后挂起将程序挂起,等待信号。 第 33-51 行:提示用户 10 秒内输入 Ctrl+c,产生信号,然后取消对信号的屏蔽。 第 52-55 行:延时 5 秒之后退出。 17.6.5 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/pc”,将源码 sigset.c 拷贝进去,如下图所示。 版本号:V2.0 日期:2015-10-2 - 499 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用命令“arm-none-linux-gnueabi-gcc -o sigset sigset.c -static”编译 sigset 文件, 如下图所示,使用命令“ls”可以看到生成了 sigset 可执行文件。 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等。 将编译成的可执行文件 sigset,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,使用 命令“./mnt/udisk/sigset”运行程序如下。 版本号:V2.0 日期:2015-10-2 - 500 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如上图所示, 打印“Wait the signal SIGINT...”之后,输入“Ctrl+c”。 打印“Please press Ctrl+c in 10 seconds...”之后再输入“Ctrl+c”。 17.7 信号量 Semaphore 前面介绍的进程通信方式中,有一个问题,就是可能有其它多个进程访问同一个资源,为 了提供一种排他性的通信,使用信号量可以解决这个问题。 17.6.1 使用 man 学习 semget 等函数 如下图所示,使用命令“man 2 semget”。 版本号:V2.0 日期:2015-10-2 - 501 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接着注意一下相关的函数,如下图所示。 接着介绍一下 semget 函数的用法。 int semget(key_t key, int nsems, int semflg); 参数 key:一个用来允许不相关的进程访问相同信号量的整数值。 参数 nsems:需要的信号量数目。这个值通常总是 1。 版本号:V2.0 日期:2015-10-2 - 502 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 参数 semflg:标记集合,与 open 函数的标记十分类似。 返回值:成功返回标识符,用于其它信号函数,错误返回-1。 17.6.2Semaphore 例程 编写简单的 seml.c 文件测试 seml 函数。 首先添加头文件,如下图所示。 然后 main 函数部分代码,如下图所示。 版本号:V2.0 日期:2015-10-2 - 503 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数部分代码,如下图所示。 然后 main 函数部分代码,如下图所示。 版本号:V2.0 日期:2015-10-2 - 504 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数部分代码,如下图所示。 然后 main 函数部分代码,如下图所示。 版本号:V2.0 日期:2015-10-2 - 505 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数部分代码,如下图所示。 如上图代码所示。 第 1-9 行:头文件。 第 10-23 行:定义结构体和几个函数。 版本号:V2.0 日期:2015-10-2 - 506 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第 29-30 行:创建信号量。 第 34-39 行:初始化信号量。 第 40-41 行:设置输出为参数的第一个字符。 第 44-61 行:向屏幕输出数据,休眠,再次输出,休眠接着循环。 第 75-84 行:set_semvalue 函数,用于初始化信号量。 第 86-93 行:del_semvalue 函数,用于删除信号量。 第 95-108 行:semaphore_p 函数,信号量操作。 第 110-123 行:semaphore_v 函数,释放信号量。 17.6.3 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/pc”,将源码 seml.c 拷贝进去,如下图所示。 版本号:V2.0 日期:2015-10-2 - 507 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用命令“arm-none-linux-gnueabi-gcc -o seml seml.c -static”编译 seml 文件,如 下图所示,使用命令“ls”可以看到生成了 seml 可执行文件。 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 将编译成的可执行文件 seml,拷贝到 U 盘,启动开发板,插入 U 盘,加载 U 盘,使用命 令“./mnt/udisk/seml a”运行程序如下。 版本号:V2.0 日期:2015-10-2 - 508 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 17.8 共享内存 shmdata 共享内存是进程间通信中最简单的方式之一。共享内存在各种进程间通信方式中具有最高 的效率。因为系统内核没有对访问共享内存进行同步,您必须提供自己的同步措施。解决这些 问题的常用方法是通过使用信号量进行同步。 17.6.1 使用 man 学习 shmget 等函数 如下图所示,使用命令“man 2 shmget”。 版本号:V2.0 日期:2015-10-2 - 509 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,注意一下相关的函数。 函数 int shmget(key_t key, size_t size, int shmflg); 参数 key:建立新的共享内存对象 参数 size:新建立的内存大小 参数 shmflg:标识符 版本号:V2.0 日期:2015-10-2 - 510 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 返回值:成功 shmget 返回一个共享内存标识符或创建一个共享内存对象,错误返回-1。 其它函数,如下所示。 void *shmat(int shmid, const void *shmaddr, int shmflg) 参数 shmid:共享内存标识符 参数 shmaddr:指定共享内存出现在进程内存地址的什么位置,直接指定为 NULL 让内核 自己决定一个合适的地址位置 参数 shmflg :SHM_RDONLY,为只读模式,其他为读写模式 返回值:成功返回共享的内存地址,否则返回-1。 int shmdt(const void *shmaddr) 参数 shmaddr:连接的共享内存的起始地址。 返回值:成功返回 0,错误返回-1。 int shmctl(int shmid, int cmd, struct shmid_ds *buf) 参数 shmid:共享内存标识符 参数 cmd IPC_RMID:删除这片共享内存 参数 buf:共享内存管理结构体 返回值:成功返回 0,错误返回-1。 版本号:V2.0 日期:2015-10-2 - 511 - www.topeetboard.com 北京迅为电子有限公司 17.6.2shmdata 例程 iTOP-4412 Linux 系统编程 V2.0 先编写简单的 shmdata.h,内存读和写都需要用到的机构。 如下图所示。 如上图代码所示。 第 4 行:定义大小为 2048。 第 6-12 行:定义结构体 shared_use_st,包含标志位以及记录写入和读取的文本。 编写简单的 shmwrite.c 文件测试写函数。 首先添加头文件,如下图所示,记得添加前面自定义的头文件。 版本号:V2.0 日期:2015-10-2 - 512 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数部分代码,如下图所示。 然后 main 函数部分代码,如下图所示。 然后 main 函数部分代码,如下图所示。 版本号:V2.0 日期:2015-10-2 - 513 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数部分代码,如下图所示。 如上图代码所示。 第 1-7 行:引用头文件。 第 15-21 行:创建共享内存 。 第 22-29 行:将共享内存连接到当前进程的地址空间。 第 30-31 行:设置共享内存。 第 32-49 行:向共享内存中写数据。 第 50-57 行:把共享内存从当前进程中分离。 版本号:V2.0 日期:2015-10-2 - 514 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 编写简单的 shmread.c 文件测试写函数。 首先添加头文件,如下图所示,记得添加前面自定义的头文件。 然后 main 函数部分代码,如下图所示。 然后 main 函数部分代码,如下图所示。 版本号:V2.0 日期:2015-10-2 - 515 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后 main 函数部分代码,如下图所示。 如上图代码所示。 第 1-6 行:头文件。 第 13-19 行:创建共享内存。 第 20-26 行:将共享内存连接到当前进程的地址空间。 版本号:V2.0 日期:2015-10-2 - 516 - www.topeetboard.com 北京迅为电子有限公司 第 28-30 行:设置共享内存。 第 31-46 行:读取共享内存中的数据。 第 47-52 行:把共享内存从当前进程中分离。 第 53-59 行:删除共享内存。 iTOP-4412 Linux 系统编程 V2.0 17.6.3 编译运行测试 在 Ubuntu 系统下,如下图所示,进入前面实验创建的目录 “/home/linuxsystemcode/pc”,将源码 shmwrite.c 和 shmread.c 以及 shmdata.h 拷贝进 去,如下图所示。 使用命令 版本号:V2.0 日期:2015-10-2 - 517 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 “arm-none-linux-gnueabi-gcc -o shmwrite shmwrite.c -static”编译 shmwrite 文件, “arm-none-linux-gnueabi-gcc -o shmread shmread.c -static”编译 shmread 文件, 如下图所示,使用命令“ls”可以看到生成了 shmread 和 shmwrite 可执行文件。 这里介绍 U 盘拷贝代码的方法,也可以编译进文件系统或者使用 NFS 文件系统等等 将编译成的可执行文件 shmwrite 和 shmread,拷贝到 U 盘,启动开发板,插入 U 盘, 加载 U 盘,使用命令“ ./mnt/udisk/shmread &”运行程序 shmread 如下。 版本号:V2.0 日期:2015-10-2 - 518 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 如下图所示,接着使用命令“./mnt/udisk/shmwrite”运行 shmwrite,注意不要加“&”。 如上图所示,除了输入字符串“end”,输入其它字符串会一直提示输入字符串,这些字 符串被 shmread 读取,并且在超级终端中打印。 版本号:V2.0 日期:2015-10-2 - 519 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第十八章 实战 网络通信-套字节 TCP 18.1 本章导读 iTOP-4412 实现基于 TCP 的 socket 编程。 在 linux 下,网络资源非常丰富,底层的东西不需要我们去管,只需要知道怎么实现我们 最终需要的功能即可。 18.1.1 工具 18.1.1.1 硬件工具 开发板 PC 机 U 盘或者 TF 卡或者 NFS 18.1.1.2 软件工具 Ubuntu12.04.2 以及虚拟机 Arm-2009q3 编译器 Notepad++编辑器 超级终端 Vim 编辑器 版本号:V2.0 日期:2015-10-2 - 520 - www.topeetboard.com 18.1.2 预备课程 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 基本开发工具的使用 常用 linux 命令 最小 linux 系统 helloworld 18.1.3 视频资源 本章配套视频为: “视频 18 网络通信-套字节 TCP” 18.2 学习目标 本章需要学习以下内容: 掌握 linux 下网络通信套字节 TCP 编程方法 18.3 实验操作 大家好,今天我们来学习一下 linux 网络通信程序的编写,我们使用的硬件平台是 iTOP-4412 开发板。 TCP 是一种面向连接的、可靠的、基于 IP 的传输层协议。通过 TCP 可以保证我们传送 的数据的正确性。 Linux 下网络通信程序基本上都是采用 socket 的方式。socket 起源于 Unix,而 Unix/Linux 基本哲学之一就是“一切皆文件”,都可以用“打开 open->读写 read/write-> 版本号:V2.0 日期:2015-10-2 - 521 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 关闭 close”模式来操作。Socket 就是该模式的一个实现,socket 即是一种特殊的文件,一些 socket 函数就是对其进行的操作(读/写 IO、打开、关闭)。说白了 socket 是应用程序与 TCP/IP 协议族通信的中间软件抽象层,它是一组接口。 现在我们看一下基于 TCP/IP 应用程序通信的流程,如下图: 通过上图我们可以看到 TCP/IP 通信是基于服务器/客户端的模式来实现的,首先是服务 器(server)端调用 socket 函数创建一个套接字,然后调用 bind 绑定函数,绑定函数主要是 版本号:V2.0 日期:2015-10-2 - 522 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 设置通信时使用哪种地址族(IPv4,IPv6 等),使用的端口号。然后调用 listen 函数来监听客 户端的连接请求。 现在我们来看下客户端(client)端的流程,首先调用 socket 函数创建一个套接字,然 后调用 connect 函数连接服务器,这时服务器端的 listen 函数监听到客户端的连接请求就会调 用 accept 函数去接受请求,这样连接就建立好了。之后双方就可以调用 read/write 函数收发 数据了,在完成通信以后服务器(server)和客户端(client)调用 close 函数关闭创建的套接 字。 下面我们来看一个实现 TCP/IP 的通信的例子,首先来看一下服务器(server)端的代 码: #include #include #include #include #include #include int main() { int sfp, nfp, num = 0; struct sockaddr_in s_add,c_add; int sin_size; 版本号:V2.0 日期:2015-10-2 - 523 - www.topeetboard.com 北京迅为电子有限公司 unsigned short portnum=0x8888; iTOP-4412 Linux 系统编程 V2.0 char buffer[100] = {0}; printf("Hello,welcome to my server !\r\n"); /* 创建 TCP 连接的套接字 */ sfp = socket(AF_INET, SOCK_STREAM, 0); if(-1 == sfp) { printf("socket fail ! \r\n"); return -1; } printf("socket ok !\r\n"); /* 变量 s_add 清零 */ bzero(&s_add,sizeof(struct sockaddr_in)); s_add.sin_family=AF_INET; s_add.sin_addr.s_addr=htonl(INADDR_ANY); s_add.sin_port=htons(portnum); 版本号:V2.0 日期:2015-10-2 - 524 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 /* 绑定 s_add 到套接字 sfp 上 */ if(-1 == bind(sfp,(struct sockaddr *)(&s_add), sizeof(struct sockaddr))) { printf("bind fail !\r\n"); return -1; } printf("bind ok !\r\n"); /*监听函数,静听客户端的连接请求 */ if(-1 == listen(sfp,5)) { printf("listen fail !\r\n"); return -1; } printf("listen ok\r\n"); sin_size = sizeof(struct sockaddr_in); 版本号:V2.0 日期:2015-10-2 - 525 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 /* 接受连接请求 */ nfp = accept(sfp, (struct sockaddr *)(&c_add), &sin_size); if(-1 == nfp) { printf("accept fail !\r\n"); return -1; } printf("accept ok!\r\nServer start get connect from %#x : %#x\r\n", ntohl(c_add.sin_addr.s_addr), ntohs(c_add.sin_port)); while(1) { memset(buffer, 0, 100); sprintf(buffer, "hello,welcome to my server(%d) \r\n", num++); /* 发送函数 */ send(nfp, buffer, strlen(buffer), 0); usleep(500000); } 版本号:V2.0 /* 关闭 socket 连接 */ 日期:2015-10-2 - 526 - www.topeetboard.com 北京迅为电子有限公司 close(nfp); iTOP-4412 Linux 系统编程 V2.0 /* 关闭 socket 连接 */ close(sfp); return 0; } 程序首先是包含一些需要用到的头文件,然后是 main 主函数,在 main 函数里面首先是定义了一 些变量,然后调用 socket 函数创建一个套接字,socket 函数的第二个参数是 SOCK_STREAM,表示创建的 是 TCP 连接。然后调用 bzero 函数把变量 s_add 清零,然后给 s_add 结构里面的变量赋值: s_add.sin_family=AF_INET;//使用 IPv4 协议 s_add.sin_addr.s_addr=htonl(INADDR_ANY);//允许任何地址 s_add.sin_port=htons(portnum);//设置端口号 然后调用 bind 绑定函数,使用的是 IPv4 协议族,然后调用 listen 监听函数,监听用户的连接请求。 在监听到用户的请求后调用 accept 函数接受请求,然后进入到循环发送的代码,我们会循环发送 “hello,welcome to my server”+发送次数号,最后会调用 close 关闭套接字。 下面我们来看看客户端(client)端的代码: #include #include #include #include 版本号:V2.0 日期:2015-10-2 - 527 - www.topeetboard.com 北京迅为电子有限公司 #include iTOP-4412 Linux 系统编程 V2.0 int main(int argc, char **argv) { int cfd; int recbyte; int sin_size; char buffer[1024] = {0}; struct sockaddr_in s_add, c_add; unsigned short portnum = 0x8888; printf("Hello,welcome to client!\r\n"); if(argc != 2) { printf("usage: echo ip\n"); return -1; } /* 创建一个 TCP 连接的 socket */ cfd = socket(AF_INET, SOCK_STREAM, 0); 版本号:V2.0 日期:2015-10-2 - 528 - www.topeetboard.com 北京迅为电子有限公司 if(-1 == cfd) { printf("socket fail ! \r\n"); return -1; } iTOP-4412 Linux 系统编程 V2.0 printf("socket ok !\r\n"); /* 变量 s_add 清零 */ bzero(&s_add,sizeof(struct sockaddr_in)); s_add.sin_family=AF_INET; s_add.sin_addr.s_addr= inet_addr(argv[1]); s_add.sin_port=htons(portnum); printf("s_addr = %#x ,port : %#x\r\n",s_add.sin_addr.s_addr,s_add.sin_port); /* 连接服务器函数 */ if(-1 == connect(cfd,(struct sockaddr *)(&s_add), sizeof(struct sockaddr))) { printf("connect fail !\r\n"); return -1; } 版本号:V2.0 日期:2015-10-2 - 529 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 printf("connect ok !\r\n"); while(1) { /* 接收服务器发过来的数据 */ if(-1 == (recbyte = read(cfd, buffer, 1024))) { printf("read data fail !\r\n"); return -1; } printf("read ok\r\nREC:\r\n"); buffer[recbyte]='\0'; printf("%s\r\n",buffer); } /* 关闭套接字 */ close(cfd); return 0; 版本号:V2.0 日期:2015-10-2 - 530 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 } 首先是包含一些需要的头文件,然后进入 main 主函数定义了一些变量,然后调用 socket 函数创建套接字,然后调用 bzero 函数把变量 s_add 清零,然后给 s_add 结构里面的变量赋 值: s_add.sin_family=AF_INET;//使用 IPv4 协议 s_add.sin_addr.s_addr= inet_addr(argv[1]);//设置要连接的 IP 地址(这里是我们执行程序的时候 传递进来的) s_add.sin_port=htons(portnum);//设置端口号 然后调用 connect 函数来连接服务器(server),在连接成功后,就进入了循环接收函数, 使用 read 函数接收服务器发送的数据。最后会调用 close 函数关闭套接字。 下面我们来编译下这两个程序,服务器(server)的程序我们运行在虚拟机 Ubuntu 上, 所以使用下面的命令编译: gcc -o server server.c 这样就生成了 server 可执行文件,客户端(client)的程序我们运行在 iTOP-4412 开发板 上,我们使用下面的命令编译: arm-none-linux-gnueabi-gcc -o client client.c 这样就生成了 client 可执行程序,把 client 下载到 iTOP-4412 开发板上,现在我们开始 运行这两个程序,首先在虚拟机 Ubuntu 上运行 serevr 程序,如下图: 版本号:V2.0 日期:2015-10-2 - 531 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 我们可以看到 server 打印出来的运行信息,现在 server 运行到了 listen 函数开始监听客 户端的连接。下面我们在 iTOP-4412 开发板上运行 client 程序(因为我把 client 下载到了/bin 目录下,所以先进入到/bin 目录)执行下面的命令: ./client 192.168.1.77 上面命令里面的 192.168.1.77 是我们虚拟机 Ubuntu 的 IP 地址,我们看到程序连接成功, 首先看一下虚拟机 Ubuntu 上的 server 打出的信息,如下图: 版本号:V2.0 日期:2015-10-2 - 532 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 我们可以看到上图中 server 打印出了客户端的 ip 地址和端口号“Server start get connect from 0xc0a801e6 : 0xe171”。 然后我们看一下 iTOP-4412 开发板串口的打印信息,如下图: 版本号:V2.0 日期:2015-10-2 - 533 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 通过上图我们可以看到打印连接成功“connect ok !”,然后串口会一直打印 read ok REC: hello,welcome to my server(0) 至此,基于 TCP/IP 的 socket 网络编程就已经完成了。 版本号:V2.0 日期:2015-10-2 - 534 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第十九章 实战 网络通信-套接字 UDP 19.1 本章导读 iTOP-4412 实现基于 UDP 的 socket 编程。 19.1.1 工具 19.1.1.1 硬件工具 开发板 PC 机 U 盘或者 TF 卡或者 NFS 19.1.1.2 软件工具 Ubuntu12.04.2 以及虚拟机 Arm-2009q3 编译器 Notepad++编辑器 超级终端 Vim 编辑器 19.1.2 预备课程 基本开发工具的使用 常用 linux 命令 版本号:V2.0 日期:2015-10-2 - 535 - www.topeetboard.com 北京迅为电子有限公司 最小 linux 系统 helloworld 网络通信-套字节 TCP iTOP-4412 Linux 系统编程 V2.0 19.1.3 视频资源 本章配套视频为: “视频 19 网络通信-套接字 UDP” 19.2 学习目标 本章需要学习以下内容: 掌握 linux 下网络通信套字节 UDP 编程方法 19.3 实验操作 大家好,上一章我们讲了基于 TCP 的 socket 编程,这一章我们讲解一下基于 UDP 的 socket 编程,UDP 是用户数据报协议,它是一种无连接的传输层协议,提供面向事物的简单不可靠信 息传送服务,所以在一些网络质量不满意的环境下,UDP 协议数据包丢失会比较严重,会造成 数据的丢失。UDP 的特点是他不属于连接型协议,所以资源消耗小。处理速度快的优点,所以 通常音频,视频和普通数据在传送时使用 UDP 较多,因为它们即使偶尔丢失一两个数据包,也 不会对接收结果产生太大影响。 UDP 的通信框图如下图所示: 版本号:V2.0 日期:2015-10-2 - 536 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 从上图可以看到基于 UDP 通信的程序也是由服务器和客户端组成。与 TCP 的服务器不同, UDP 的服务器不需要 listen 和 accept 函数,客户端不需要 connect 函数。 下面我们通过一个例子来了解一下 UDP 的应用程序,首先我们来看下服务器(server)端的 程序 server.c: #include #include #include #include int main(int argc, char **argv) { int n; char recvline[1024] = {0}; 版本号:V2.0 日期:2015-10-2 - 537 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 int sockfd; struct sockaddr_in servaddr; /* 创建一个 UDP 连接的 socket */ sockfd = socket(PF_INET, SOCK_DGRAM, 0); /* 变量 servaddr 清零 */ bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(50001); /* 绑定 servaddr 到创建的 socket 上 */ bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); /* 接收客户端发送的数据 */ recvfrom(sockfd, recvline, 1024, 0, NULL, NULL); printf("%s\n", recvline); 版本号:V2.0 日期:2015-10-2 - 538 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 /* 关闭 socket 连接 */ close(sockfd); } 上面的代码和我们前面一章的 TCP 的服务器程序差不多,首先也是定义一些变量,然后调 用 socket 函数创建一个套接字,这里 socket 函数的第二个参数是 SOCK_DGRAM,即用户数 据报,也就是创建的 UDP 连接,然后调用 bzero 函数清空变量 servaddr 的值,然后设置 servaddr 结构的值,接着调用 bind 绑定函数,然后调用 recvfrom 函数直接接收数据,而没 有调用 listen 和 accept 函数。 下面我们来看看客户端(client)的程序 client.c: #include #include #include #include int main(int argc, char **argv) { int sockfd; struct sockaddr_in servaddr; if(argc != 2) { 版本号:V2.0 日期:2015-10-2 - 539 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 printf("usgae: ./client [ip]\n"); return -1; } /* 创建一个 UDP 的 socket 连接 */ sockfd = socket(PF_INET, SOCK_DGRAM, 0); /* 变量 servaddr 清零 */ bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(50001); servaddr.sin_addr.s_addr = inet_addr(argv[1]); char sendline[100]; sprintf(sendline, "Hello, world!"); /* 发送数据 */ sendto(sockfd, sendline, strlen(sendline), 0, (struct sockaddr *)&servaddr, sizeof(servaddr)); 版本号:V2.0 日期:2015-10-2 - 540 - www.topeetboard.com 北京迅为电子有限公司 /* 关闭 socket 连接 */ close(sockfd); iTOP-4412 Linux 系统编程 V2.0 return 1; } 客户端(client)的程序首先是定义一些使用的变量,然后也是调用 socket 函数创建一个 套接字,socket 函数的第二个参数是 SOCK_DGRAM,即用户数据报,也就是 UDP 连接,然 后调用 bzero 函数把 servaddr 结构的变量清零,然后设置 servaddr 结构变量的值,然后调用 sendto 发送函数,这里客户端程序没有调用 bind 函数和 connect 函数。现在我们使用命令 gcc -o server server.c 执行结果如下图: 版本号:V2.0 日期:2015-10-2 - 541 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用命令 arm-none-linux-gnueabi-gcc -o client client.c 编译 client.c,执行结果如下 图: 我们把生成的 client 拷贝到我们的 NFS 文件系统的 bin 目录下,如下图: 版本号:V2.0 日期:2015-10-2 - 542 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后我们在虚拟机 Ubuntu 上运行 server 程序,如下图: 版本号:V2.0 日期:2015-10-2 - 543 - www.topeetboard.com 北京迅为电子有限公司 在 4412 开发板上运行 client 程序,如下图: iTOP-4412 Linux 系统编程 V2.0 执行结果如下图: 版本号:V2.0 日期:2015-10-2 - 544 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 现在我们看下虚拟机 Ubuntu 的 server 程序的输出,如下图: 版本号:V2.0 日期:2015-10-2 - 545 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 我们可以看到 server 程序输出“Hello,word”,上面的打印信息就是 client 发送的数据。 至此基于 UDP 的 socket 通讯就实现了。 版本号:V2.0 日期:2015-10-2 - 546 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第二十章 实战 搭建 web 服务器 20.1 本章导读 iTOP-4412 实现 web 服务器。 20.1.1 工具 20.1.1.1 硬件工具 开发板 PC 机 U 盘或者 TF 卡或者 NFS 20.1.1.2 软件工具 Ubuntu12.04.2 以及虚拟机 Arm-2009q3 编译器 Notepad++编辑器 超级终端 Vim 编辑器 20.1.2 预备课程 基本开发工具的使用 常用 linux 命令 版本号:V2.0 日期:2015-10-2 - 547 - www.topeetboard.com 最小 linux 系统 helloworld 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 20.1.3 视频资源 本章配套视频为: “视频 20 搭建 web 服务器” 20.2 学习目标 本章需要学习以下内容: 掌握 boa 搭建服务器的方法 初步了解 html 网页制作 20.3 实验操作 大家好,今天我来学习一下利用 iTOP-4412 开发板搭建一个 web 服务器。我们需要用到 boa,boa 是一个小型的 web 服务器,可执行代码只有约 60KB,可以用于多种平台,它一个 单任务 web 服务器,只能依次完成用户的请求,在嵌入式中比较常见。boa 的官方网站为 www.boa.org,可以在上面下载最新版本的 boa,这里我们使用的是 boa-0.94.13.tar.gz。 拷贝下载的 boa-0.94.13.tar.gz 到我们的 Ubuntu 虚拟机,如下图: 版本号:V2.0 日期:2015-10-2 - 548 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后使用 tar 命令解压 boa-0.94.13.tar.gz,如下图所示: 版本号:V2.0 日期:2015-10-2 - 549 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 执行完上面的解压命令后,会在当前目录下生成 boa-0.94.13 文件夹,如下图: 使用 cd 命令进入到 boa-0.94.13 文件夹,如下图: 版本号:V2.0 日期:2015-10-2 - 550 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 现在我们开始编译 boa,如上图所示,在 boa-0.94.13 文件夹下面有 src 文件夹,使用 cd 命令进入到 src 目录,如下图所示: 版本号:V2.0 日期:2015-10-2 - 551 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接下来运行./configure 生成 Makefile 编译文件,如下图: 版本号:V2.0 日期:2015-10-2 - 552 - www.topeetboard.com 北京迅为电子有限公司 运行结果如下图所示: iTOP-4412 Linux 系统编程 V2.0 执行完上面的命令后,会在当前目录下生成 Makefile 文件,如下图所示: 版本号:V2.0 日期:2015-10-2 - 553 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 在编译之前我们需要修改一下 Makefile 里面的两个参数,使用 vi 命令打开 Makefile 文件, 如下图所示: 版本号:V2.0 日期:2015-10-2 - 554 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 在 Makefile 文件里面找到“CC = gcc”这一行,如下图所示: 版本号:V2.0 日期:2015-10-2 - 555 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 将这一行修改成“CC = arm-none-linux-gnueabi-gcc -static”,如下图所示: 然后找到”CPP = gcc -E“这一行,如下图所示: 版本号:V2.0 日期:2015-10-2 - 556 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 把这一行修改成“CPP = arm-none-linux-gnueabi-gcc -E -static”,如下图所示: 版本号:V2.0 日期:2015-10-2 - 557 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 最后退出并保存 Makefile 文件,接下来输入 make 命令,开始编译 boa,如下图所示: 在编译的过程中会出现下面的错误,如图所示: 版本号:V2.0 日期:2015-10-2 - 558 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 解决办法,使用 vi 命令打开当前目录下的 compat.h,如下图所示: 版本号:V2.0 日期:2015-10-2 - 559 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后找到“#define TIMEZONE_OFFSET(foo) foo##->tm_gmtoff”这一行,如下图所 示: 把这一行修改为“#define TIMEZONE_OFFSET(foo) foo##->tm_gmtoff”,如下图所 示: 版本号:V2.0 日期:2015-10-2 - 560 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后保存并退出 compat.h,输入 make,继续编译 boa,如下图: 版本号:V2.0 日期:2015-10-2 - 561 - www.topeetboard.com 北京迅为电子有限公司 编译完成后,如下图所示: iTOP-4412 Linux 系统编程 V2.0 我们使用 ls 命令看到在当前目录下生成 boa 文件,如下图: 版本号:V2.0 日期:2015-10-2 - 562 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 我们可以使用 ll boa 命令查看一下 boa 文件的大小,如下图: 版本号:V2.0 日期:2015-10-2 - 563 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接下来使用 arm-none-linux-gnueabi-strip boa 命令为 bos 文件瘦身,如下图: 执行完上面的命令后,我们在输入 ll boa 命令查看 boa 文件的大小,如下图所示: 版本号:V2.0 日期:2015-10-2 - 564 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 通过上面的图片我们看到 boa 文件比之前变小了,至此 boa 的编译就完成了,下面我们需 要把 boa 文件拷贝到我们的文件系统里面。这里我使用的是 NFS 文件系统(NFS 文件系统前 面章节已经讲解过,这里就不在讲解了),我的 NFS 文件系统是虚拟机 Ubuntu 的 /home/topeet/linux/app/system 这个目录。使用 cp 命令拷贝编译最终生成的 boa 到 NFS 文件系统的 bin 目录下面,如下图所示: 版本号:V2.0 日期:2015-10-2 - 565 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 拷贝完成 boa,我们需要在我们的 NFS 文件系统下面建立几个文件夹(我们的 NFS 文件 系统目录是/home/topeet/linux/app/system),首先在 etc 目录下建立 boa 文件夹,如下图: 版本号:V2.0 日期:2015-10-2 - 566 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 接下来在 NFS 文件系统的根目录下建立 www 文件夹,如下图: 版本号:V2.0 日期:2015-10-2 - 567 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后在上面建立的 www 目录下面建立文件夹 cgi-bin 目录,如下图: boa 程序运行需要一个配置文件:boa.conf,在 boa-0.94.13 目录下面有个默认的 boa.conf 文件,我们把它拷贝到 NFS 文件系统的 etc/boa 目录下面,如下图: 版本号:V2.0 日期:2015-10-2 - 568 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后拷贝虚拟机 Ubuntu 的/etc 目录下的 mime.types 文件到 NFS 文件系统的 etc 目录下 面,如下图所示: 版本号:V2.0 日期:2015-10-2 - 569 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后在 NFS 文件系统的 etc 目录下用命令 vi group 命令建立 group 文件,如下图所示: 版本号:V2.0 日期:2015-10-2 - 570 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后在 group 文件输入“root:*:0:”,添加 root 用户组,如下图所示: 然后保存并退出。 然后我们进到 NFS 文件系统的 etc/boa 目录,如下图所示: 版本号:V2.0 日期:2015-10-2 - 571 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 使用 vi boa.conf 命令打开 boa.conf 文件,如下图所示: 版本号:V2.0 日期:2015-10-2 - 572 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 打开 boa.conf 文件,找到“Group nogroup”这一行,修改为“Group root”,如下图: 然后找到“#ServerName www.your.org.here”这一行,修改为“ServerName www.your.org.here”, 如下图所示: 版本号:V2.0 日期:2015-10-2 - 573 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后找到“DocumentRoot /var/www”这一行,修改为“DocumentRoot /www”(注 意:这里的“/www”就是前面步骤我们使用 mkdir 创建的 www 目录),如下图所示: 版本号:V2.0 日期:2015-10-2 - 574 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后找到“ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/”这一行,修改为“ScriptAlias /cgi-bin/ /www/cgi-bin/”,如下图所示: 版本号:V2.0 日期:2015-10-2 - 575 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 最后保存并退出 boa.conf,至此完成 boa.conf 配置文件的修改。下面我们添加科技自动 运行 boa 的脚本,打开 NFS 文件系统的 etc/init.d/rcS 文件,如下图所示: 版本号:V2.0 日期:2015-10-2 - 576 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 打开 etc/init.d/rcS 文件以后,定位到他的最后一行,如下图所示: 版本号:V2.0 日期:2015-10-2 - 577 - www.topeetboard.com 北京迅为电子有限公司 然后在最后一行添加“boa &”,如下图所示: iTOP-4412 Linux 系统编程 V2.0 然后保存并退出 etc/init.d/rcS。然后使用 cd www 命令,进入到前面创建的 www 目录, 如下图所示: 版本号:V2.0 日期:2015-10-2 - 578 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后使用 vi index.html 命令建立 index.html 文件,如下图所示: 版本号:V2.0 日期:2015-10-2 - 579 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后在里面输入下面的代码:(注意:web 页面不要包含汉字) iTOP-4412 版本号:V2.0 日期:2015-10-2 - 580 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0

iTOP-4412 WEB SERVER

   
如下图所示: 版本号:V2.0 日期:2015-10-2 - 581 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后保存并退出 index.html,至此基于 boa 的 web 服务器就搭建完成了,上面我们创建 的 index.html 是一个简单的 wen 网页,用于我们测试。现在启动我们的开发板(开发板是挂 载 NFS 网络文件系统),开发板起来以后我们输入 ps 命令,可以看到 boa 程序在运行,如下 图: 版本号:V2.0 日期:2015-10-2 - 582 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后我们在 pc 机器打开浏览器,输入开发板的 IP 地址(192.168.1.230),可以看到我们 在开发板上创建的 index.html,如下图所示: 至此我们的 web 服务器搭建完成了。 版本号:V2.0 日期:2015-10-2 - 583 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 第二十一章 实战 web 控制 led 21.1 本章导读 本章介绍了额外的一些 web 知识,用于实现网络数据的传输。用户可以在这个例子的基础 上扩展其功能。 21.1.1 工具 21.1.1.1 硬件工具 开发板 PC 机 U 盘或者 TF 卡或者 NFS 21.1.1.2 软件工具 Ubuntu12.04.2 以及虚拟机 Arm-2009q3 编译器 Notepad++编辑器 超级终端 Vim 编辑器 21.1.2 预备课程 基本开发工具的使用 版本号:V2.0 日期:2015-10-2 - 584 - www.topeetboard.com 常用 linux 命令 最小 linux 系统 helloworld 搭建 web 服务器 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 21.1.3 视频资源 本章配套视频为: “视频 21web 控制 led” 21.2 学习目标 本章需要学习以下内容: Web 控制 led 21 实验操作 大家好,上一章我们讲了在 iTOP-4412 开发板上搭建 web 服务器,这一 章我们在前面一章的基础上讲解一下通过 web 网页实现控制 LED。 要实现控制 led,我们需要 CGI 编程,CGI(Common Gateway Interface) 是外部应用扩展,应用程序与 www 服务器交互的一个标准接口。按照 CGI 标准 编写的外部扩展应用程序可以处理客户端浏览器输入的数据,从而完成客户端与 服务器的交互操作。而 CGI 规范就定义了 web 服务器如何向扩展应用程序发送消 息,在收到扩展应用程序的信息后又如何进行处理等内容。通过 CGI 可以提供许 版本号:V2.0 日期:2015-10-2 - 585 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 多静态的 HTML 网页无法实现的功能。比如搜索引擎、基于 web 的数据库访问 等等。 首先进入到我们的 NFS 文件系统所在的目录,如下图: 在前面的搭建 web 服务器章节,我们在修改 boa.conf 配置文件的时候指定 了 web 网页的存放目录“DocumentRoot /www”,现在我们打开之前我们在 www 目录创建的 index.html,如下图所示: 版本号:V2.0 日期:2015-10-2 - 586 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 打开 index.html 后,删除掉里面的内容,然后输入下面的内容: led 远程控制 iTOP-4412 Linux 系统编程 V2.0 版本号:V2.0 日期:2015-10-2 - 589 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0

 

iTOP-4412 WEB SERVER

 
版本号:V2.0 日期:2015-10-2 - 590 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0
Led1
Led2

 

 

如下图所示: 版本号:V2.0 日期:2015-10-2 - 591 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后保存并退出。上面输入的是 HTML 格式的代码,主要是用到了通过表单 向服务器提交信息,在表单里面指定了服务器端处理接收到信息的 CGI 程序是 myled,这是在 form 表单的属性里设置的,代码是“form action="/cgi-bin/myled.cgi" method="get”,使用的传递数据的方式是 get 方法,如下图所示: 版本号:V2.0 日期:2015-10-2 - 592 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 修改完了 index.html,我们需要些 CGI 程序。在 boa 的配置文件 boa.conf 里面我们指定了 CGI 程序的存储目录是“ScriptAlias /cgi-bin/ /www/cgi-bin/”, 如下图所示: 版本号:V2.0 日期:2015-10-2 - 593 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 现在我们进入到 NFS 文件系统的 www/cgi-bin 目录,如下图所示: 版本号:V2.0 日期:2015-10-2 - 594 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后再 cgi-bin 目录我们创建 myled.c,如下图所示: 然后在 myled.c 里输入下面的代码: #include #include int main() { char *data; int leds[2] = {0, 0}; 版本号:V2.0 日期:2015-10-2 - 595 - www.topeetboard.com long m, n; 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 int exit=0,i,fd; printf("Content-Type:text/html;charset=gb2312\n\n"); printf("\n"); printf("\n"); printf("iTOP-4412 "); printf("

iTOP-4412

"); data = getenv("QUERY_STRING"); printf("

receive data:%s

",data); while(*data != '\0') { if(*data=='=') switch(*(data+1)) { case '1':leds[0]=1;break; case '2':leds[1]=1;break; 版本号:V2.0 日期:2015-10-2 - 596 - www.topeetboard.com 北京迅为电子有限公司 default:exit=1;break; } if(exit == 1) break; data++; } iTOP-4412 Linux 系统编程 V2.0 fd=open("/dev/leds",0); for(i=0;i<2;i++) { if(leds[i]==1) printf("

%d\t

",i+1); ioctl(fd,leds[i],i); } printf("\n"); printf("\n"); return 0; } 版本号:V2.0 日期:2015-10-2 - 597 - www.topeetboard.com 如下图所示: 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 最后保存并退出。 上面的代码是 C 语言,主要是完成了获取 web 提交过来的数据,然后对获得 的数据解析,最后会调用 led 的 ioctl 函数来点亮或关闭 led。里面的 printf 打印 语句,最终会生成一个 web 页面。接下来编译 myled.c 生成 myled.cgi(在 index.html 的表单里面设置了处理文请求的 cgi 程序是 myled.cgi),使用命令 “arm-none-linux-gnueabi-gcc -o myled.cgi myled.c -static”编译 myled.c, 如下图所示: 版本号:V2.0 日期:2015-10-2 - 598 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 编译完成后,我们可以看到在 www/cgi-bin 目录下生成了 myled.cgi,如下 图所示: 版本号:V2.0 日期:2015-10-2 - 599 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 注意:生成的 myled.cgi 需要有可执行权限,所以我们使用 chmod 命令修 改下它的权限,如下图所示: 版本号:V2.0 日期:2015-10-2 - 600 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 现在控制 led 的 web 程序就已经完成了,现在启动开发板,如下图所示: 版本号:V2.0 日期:2015-10-2 - 601 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 通过上图我们可以看到 iTOP-4412 开发板已经起来了,然后打开 PC 的浏览 器,输入开发板的 ip 地址,如下图所示: 输入完成后,按回车,即可打开开发板的 index.html 页面,如下图所示: 我们可以选中 led1 和 led2 右边的复选框,如下图所示: 版本号:V2.0 日期:2015-10-2 - 602 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 然后点击页面上的“submit”按钮,会打开一个新的 web 页面,如下图: 上图中的页面里面的信息就是我们的 myled.cgi 程序里面的 printf 打印出来 的,其中“receive data:led1=1&led2=2&submit=submit”,就是客户端通过 get 版本号:V2.0 日期:2015-10-2 - 603 - www.topeetboard.com 北京迅为电子有限公司 iTOP-4412 Linux 系统编程 V2.0 方式传递给 web 服务器的数据,下面两行的 1 和 2 是 myled.cgi 程序从“receive data:led1=1&led2=2&submit=submit”里面解析出来的值。同时我们还可以在串口 上看到 iTOP-4412 开发板 led 驱动打印出来的信息,如下图所示: 至此通过 web 页面控制 led 的实验已经完成了,大家可以参照这个例程来自 己实现一个控制蜂鸣器的 web 程序。 版本号:V2.0 日期:2015-10-2 - 604 - www.topeetboard.com

Top_arrow
回到顶部
EEWORLD下载中心所有资源均来自网友分享,如有侵权,请发送举报邮件到客服邮箱bbs_service@eeworld.com.cn 或通过站内短信息或QQ:273568022联系管理员 高进,我们会尽快处理。