User Manual IoT-9608
ARM嵌入式工业控制模块
UM01010101 V1.02 Date: 2016/08/01 产品用户手册
类别 关键词 摘 要
内容
AM3352,Linux,CAN,Ethernet,Serial,USB
IoT-9608 工控板使用指南
广州致远电子股份有限公司
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 修订历史
版本 V0.90 V1.00 V1.01 V1.02 日期 2015/08/01 2015/12/25 2015/05/20 2016/08/01 原因 创建文档 发布文档 1、 纠正文档中关于串口以及其他的错误描述 2、 蜂鸣器测试改为先设置period_freq,后设置duty_percent 纠正2.1.2节的错误描述 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
i
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 目 录
1. IoT-9608 工控主板简介 ........................................................................................... 1
1.1 1.2 1.3 1.4 2.1
工控主板简介 ............................................................................................................... 1 主板主要接口 ............................................................................................................... 1 硬件参数 ....................................................................................................................... 2 软件参数 ....................................................................................................................... 2 开机和登录 ................................................................................................................... 4 2.1.1 启动选择 ........................................................................................................... 4 2.1.2 串口连接 ........................................................................................................... 4 2.1.3 串口登录 ........................................................................................................... 6 2.1.4 SSH远程登录 ...................................................................................................... 6 关机 ............................................................................................................................... 7 查看系统信息 ............................................................................................................... 8 系统设置 ....................................................................................................................... 8 2.4.1 网络设置 ........................................................................................................... 8 2.4.2 系统时钟 ........................................................................................................... 9 文件传输 ....................................................................................................................... 9 2.5.1 SSH文件传输 ...................................................................................................... 9 2.5.2 NFS 文件传输 ................................................................................................... 11 U盘使用 ..................................................................................................................... 11 SD卡使用 ................................................................................................................... 12 U-Boot交互 ................................................................................................................ 12 串口测试 ..................................................................................................................... 12 分区描述 ..................................................................................................................... 14 支持的文件系统 ......................................................................................................... 14 安装第三方软件 ......................................................................................................... 15 程序开机自启动 ......................................................................................................... 15 应用程序开发环境构建 ............................................................................................. 17 4.1.1 嵌入式Linux开发一般方法 ......................................................................... 17 4.1.2 安装操作系统 ................................................................................................. 18 4.1.3 构建交叉开发环境 ......................................................................................... 18 4.1.4 NFS 服务器配置 ............................................................................................... 19 Hello 程序 .................................................................................................................. 20 GPIO 使用 ................................................................................................................. 21 蜂鸣器使用 ................................................................................................................. 22 串口编程 ..................................................................................................................... 22 4.5.1 访问串口设备 ................................................................................................. 23 4.5.2 配置串口接口属性 ......................................................................................... 24 4.5.3 获得和设置串口信号线状态 ......................................................................... 32
2. 系统基本操作 ........................................................................................................... 4
2.2 2.3 2.4
2.5
2.6 2.7 2.8 2.9 3.1 3.2 3.3 3.4 4.1
3. 文件系统 ................................................................................................................. 14
4. 应用程序开发 ......................................................................................................... 17
4.2
4.3 4.4 4.5
产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
1
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 4.6
Socket CAN编程 ....................................................................................................... 33 4.6.1 初始化CAN网络接口 .................................................................................. 33 4.6.2 socket can编程 ................................................................................................... 34 4.6.3 示例程序 ......................................................................................................... 37 4.7 看门狗使用 ................................................................................................................. 42
4.7.1 概述 ................................................................................................................. 42 4.7.2 范例 ................................................................................................................. 42
5. 系统恢复和更新 ..................................................................................................... 44
5.1 5.2 5.3 5.4 5.5 5.6
制作SD卡 .................................................................................................................. 44 烧写Linux固件 ......................................................................................................... 44 升级某个固件 ............................................................................................................. 45 全自动升级固件 ......................................................................................................... 46 其它 ............................................................................................................................. 46 Tera Term使用说明 ................................................................................................... 46
6. 免责声明 ................................................................................................................. 49
产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
2
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 1. IoT-9608 工控主板简介
1.1 工控主板简介
IoT-9608是广州致远电子股份有限公司开发的基于AM3352处理器的工控主板,采用“核心板+底板”的结构。板载10路UART串口,2路USB Host 2.0接口,1路10/100M以太网接口,1路千兆网,2路CAN接口,1路SD卡接口,8路AD接口,1路MiniPCIE接口座。
主板外观如图 1.1所示。
图 1.1 主板外观图
1.2 主板主要接口
IoT-9608主板各接口简要描述如表 1.1所列。
表 1.1 IoT-9608 工控主板接口描述
标号 J2 J12 CZ1 CZ2 J5 J6 电源接口 10/100/1000M 以太网 USB Host USB Host 8路ADC 扩展接口 1 功能 9~24V 供电 NET1为百兆,NET2为千兆 CAN 备注 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
1
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 串口 GPIO MiniPCIE接口座 J7 J9 J4 JP3 JP4 J8 J3(背面) U14 扩展接口 2 扩展接口 3 扩展接口 4 看门口跳线区 U-Boot跳线区 调试串口 SD卡 SIM卡 1.3 硬件参数
IoT-9608主板硬件参数如表 1.2所列。
表 1.2 IoT-9608 主板硬件参数
项目 处理器 内存 电子硬盘 扩展串口 串口 USB Host MiniPCIE插座 CAN 接口 以太网 SD 卡接口 RTC 蜂鸣器 指示灯 描述 AM3352(Cortex-A8 内核),800MHz 512MB DDR3 256MB SLC NAND 4 路 6 路(包含 1 路调试串口) 2 路,USB 2.0 高速 1 路 2 路 2路(包含1路10/100M 自适应以太网和1路10/100/1000M自适应以太网) 1 路 以太网 说明 默认启动10/100M自适应2 路(包含1路内部RTC和1路外部RTC) 只启用外部RTC 1 个 2 个 1.4 软件参数
IoT-9608运行Linux-3.2.0,包含如下驱动程序: NAND Flash驱动程序; SD/MMC卡驱动程序;
USB Host驱动程序,支持USB键盘、USB鼠标和U盘; CAN-Bus驱动程序(Socket CAN接口); 10/100M自适应以太网驱动程序; 10/100/1000M自适应以太网驱动程序; MiniPCIE接口座,支持WIFI,GPRS,3G; UART驱动,包含6路内部串口和4路扩展串口; RTC驱动程序,包含内部和外部RTC; ADC驱动程序; 看门狗驱动程序;
产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
2
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 LED驱动; 交流蜂鸣器驱动; GPIO驱动。
注意:IoT-9608的MiniPCIE接口座不支持标准PCIE协议的设备。
产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
3
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 2. 系统基本操作
2.1 开机和登录
系统默认IP:192.168.1.136(百兆网卡) SSH登录用户名和密码均为:root
2.1.1 启动选择
IoT-9608支持从NAND或者SD卡启动,通过JP4 跳线进行选择。断开JP4 选择从NAND 启动,短接后从SD卡启动。
2.1.2 串口连接
IoT-9608的调试串口为UART0,从J8和J10接口引出,默认为RS232电平。
通过串口延长线或者杜邦线将调试串口与PC电脑串口相连,设置串口为115200-8N1,无流控制。
在Windows环境下,可以使用超级终端或者其它串口软件,下面以超级终端(2.4.8版本)为例进行介绍。打开超级终端,在菜单栏选择“文件”“新建连接”,在弹出的窗口的“连接类型”里选择串口,如图 2.1 所示。
图 2.1 新建连接
点击“确定”进入串口属性设置界面,在这里设定串口的波特率、数据位等参数,具体设置为“115200,8N1,无流控制”,如图 2.2 所示。
产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
4
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块
图 2.2 串口属性设置
确认设置无误后点击“确定”,将得到如图 2.3 所示的超级终端界面。
图 2.3 设定完成的超级终端界面
产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
5
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 2.1.3 串口登录
接好串口,打开串口软件,给工控板上电,在U-Boot阶段不要按任何按键,系统将启动并进入Linux系统,在超级终端可以看到启动信息。系统启动完毕,进入Linux Shell界面,如图 2.4 所示。
图 2.4 通过超级终端登录Linux系统
2.1.4 SSH远程登录
IoT-9608系统支持SSH远程登录,可以使用任何SSH软件进行登录。下面以Putty软件通过SSH协议进行登录为例进行介绍。
IoT-9608有2路以太网网卡,默认启动百兆网卡(即NET1网口),其IP为192.168.1.136,要进行SSH远程登录,需要为主机设置或者添加一个192.168.1.x的IP地址。启动Putty软件,在“Host Name”栏填入工控板的IP地192.168.1.136,选中SSH协议,如图 2.5所示。
产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
6
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块
图 2.5 选中使用SSH协议
点击“Open”,在登录界面输入用户名和密码“root”,登录Linux系统,如图 2.6所示。
图 2.6 通过SSH登录Linux系统
2.2 关机
一般情况下直接关闭电源即可。如果有数据存储操作,为了确保数完全写入,可输sync命令,完成数据同步后关闭电源;或者输入poweroff命令,等串口端出现“System halted”提示后再关闭电源。
[root@IoT9608 ~]# poweroff The system is going down NOW! Sent SIGTERM to all processes Sent SIGKILL to all processes Requesting system poweroff System halted.
产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
7
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 2.3 查看系统信息
查看系统内核版本,使用uname命令:
[root@IoT9608 ~]# uname -a
Linux IoT9608 3.2.0 #9 Mon Aug 10 14:45:22 CST 2015 armv7l GNU/Linux
查看系统内存使用情况,使用free命令:
[root@IoT9608 ~]# free
total 512712 0
used 14524 14512 0
free 498188 498200 0
shared 0
buffers 12
Mem: Swap:
-/+ buffers:
查看系统磁盘使用情况,使用df命令:
[root@IoT9608 ~]# df Filesystem ubi0:rootfs tmpfs tmpfs tmpfs ubi1:opt
Size 56.2M 250.3M 250.3M 7.4G
Used 52.6M 52.0K 0
116.4M
Available Use% 3.6M 250.3M 250.3M 250.3M 7.3G 156.0M
94% 0% 0% 0% 2% 1%
Mounted on / /tmp /var /media
/media/mmcblk0p1 /opt
250.3M 12.0K
/dev/mmcblk0p1
162.7M 1.9M
查看CPU等其它信息:
[root@IoT9608 ~]# cat /proc/cpuinfo Processor BogoMIPS Features
: ARMv7 Processor rev 2 (v7l) : 794.62
: swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls : 0x41 : 7 : 0x3 : 0xc08 : 2 : IoT-9608 : 0000
: 0000000000000000
CPU implementer CPU architecture CPU variant CPU part CPU revision
Hardware Revision Serial
更多的系统信息请使用相应的命令进行查看。
2.4 系统设置
2.4.1 网络设置
1. IP地址
临时改变IP可以使用ifconfig命令进行,如:
[root@IoT9608 ~]# ifconfig eth0 192.168.1.136
更详细的网络设置请参考其它资料。
产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
8
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 永久改变网卡设置可使用eeprom命令进行更改:
[root@IoT9608 ~]# eeprom net set ip 192.168.1.136
2. MAC 地址
IoT-9608允许更改MAC地址,出厂为MAC分配了广州致远通过IEEE标准协会购买的合法的MAC地址(致远的MAC地址以00-14-97开头),贴在核心板的标签上。如果有需要,可以用以下命令修改网卡 MAC地址,如果不修改则系统将使用TI分配的MAC地址(也是合法地址)。
[root@IoT9608 ~]# ifconfig eth0 hw ether 00:14:97:0f:00:00
MAC 地址查询网址:http://standards.ieee.org/develop/regauth/oui/public.html。
查询范例:查询00-14-97开头的MAC地址所属厂商:
查询结果如下:
2.4.2
系统时钟
查看系统时间,使用date命令:
[root@ IoT9608 ~]# date Mon Jan 28 15:35:12 UTC 2014
设置系统时钟,先使用date命令设置好时间,然后使用hwclock -w命令将时间写入硬件RTC。
例如:设置硬件RTC时间为2014-08-28,15:34:00,则可以使用如下命令:
[root@ IoT9608 ~]# date 2014.08.28-15:34:00 [root@ IoT9608 ~]# hwclock -w
2.5 文件传输
2.5.1 SSH文件传输
IoT-9608支持SSH远程登录,如果所使用的SSH软件带有文件传输功能,还可以通过SSH进行文件传输。下面以带文件传输的SSH Secure File Transfer为例进行介绍。
SSH Secure File Transfer的运行界面如图 2.7 所示。
产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
9
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块
图 2.7 SSH Secure File Transfer 运行界面
点击界面的“Quick Connect”按钮,在远程连接界面相应栏中填入IoT-9608的IP地址和登录所使用的用户名,如 图 2.8 所示。
图 2.8 填写主机和用户
最后点击“Connect”按钮,输入密码后登录系统,并可进行文件传输。图 2.9 所示为切换到系统根目录(/)下的视图。
产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
10
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块
图 2.9 SSH 文件按浏览视图
通过SSH Secure File Transfer可以进行文件传输,由于系统保护机制,只有/opt目录可写,所以进行文件传输需要先在SSH中将远程目录切换到/opt目录。 2.5.2 NFS 文件传输
工控板只能作为 NFS 客户端,可以通过NFS方式登录到NFS服务器,进行文件传输。使用mount命令,格式如下:
[root@IoT9608 ~]# mount -t nfs nfs-server-ip:nfs-share-directory/mountpoint -o nolock
例如:
[root@IoT9608 ~]# mount -t nfs 192.168.1.138:/home/chenxibing/nfs /mnt -o nolock
NFS挂载成功后,可以使用cp命令将NFS服务器的文件复制到系统本地目录。例如:
[root@IoT9608 ~]# cp /mnt/hello/hello /opt
2.6 U盘使用
IoT-9608带2路USB Host,可支持U盘、USB读卡器或者USB接口的硬盘等移动存储设备。插入可用的U盘后,系统通常会自动挂载到/media目录下,具体目录取决于U盘的分区情况,U盘通常被识别为SCSI设备,设备名为/dev/sdaX或者/dev/sdbX,挂载为/media/sdaX或者/media/sdbX。
产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
11
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 操作完毕,建议使用先sync命令完成同步,或者使用umount命令卸载U盘,确保数据完全写入,再拔取U盘。
2.7 SD卡使用
插入TF卡,系统会进行TF卡自动挂载。一般会挂载在/media/mmcX目录下。X数值取决于卡的分区情况,如果只有一个分区,则需要手工挂载:
[root@IoT9608 ~]# mount -t vfat /dev/mmcblk0 /mnt
操作完毕,需要先卸载然后才能将卡拔出。
2.8 U-Boot交互
IoT-9608采用U-Boot做为系统引导程序,在必要的情况下,可以进入U-Boot,进行一些高级设置。
IoT-9608为了防止某些意外中止U-Boot引导进程,设置了保护机制,需要在特定时间段输入特定字符串才能进入U-Boot交互界面。U-Boot 启动后,出现“Autobooting in 1seconds. Enter \"zlg\" to interrupt Autoboot.”提示后的 1 秒钟内输入“zlg”即可进入 U-Boot交互界面。
U-Boot 2011.09-00000-g9bb2452-dirty (Jan 06 2015 - 10:06:59)
I2C: ready DRAM: 512 MiB
WARNING: Caches not enabled
NAND: HW ECC Hamming Code selected 256 MiB
MMC: OMAP SD/MMC: 0 Check SD Card ......
Card did not respond to voltage select! Net: cpsw
Autobooting in 1 seconds. Enter \"zlg\" to interrupt Autoboot.
此时输入“zlg”进入如下菜单界面(输入的“zlg”无回显):
[e] Erase NAND Flash [a] Burn all images [b] Burn bootloader [k] Burn kernel [l] Burn logo [r] Reboot [q] exit to cmdline
2.9 串口测试
IoT-9608系统自带一个串口测试软件microcom,可以很简便快捷的测试串口。Microcom 的用法如下:
Usage: microcom [-d DELAY] [-t TIMEOUT] [-s SPEED] [-X] TTY
例如,需要测试串口ttyO1,波特率为38400。将IoT-9608的ttyO1通过TTL-232转换模块和延长线与PC的某个串口相连,PC上打开串口软件。在IoT-9608的终端输入如下命令: 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
12
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 [root@IoT9608 ~]# microcom -t 3000 -s 38400 /dev/ttyO1
然后在终端输入字符,在PC的串口软件可以看到所发送的字符,反之亦然。-t 3000表示在3000ms内没有输入,程序就自动退出。
产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
13
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 3. 文件系统
3.1 分区描述
系统板载256MB字节NAND Flash,一共分为7个MTD分区,查看/proc/mtd文件可看到各MTD分区信息:
[root@IoT9608 ~]# cat /proc/mtd dev:
size erasesize name
mtd0: 00080000 00020000 \"SPL\" mtd1: 00200000 00020000 \"U-Boot\" mtd2: 00400000 00020000 \"Kernel\" mtd3: 00400000 00020000 \"Kernel2\" mtd4: 00100000 00020000 \"Logo\" mtd5: 04000000 00020000 \"File System\" mtd6: 0b480000 00020000 \"Opt\"
各分区的大小和用途等如表 3.1所列。
表 3.1 系统分区
分区 SPL U-Boot Kernel Kernel2 Logo File System Opt 0.5MB 2MB 4MB 4MB 1MB 67MB 剩余空间 大小 SPL区域 U-Boot Linux内核 Linux内核(备份) 内核LOGO 用户文件系统区域 /opt分区,可存放用户数据或者程序 用途 建议用户将应用程序或者程序数据存放在/opt分区,而不要放在用户文件系统中,以免对文件系统造成破坏。
3.2 支持的文件系统
系统支持多种常见文件系统,如ext2、fat等,具体支持哪些文件系统,可通过查看/proc/filesystem文件。
[root@IoT9608 ~]# cat /proc/filesystems nodev nodev nodev nodev nodev nodev nodev nodev nodev nodev nodev
sysfs rootfs bdev proc tmpfs binfmt_misc debugfs sockfs usbfs pipefs anon_inodefs
14
产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 nodev nodev
rpc_pipefs devpts ext3 ext2 cramfs ramfs vfat msdos nfs nfs4 mqueue mtd_inodefs oprofilefs ubifs
nodev
nodev nodev nodev nodev nodev nodev
3.3 安装第三方软件
建议用户程序须安装在/opt 目录下,在/opt 目录下建立合理的程序目录结构,如:
/opt/myapp/
|-- bin |-- data |-- doc |-- etc |-- lib `-- share
#存放用户程序可执行文件 #存放数据文件 #存放文档文件 #存放配置等文件
#存放程序所需要的额外的库文件 #存放共享文件
/opt 在物理上是一个单独的MTD分区,专门用于安装用户程序和存放用户数据。
3.4 程序开机自启动
系统启动过程中会扫描/etc/init.d 目录下所有以“S”开头的文件并启动。所以只需在/etc/init.d 目录下编写一个文件名为:“S+编号+名称”的可执行脚本即可,在脚本中增加启动某个具体程序的语句即可。文件名必须以“S”开头,编号代表了启动级别,越大越晚运行,取值建议在90~99之间。
例如,需要开机启自动的应用程序为/opt/myapp/bin/myapp,可编写S90myapp脚本并增加可执行权限,放到/etc/init.d 目录下,文件内容可简单的写为:
#!/bin/sh
/opt/myapp/bin/myapp &
实际应用中,如果程序启动之前需要设置一些环境变量,或者进行其他初始化,或者加载某些外设驱动或者库等等,最好编写一个独立的程序启动脚本来完成以上工作,如启动程序的脚本为startmyapp,内容如下(注意,脚本需要可执行权限):
#!/bin/sh insmod xxx.ko export XXX= export YYY= /opt/myapp/bin/myapp
产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
15
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 实现开机自启动只需在/etc/init.d/S90myapp 中调用这个脚本即可:
#!/bin/sh
/opt/myapp/startmyapp &
例如,要实现开机启动QT演示程序,可在/etc/init.d目录下增加一个S90qt文件,其中内容如下:
#!/bin/sh
/usr/share/zhiyuan/zylauncher/start_zylauncher &
出厂的文件系统,除了/opt和临时目录/tmp可写之外,其余目录都是只读系统,防止系统受到意外损坏。但是系统不可避免的需要进行某些修改,系统提供了这样的操作机制。在进行文件复制、修改等命令前加上wr,即可修改系统的只读目录和文件,例如:
[root@IoT9608 ~]# wr cp S90qt /etc/init.d/
这样就可以将S90qt文件复制到本来只读的/etc/init.d目录。
要编辑修改某个文件,可在vi前加上wr,实现对文件的修改。例如要修改/etc/inittab文件,则可以这样操作:
[root@IoT9608 ~]# wr vi /etc/inittab
产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
16
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 4. 应用程序开发
4.1 应用程序开发环境构建
4.1.1 嵌入式Linux开发一般方法
嵌入式Linux系统,由于系统资源的匮乏,通常无法安装本地编译器进行本地开发,而需要在借助一台主机进行交叉开发。一般情况下,主机运行Linux操作系统,在主机安装相应的交叉编译器,将在主机编辑好的程序交叉编译后,通过一定方式如以太网或者串口将程序下载到目标系统运行,或者进行调试。一般的交叉开发流程如图 4.1所示。
图 4.1 嵌入式Linux交叉开发一般流程
嵌入式Linux开发的一般模型如图 4.2所示。通常需要一台PC主机,在其中安装好各种进行交叉编译所需要的软件,通过串口和以太网和目标板相连。在主机上进行程序编辑和编译,得到的可执行文件通过串口或者以太网下载到目标板中运行或者进行调试。
图 4.2 嵌入式Linux开发模型
进行嵌入式Linux开发,NFS(Network FileSystem)方式应该是最用的开发方式了。主机开启NFS服务,作为 NFS 服务器,目标板作为NFS客户端,目板通过NFS方式,将主机NFS服务器目录挂载到本地系统,像操作本地文件一样操作远程机器的文件。 对主机的要求,硬件方面,要求有串口和网口;软方面,操作系统推荐使用主流发行版,如ubuntu等,还需要安装开发相关的软件,同时还需要其它的软件如交叉编译器等。 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
17
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 4.1.2 安装操作系统
按照一般方法安装即可。
4.1.3 构建交叉开发环境
1. 工具链和安装
工具链压缩包:arm-2011.03-41-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 安装工具链只需将压缩包进行解压,并设置环境变量即可。解压后生成arm-2011.03目录,其中bin里面包含工具链如arm-none-linux-gnueabi-gcc、arm-none-linux-gnueabi-g++的可执行文件。
设置工具链路径,将arm-2011.03/bin目录添加到系统PATH环境变量中即可,假如工具链 安 装 在/home/ctools/arm-2011.03目 录 , 则 需 要 指 定 交 叉 编 译 目 录 到/home/ctools/arm-2011.03/bin。
具体设置方法:修改~/.bashrc 文件,在 PATH 变量中增加交叉编译工具链的安装路径,然后运行~/.bashrc 文件,使设置生效。
# User specific environment and startup programs
PATH=/home/ctools/arm-2011.03/bin:$PATH //增加交叉编译器安装路径 运行.bashrc文件的方法,进入用户主目录,输入. .bashrc命令(点+空格.bashrc)。 在终端输入arm-none-并按TAB键,如果能够看到很多arm-none-linux-gnueabi-前缀的命令,则基本可以确定交叉编译器安装正确。
chenxibing@linux-compiler: ~$ arm-none-linux-gnueabi- arm-none-linux-gnueabi-addr2line arm-none-linux-gnueabi-ar arm-none-linux-gnueabi-as arm-none-linux-gnueabi-c++ arm-none-linux-gnueabi-cpp arm-none-linux-gnueabi-elfedit arm-none-linux-gnueabi-g++ arm-none-linux-gnueabi-gcc arm-none-linux-gnueabi-gcov arm-none-linux-gnueabi-gdb
arm-none-linux-gnueabi-gdbtui arm-none-linux-gnueabi-gprof arm-none-linux-gnueabi-ld arm-none-linux-gnueabi-nm arm-none-linux-gnueabi-objcopy arm-none-linux-gnueabi-objdump arm-none-linux-gnueabi-ranlib arm-none-linux-gnueabi-readelf arm-none-linux-gnueabi-size arm-none-linux-gnueabi-sprite arm-none-linux-gnueabi-strings arm-none-linux-gnueabi-strip
arm-none-linux-gnueabi-c++filt
arm-none-linux-gnueabi-gcc-4.5.2
2. 测试工具链
编写一个简单的应用程序文件如 hello.c,然后在终端输入“arm-none-linux-gnueabi-gcc hello.c -o hello”,编译 hello.c,得到hello程序后,使用file命令查看其格式。
chenxibing@linux-compiler: ~$ arm-none-linux-gnueabi-gcc hello.c -o hello chenxibing@linux-compiler: ~$ file hello
hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.16, not stripped
如果得到如上信息,可知hello程序是ARM格式的文件,arm-none-linux-gnueabi-工具链已经可以正常使用了。
产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
18
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 4.1.4 NFS 服务器配置
NFS即网络文件系统(Network File-System),可以通过网络,让不同机器、不同系统之间可以实现文件共享。通过 NFS,可以访问远程共享目录,就像访问本地磁盘一样。NFS只是一种文件系统,本身并没有传输功能,是基于RPC(远程过程调用)协议实现的,采用C/S架构。
嵌入式Linux开发中,通常需要在主机上配置NFS服务器,将某系统特定目录共享给目标系统访问和使用。通过 NFS,目标系统可以直接运行存放于主机上的程序,可以减少对目标系统FLASH的烧写,既减少了对FLASH损害,同时也节省了烧写FLASH所花费的时间。
1. 添加NFS目录
修改/etc/exports文件,在其中增加NFS目录(需要root权限,请使用sudo命令)并指定访问主机的IP以及访问权限。
chenxibing@linux-compiler: ~$ sudo vi /etc/exports [sudo] password for chenxibing:
如增加/home/chenxibing/nfs 目录,并允许IP为192.168.1.*的任何系统进行NFS访问,增加内容如下:
/home/chenxibing/nfs 192.168.1.*(rw,sync,no_root_squash)
2. 启动NFS服务
同样需要root权限,执行sudo /etc/init.d/nfs-kernel-server start 或者restart命令,可以启动或者重新启动NFS服务:
chenxibing@linux-compiler: ~$ sudo /etc/init.d/nfs-kernel-server start
在NFS服务已经启动的情况下,如果修改/etc/exports了文件,可以重启NFS服务,刷新NFS共享目录,或者输入exports -rv命令重新导出NFS共享目录。
chenxibing@linux-compiler: ~$ sudo exportfs –rv
3. 测试NFS服务器
首先可以在主机上进行自测,将已经设定好的 NFS 共享目录mount到另外一个目录下,看能否成功。假定主机IP为192.168.1.138,NFS共享目录为/home/chenxibing/nfs可使用如下命令进行测试:
chenxibing@linux-compiler: ~$ sudo mount -t nfs 192.168.1.138:/home/chenxibing/nfs /mnt
如 果 指 令 运 行 没 有 出 出 错 , 则NFS挂 载 成 功 , 在/mnt目 录 下 应 该 可 以 看 到/home/chenxibing/nfs 目录下的内容。
启动工控板并进入Linux。将目标板接入局域网或者通过交叉网线与机直连,设定目标板的IP,使之与主机在同一网段,然后进行远程mount操作。
[root@IoT9608 ~]# ifconfig eth0 192.168.1.136 [root@IoT9608 ~]# ping 192.168.1.138
[root@IoT9608 ~]# mount -t nfs 192.168.1.138:/home/chenxibing/nfs /mnt -o nolock
在进行远程挂载之前,最好先用 ping 命令检查网络通信是否正常,只有在能ping通的情况下,才能进行正常挂载,否则请检查网络。如果在已经ping通的情况下,远程挂载出现错误,请检查主机和目标机的其它设置。
NFS基于RPC协议,进行NFS挂载,客户端需要运行portmap服务,如果出现“RPC:Timed 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
19
广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 out”的错误,则有可能是目标板尚未启动portmap服务。解决方法是在目标板启动portmap 服务:
[root@IoT9608 ~]# portmap&
4.2 Hello 程序
使用熟悉的文本编辑器,在 NFS 目录下,编写一个简单的程序,往端打印“Hello”字符串,程序清单 4.1 是一个简单范例。
程序清单 4.1 Hello程序
#include int i; for (i=0; i<5; i++) printf(\"Hello %d!\\n\return 0; 启动终端,进入hello程序文件所在目录,输入编译命令对hello.c进行编译: chenxibing@linux-compiler: hello$ a arm-arago-linux-gnueabi-gcc hello.c -o hello 编译完毕,将得到hello文件。 启动系统,进行NFS挂载,并进入hello程序所在目录,运行hello序。 [root@IoT9608 ~]# mount -t nfs 192.168.1.138:/home/chenxibing/nfs /mnt -o nolock [root@IoT9608 ~]# cd /mnt/hello [root@IoT9608 hello]# ./hello Hello 0! Hello 1! Hello 2! Hello 3! Hello 4! 如果需要固化hello程序,只需使用cp命令将hello文件复制到本目录即可。 [root@IoT9608 hello]# cp hello /opt 这是一个非常简单的程序,并且只有一个文件,所以可以采用直接输入命令进行交叉编译,如果工程较大,文件较多,这种方式就不可取了,通常需要编写Makefil文件,通make程序来进行工程管理。程序清单 4.2所示是一个简单的Makefile文件。 程序清单 4.2 应用程序Makefile范例 EXEC=hello OBJS=hello.o CROSS=arm-none-linux-gnueabi- CC=$(CROSS)gcc STRIP=$(CROSS)strip CFLAGS=-Wall -g -O2 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 20 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 all: clean $(EXEC) $(EXEC):$(OBJS) $(CC) $(CFLAGS) -o $@ $(OBJS) $(STRIP) $@ -rm -f $(EXEC) *.o clean: 有了合适的Makefile文件,只需在终端输入make命令即可编译程序。Makefile编写有详细规则,请参考其它书籍或者资料。 4.3 GPIO 使用 IoT-9608 支持 20 个用户可用 GPIO,原理图和 PCB 丝印如图 4.3 所示。 图 4.3 IoT-9608的GPIO原理图 各GPIO在Linux系统的序号分别如表 4.1所列。 表 4.1 GPIO列表 工位 丝印名称 P0.2 P0.3 P0.8 J9 P0.9 P0.10 P0.11 P1.28 P2.20 注:全部GPIO默认作为输入。 处理器 IO GPIO0_2 GPIO0_3 GPIO0_8 GPIO0_9 GPIO0_10 GPIO0_11 GPIO1_28 GPIO2_10 序号 gpio2 gpio3 gpio8 gpio9 gpio10 gpio11 gpio60 gpio74 GPIO的全部操作通过/sys/class/gpio目录下的文件来完成。该目录下提供了GPIO的相关操作接口。该目录下默认有如下文件: [root@IoT9608 ~]# cd /sys/class/gpio/ [root@IoT9608 gpio]# ls export gpio115@ gpio116@ gpio117@ gpio2@ gpio3@ gpio8@ gpiochip0@ gpiochip32@ gpiochip64@ gpiochip96@ unexport gpio10@ gpio11@ gpio114@ gpio60@ gpio74@ gpio75@ gpio87@ gpio89@ gpio9@ 需要操作某个GPIO,只需操作gpioN里面的文件即可。例如操作gpio22,首先进入 gpio22目录,查看里面可操作的文件: 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 21 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 [root@IoT9608 gpio]# cd gpio10 [root@IoT9608 gpio10]# ls active_low direction edge power/ subsystem@ uevent value direction用于设置或查询GPIO的方向,可能值为“in”或者“out”,分别表示输入或者输出;value表示GPIO的电平值,在输入模式下表示该引脚的电平(0 或者 1),在输出模式下表示写入该引脚的值(0或者1)。 操作I/O需要先设置方向,然后进行I/O操作。例如: [root@IoT9608 gpio10]# echo out > direction [root@IoT9608 gpio10]# echo 1 > value 如果作为输入引脚使用,则: [root@IoT9608 gpio10]# echo in > direction [root@IoT9608 gpio10]# cat value 1 4.4 蜂鸣器使用 IoT-9608板载一个交流蜂鸣器,通过PWM控制,设置占空比、频率后可以开启或者关闭蜂鸣器。 相关的操作接口在/sys/class/pwm/ecap.0目录下,涉及到如下几个文件:request、duty_percent 、period_freq、run其对应的功能如表 4.2所示。 表 4.2 蜂鸣器接口 接口 request duty_percent period_freq run 说明 获取/释放设备 设置占空比(%) 设置频率(HZ) 打开/关闭蜂鸣器 使用蜂鸣器前,须先往request文件系统写入1,然后将占空比如50%写入duty_percent文件,再将PWM发生频率如150Hz写入period_freq文件,最后往run写入1开启蜂鸣器, 写入0关闭蜂鸣器。操作范例: [root@IoT9608 ~]# cd /sys/class/pwm/ecap.0 [root@IoT9608 ecap.0]# echo 1 > request #请求获得蜂鸣器 [root@IoT9608 ecap.0]# echo 150 > period_freq #PWM 频率 150Hz [root@IoT9608 ecap.0]# echo 50 > duty_percent #PWM 占空比 50% [root@IoT9608 ecap.0]# echo 1 > run [root@IoT9608 ecap.0]# echo 0 > run #开启蜂鸣器 #关闭蜂鸣器 如果不再使用蜂鸣器,可往request文件写入0,释放蜂鸣器。 [root@IoT9608 ecap.2]# echo 0 > request #释放蜂鸣器 4.5 串口编程 IoT-9608上有10路串口,其中6路处理器自带串口,4路扩展串口,各串口在Linux系统中的设备名称如表 4.3所列。 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 22 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 表 4.3 串口列表 工作位 J8 印丝 TX1/RX1 TX3/RX3 TX4/RX4 功能 UART0(/dev/ttyO0) UART1(/dev/ttyO1) UART3(/dev/ttyO3) UART4(/dev/ttyO4) UART5(/dev/ttyO5) UART6(/dev/ttyS0) UART7(/dev/ttyS1) UART8(/dev/ttyS2) UART9(/dev/ttyS3) 备注 调试串口,RS232电平 TTL 电平 TTL 电平 TTL 电平 TTL 电平 TTL 电平 TTL 电平 TTL 电平 TTL 电平 J7 TX5/RX5 TX6/RX6 TX7/RX7 TX8/RX8 TX9/RX9 其中,TX2/RX2(即/dev/ttyO2)被用到MiniPCIE接口上,在PACK-CAN-UART转接板上, TX1~TX5是RS232接口,TX6~TX9是RS485串口,其对应串口号如表 4.4所示,其编程方法与RS232完全相同。 表 4.4 PACK-CAN-UART转接板串口列表 PACK-CAN-UART转接板丝印 TXD1/RXD1 TXD2/RXD2 TXD3/RXD3 TXD4/RXD4 A1/B1 A2/B2 A3/B3 A4/B4 IoT-9608工控板印丝 TX1/RX1 TX3/RX3 TX4/RX4 TX5/RX5 TX6/RX6 TX7/RX7 TX8/RX8 TX9/RX9 功能 UART1(/dev/ttyO1) UART3(/dev/ttyO3) UART4(/dev/ttyO4) UART5(/dev/ttyO5) UART6(/dev/ttyS0) UART7(/dev/ttyS1) UART8(/dev/ttyS2) UART9(/dev/ttyS3) 4.5.1 访问串口设备 1. 打开串口设备文件 在使用串口设备之前,我们需要先打开串口设备文件,获得串口设备文件描述符fd。在IoT-9608的Linux系统中,串口设备文件名是“/dev/ttyOn”和“/dev/ttySn”(其中n = 0、1、2、3……)。我们可以使用标准的open函数打开串口设备文件,程序清单 4.3所示。 程序清单 4.3 打开串口设备 fd = open(\"/dev/ttyOn\ if(iFd < 0) { } perror(cSerialName); exit(0); 2. open选项 当打开串口设备文件时,我们除了用到O_RDWR选项标志外,还使用到O_NOCTTY和O_NDELAY选项标志: 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 23 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 fd = open(\"/dev/ttyO1\ O_NOCTTTY选项标志是告诉Linux:本程序是不作为串口端口的“控制终端”。如果不作这样特别指出,会有一些输入字符(如一些产生中断信号的键盘输入字符等)影响进程。 O_NDELAY标志表示程序忽略DCD信号线。如果不加这标志选项,进程可能在DCD信号线被拉低时进入休眠。 3. 向串口设备写入数据 向串口设备写入数据使用标准的write系统调用,如程序清单 4.4所示。 程序清单 4.4 向串口设备写入数据 n =write(fd, \"hollow zlg \\r\if (n < 0) { } printf(\"write data to serial failed! \\n\"); 4. 从串口设备读取数据 当串口设备工作在原始数据模式时,每次read系统调用都返回串口驱动缓冲区里实际可用的数据。如果缓冲区没有数据可用,read系统调用等待到数据到来。这可能会堵塞进程。为了使read调用能立即返回,可以采用下面操作: fcntl(fd, F_SETFL, FNDELAY); FNDELAY选项会使read函数在串口没有数据到来的情况下立即返回。若要恢复正常状态,可以再次调用fcntl()而不带FNDELAY选项: fcntl(fd, F_SETFL, 0); 这些操作通常在完成open(带O_NDELAY选项)串口设备后执行。 5. 关闭串口设备 关闭串口设备仅需close系统调用: close(fd); 关闭一个串口设备通常会引起串口DTR信号线电平置高,使大部分的modem设备挂起。 4.5.2 配置串口接口属性 串口设备的波特率、数据位、校验方式等属性,是通过终端接口配置实现的。 1. 终端接口 终端属性用termios结构描述,如程序清单 4.5所示。 程序清单 4.5 termios结构 struct termios { }; tcflag_t c_cflag; tcflag_t c_iflag; tcflag_t c_oflag; tcflag_t c_lflag; /* 控制标志 */ /* 输入标志 */ /* 输出标志 */ /* 本地标志 */ /* 控制字符 */ tcflag_t c_cc[NCCS]; 简单来说,输入控制标志由终端设备驱动程序用来控制字符的输入(剥除输入字节的第产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 24 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 8位,允许输入奇偶校验等等),输出控制则控制驱动程序输出,控制标志影响到RS-232串行线,本地标志影响驱动程序和用户之间的接口(串口作为用户终端时)。 2. 获得和设置属性 使用函数tcgetattr和tcsetattr可以获得或设置termios结构,如程序清单4.6所示。 程序清单 4.6 设置和获得termios结构函数 #include int tcgetattr(int fd, struct termios *termptr); int tcsetattr(int fd, int opt, const struct termios *termptr); 上述两函数执行时,若成功中则返回0,若出错则返回-1。这两个函数都有一个指向termios 结构的指针作为其参数,它们返回当前串口的属性,或者设置该串口的属性。 在串口驱动程序里,有输入缓冲区和输出缓冲区。在改变串口属性时,缓冲区中的数据可能还存在,这时需要考虑到更改后的属性什么时候起作用。tcsetattr的参数opt使我们可以指定在什么时候新的串口属性才起作用。opt可以指定为下列常量中的一个: TCSANOW更改立即发生。 TCSADRAIN发送了所有输出后更改才发生。若更改输出参数则应用此选项。 TCSAFLUSH发送了所有输出后更改才发生。更进一步,在更改发生时未读的所有 输入数据被删除(刷清)。 3. 控制标志 c_cflag成员控制着波特率、数据位、奇偶校验、停止位以及流控制。表 4.5列出了c_cflag可用的部分选项。 表 4.5 c_flag部分可用选项 标志 CBAUD B0 B110 B134 B1200 B2400 B4800 B9600 B19200 B57600 B115200 B460800 CSIZE CS5 CS6 CS7 CS8 CSTOPB 波特率位屏蔽 0 位/秒(挂起) 100 位/秒 134 位/秒 1200 位/秒 2400 位/秒 4800 位/秒 9600 位/秒 19200 位/秒 57600 位/秒 115200 位/秒 460800 位/秒 数据位屏蔽 5 位数据位 6 位数据位 7 位数据位 8 位数据位 2 位停止位,否则为 1 位 说明 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 25 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 启动接收 进行奇偶校验 奇校验,否则为偶校验 最后关闭时断开 忽略调制调解器状态行 CREAD PARENB PARODD HUPCL CLOCAL c_cflag 成员有两选项通常是要启用的:CLOCAL和CREAD。这会程序启动接收字符装置,同时忽略串口信号线的状态。 标志选项 termios各成员的各个选项标志(除屏蔽标志外)都用一位或几位表示(设置或清除)表示,而屏蔽标志则定义多位,它们组合在一起,于是可以定义多个值。屏蔽标志有一个定义名,每个值也有一个名字。例如,为了设置字符长度,首先用字符长度屏蔽标志CSIZE将表示字符长度的位清0,然后设置下列值之一:CS5、CS6、CS7或CS8。 程序清单 4.7例示了怎样使用屏蔽标志或设置一个值。 程序清单 4.7 tcgetattr和tcsetattr实例 #include int main(void) { switch(term.c_cflag & CSIZE) { case CS5: printf(\"5 bits/byte \\n\"); break; printf(\"6 bits/byte \\n\"); break; printf(\"7 bits/byte \\n\"); break; if (tcgetattr(fd, &term) < 0) { } printf(\"tcgetattr error\"); exit(0); fd = open(\"/dev/ttyS0\ if(iFd < 0) { } perror(cSerialName); exit(0); struct termios term; int fd; case CS6: case CS7: 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 26 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 } case CS8: } term.c_cflag &= ~CSIZE; term.c_cflag |= CS8; if (tcsetattr(fd, TCSANOW, &term) < 0) { } return 0; printf(\"tcsetattr error\"); exit(0); printf(\"8 bits/byte \\n\"); break; printf(\"unknown bits/byte \\n\"); default: 设置波特率 cfsetispeed和cfsetospeed分别用于设置串口的输入和输出波特率,其具体的函数定义如下所示: #include int cfsetispeed(struct termios *termptr, speed_t speed); int cfsetospeed(struct termios *termptr, speed_t speed); 这两个函数若执行成功返回0,若出错则返回-1。 使用这两个函数时,应当理解输入、输出波特率是存在串口设备termios结构中的。在调用任一cfset函数之前,先要用tcgetattr获得设备的termios结构。与此类似,在调用任一cfset函数后,波特率都被设置到termios结构中。为使用这种更改影响到设备,应当调用tcsetattr函数。操作方法如程序清单 4.8所示。 程序清单 4.8 设置波特率示例 if (tcgetattr(fd, &opt)< 0) { } cfsetispeed(&opt, B9600); cfsetospeed(&opt, B9600); if (tcsetattr(fd, TCSANOW, &opt)<0) { } return ERROR; return ERROR; 设置数据位 设置数据位不需要专用的函数。在设置数据位之前,需要用数据位屏蔽标志(CSIZE)把数据位清零,然后设置数据位,如下所示: 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 27 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 */ options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; /* 先把数据位清零 /* 把数据位设置为8位 */ 设置奇偶校验 正如设置数据位一样,设置奇偶校验是在直接在cflag成员上设置。下面是各种类型的校验设置方法。 无奇偶校验(8N1) options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; 7位数据位奇偶校验(7E1) options.c_cflag |= PARENB; options.c_cflag &= ~PARODD; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS7; 奇校验(7O1) options.c_cflag |= PARENB; options.c_cflag |= PARODD; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS7; 4. 本地标志 本地标志c_lflag控制着串口驱动程序如何管理输入的字符。表 4.6所示的是c_lflag部分可用标志。 表 4.6 c_lflag标志 标志 ISIG ICANON XCASE ECHO ECHOE ECHOK ECHONL NOFLSH IEXTEN ECHOCTL ECHOPRT ECHOKE PENDIN TOSTOP 启用终端产生的信号 启用规范输入 规范大/小写表示 进行回送 可见擦除字符 回送 kill 符 回送 NL 在中断或退出键后禁用刷清 启用扩充的输入字符处理 回送控制字符为^(char) 硬拷贝的可见擦除方式 Kill 的可见擦除 重新打印未决输入 对于后台输出发送 SIGTTOU 说明 选择规范模式 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 28 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 规范模式是行处理的。调用read读取串口数据时,每次返回一行数据。当选择规范模式时,需要启用ICANON、ECHO和ECHOE选项: options.c_lflag |= (ICANON | ECHO | ECHOE); 当串口设备作为用户终端时,通常要把串口设备配置成规范模式。 选择原始模式 在原始模式下,串口输入数据是不经过处理的。在串口接口接收的数据被完整保留。要使串口设备工作在原始模式,需要关闭ICANON、ECHO、ECHOE和ISIG选项: options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); 5. 输入标志 c_iflag成员负责控制串口输入数据的处理。表 4.7所示是c_iflag部分可用标志。 表 4.7 c_iflag标志 标志 INPCK IGNPAR PARMRK ISTRIP IXON IXOFF IGNBRK INLCR IGNCR ICRNL 启用终端产生的信号 忽略奇偶错字符 标记奇偶错 剥除字符第 8 位 启用/停止输出控制流起作用 启用/停止输入控制流起作用 忽略 BREAK 条件 将输入的 NL 转换为 CR 忽略 CR 将输入的 CR 转换为 NL 说明 设置输入校验 当c_cflag成员的PARENB(奇偶校验)选项启用时,c_iflag的也应启用奇偶校验选项。操作方法是启用INPCK和ISTRIP选项: options.c_iflag |= (INPCK | ISTRIP); 值得注意的是IGNPAR选项在一些场合的应用带有一定的危险性,它是指示串口驱动程序忽略串口接口接收到的字符奇偶校验出错。也是说,IGNPAR使即使奇偶校验出错的字符也通过输入。这在测试通信链路的质量时也许有用,但在通常的数据通信应用中不应使用。 设置软件流控制 使用软件流控制是启用IXON、IXOFF和IXANY选项: options.c_iflag |= (IXON | IXOFF | IXANY); 相反,要禁用软件流控制是禁止上面的选项: options.c_iflag &= ~(IXON | IXOFF | IXANY); 6. 输出标志 c_oflag成员管理输出过滤。表 4.8所示的是c_oflag成员部分选项标志。 表 4.8 c_oflag标志 标志 说明 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 29 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 退格延迟屏蔽 标志或空奇偶性 CR 延迟屏蔽 换页延迟屏蔽 将输出的 CR 转换为 NL 填充符为 DEL,否则为 NULL 对于延迟使用填充符 将输出的小写字符转换为大写字符 将 NL 转换为 CR-NL NL 执行 CR 功能 在 0 列不输出 CR 执行输出处理 将制表符扩充为空格 BSDLY CMSPAR CRDLY FFDLY OCRNL OFDEL OFILL OLCUC ONLCR ONLRET ONOCR OPOST OXTABS 启用输出处理 启用输出处理是在c_oflag成员启用OPOST选项: options.c_oflag |= OPOST; 使用原始输出 使用原始输出,就是禁用输出处理。使用原始输出,数据能不经过处理、过滤地完整地输出到串口接口。操作方法: options.c_oflag &= ~OPOST; 当OPOST被禁止,c_oflag其它选项也被忽略。 7. 控制字符组 c_cc数组包含了所有可以更改的特殊字符。该数组长度是NCCS,一般是介于15-20之间。c_cc数组的每个成员的下标都用一个宏表示。表 4.9列出了c_cc的部分标志。 表 4.9 c_cc标志 标志 VINTR VQUIT VERASE VEOF VEOL VMIN VTIME 中断 退出 擦除 行结束 行结束 需读取的最小字符数 可以等待数据的最长时间 说明 VMIN和VTIME 在规范模式下,调用read读取串口数据时,通常是返回一行数据。而在原始模式下,串口输入数据是不分行的。 在原始模式下,返回读取数据的数量需要考虑两个变量:MIN和TIME。MIN和TIME在c_cc数组中的下标名为VMIN和VTIME。 MIN说明一个read返回前的最小字节数。TIME说明等待数据到达的分秒数(秒的1/10为分秒)。有下列四种情形: 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 30 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 当MIN > 0,TIME > 0时 TIME说明字节间的计时器,在接到第一个字节时才启动它。在该计时器超时之前,若已接到MIN个字节,则read返回MIN个字节。如果在接到MIN个字节之前,该计时器已超时,则read返回已接收到的字节(因为只有在接收到第一个字节时才启动,所以在计时器超时的时候,至少返回了1个字节)。这种情形中,在接到第一个字节之前,调用者阻塞。如果在调用read时数据已经可用,则这如同在read后数据立即被接到一样。 当MIN > 0,TIME == 0时 已经接到了MIN个字节时,read才返回。这可能会造成read无限期地阻塞。 当MIN == 0, TIME > 0时 TIME指定了一个调用read时启动的计时器,(与第一种情形是不同的,在第一种情形下,是在接收到第一个字节时,才启动定时器)在接到1字节或者该计时器超时,read即返回。如果是计时器超时,则read返回0。 当MIN == 0,TIME == 0时 如果有数据可用,则read最多返回所要求的字节数。如果无数据可用,则read立即返回0。 8. 实例 程序清单 4.9是原始模式下串口操作的实例。 程序清单 4.9 串口程序示例 #include #define DEV_NAME \"/dev/ttyO1\" int main(void) { iFd = open(DEV_NAME, O_RDWR |O_NOCTTY); if(iFd < 0) { } 31 perror(DEV_NAME); return -1; int iFd, i; int len; unsigned char ucBuf[1000]; struct termios opt; 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 } if (tcgetattr(iFd, &opt)<0) { } opt.c_lflag opt.c_iflag opt.c_oflag opt.c_cflag opt.c_cflag &= ~(ECHO | ICANON | IEXTEN | ISIG); &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); &= ~(OPOST); &= ~(CSIZE | PARENB); |= CS8; return -1; opt.c_cc[VMIN] = 255; opt.c_cc[VTIME] = 150; cfsetispeed(&opt, B115200); cfsetospeed(&opt, B115200); if (tcsetattr(iFd, TCSANOW, &opt)<0) { } tcflush(iFd,TCIOFLUSH); for (i = 0; i < 1000; i++){ } write(iFd, ucBuf, 0xff); len = read(iFd, ucBuf, 0xff); printf(\"get date: %d \\n\for (i = 0; i < len; i++){ } printf(\"\\n\"); close(iFd); return 0; printf(\" %x\ucBuf[i] = 0xff -i; return -1; 测试上述代码时,需要把“/dev/ttyO1”对应的RS-232接口的RXD和TXD用杜邦线短接起来。当程序执行时,程序在串口把发出去的数据完封不动地读回来,并打印出来。 4.5.3 获得和设置串口信号线状态 获得和设置串口信号线状态是通过对打开的串口设备文件描述符调用ioctl实现。程序清单 4.10是获取串口信号线状态的范例。 程序清单 4.10 设置串口信号线状态 #include 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 32 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 #include ioctl(fd, TIOCMGET, &status); 在该例子中,使用TIOCMGET命令调用ioctl把串口信号线状态存放在整形变量status中。该整形变量的各位含义如表 4.10所示。 表 4.10 TIOCM 标志 标志 TIOCM_LE TIOCM_DTR TIOCM_RTS TIOCM_ST TIOCM_SR TIOCM_CTS TIOCM_CAR TIOCM_CD TIOCM_RNG TIOCM_RI TIOCM_DSR DSR DTR RTS TXD RXD CTS DCD 等于 TIOCM_CAR RNG 等于 TIOCM_RNG DSR 说明 设置串口信号线状态需要使用 TIOCMSET 命令,如程序清单 4.11 所示。 程序清单 4.11 设置串口信号线状态 #include ioctl(fd, TIOCMGET, &status); status &= ~TIOCM_DTR; ioctl(fd, TIOCMSET, &status); 上述代码是把DTR信号线拉低。 4.6 Socket CAN编程 IoT-9608自带2路CAN接口,支持SocketCAN。下面对Socket CAN的使用进行一些介绍。 4.6.1 初始化CAN网络接口 在使用socket can之前,需要先设置CAN的波特率和激活CAN网络接口。可以使用参考下面的指令: [root@IoT9608~]#/sbin/ip link set can0 type can bitrate 1000000 #设置波特率为1M,当然也可以设置为其它的波特率 [root@IoT9608~]#ifconfig can0 up 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 33 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 完成之后,输入“ifconfig can0”命令就可以看到新添加的CAN网络接口: [root@IoT9608~]#ifconfig can0 can0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 UP RUNNING NOARP MTU:16 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:10 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) 这时我们就可以使用socket can了。 4.6.2 socket can编程 1. 创建套接字 就像TCP/IP协议一样,在使用CAN网络之前需要先打开一个套接字。CAN的套接字使用到了一个新的协议族,所以在调用socket(2)这个系统函数的时候需要将PF_CAN作为第一个参数。当前有两个CAN的协议可以选择:一个是原始套接字协议;另一个是广播管理协议。可以这样来打开一个套接字: s = socket(PF_CAN, SOCK_RAW, CAN_RAW); 或者 s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM); 2. 绑定CAN接口 在成功创建一个套接字之后,通常需要使用bin(2)函数将套接字绑定在某个指定的CAN接口上(这和TCP/IP使用不同的IP地址不同)。在绑定(CAN_RAW)或连接(CAN_BCM)套接字之后,就可以在套接字上使用read(2)/write(2),也可以使用send(2)/sendmsg(2)和对应的rev*操作。 基本的CAN帧结构和套接字地址结构定义在/include/linux/can.h,如程序清单 4.12所示。 程序清单 4.12 can_frame的定义 /* * 扩展格式识别符由 29 位组成。其格式包含两个部分:11 位基本 ID、18 位扩展 ID。 * Controller Area Network Identifier structure * * bit 0-28 : CAN识别符 (11/29 bit) * bit 29 : 错误帧标志 (0 = data frame, 1 = error frame) * bit 30 : 远程发送请求标志 (1 = rtr frame) * bit 31 :帧格式标志 (0 = standard 11 bit, 1 = extended 29 bit) */ typedef __u32 canid_t; */ struct can_frame { }; canid_t can_id; __u8 can_dlc; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ /* 数据长度: 0 .. 8 */ __u8 data[8] __attribute__((aligned(8))); 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 34 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 结构体的有效数据在data数组中,它的字节对齐是64bit的,所以用户可以比较方便的在data中传输自己定义的结构和共用体。CAN总线中没有默认的字节序。在CAN_RAW套接字上调用read(2),返回给用户空间的数据是一个struct can_frame的结构体。 就像PF_PACKET套接字一样,sockaddr_can结构体也有接口的索引,这个索引绑定了特定接口,如程序清单 4.13所示。 程序清单 4.13 struct sockaddr_can结构体 struct sockaddr_can { }; /* transport protocol class address info (e.g. ISOTP) */ struct { canid_t rx_id, tx_id; } tp; /* reserved for future CAN protocols address information */ } can_addr; sa_family_t can_family; int can_ifindex; union { 指定接口索引需要调用ioctl(),如程序清单 4.14所示。 程序清单 4.14 绑定接口 int s; struct sockaddr_can addr; struct ifreq ifr; s = socket(PF_CAN, SOCK_RAW, CAN_RAW); strcpy(ifr.ifr_name, \"can0\" ); ioctl(s, SIOCGIFINDEX, &ifr); addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; bind(s, (struct sockaddr *)&addr, sizeof(addr)); „„ 为了将套接字和所有的CAN接口绑定,接口索引必须是0。这样套接字就可以从所有使用的CAN接口接收CAN帧。revfrom(2)可以指定从哪个接口接收。在一个已经和所有CAN接口绑定的套接字上,sendto(2)可以指定从哪个接口发送。 3. 接收/发送帧 从一个CAN_RAW套接字上读取CAN帧也就是读取struct can_frame结构体,如程序清单 4.15所示。 程序清单 4.15 接收CAN帧 struct can_frame frame; nbytes = read(s, &frame, sizeof(struct can_frame)); if (nbytes < 0) { 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 35 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 } perror(\"can raw socket read\"); return 1; /* paranoid check ... */ if (nbytes < sizeof(struct can_frame)) { } /* do something with the received CAN frame */ /*写CAN帧也是类似的用到write(2)函数: */ nbytes = write(s, &frame, sizeof(struct can_frame)); fprintf(stderr, \"read: incomplete CAN frame\\n\"); return 1; 如果套接字跟所有的CAN接口都绑定了(addr.can_index = 0),推荐使用recvfrom(2) 获取数据源接口信息,程序清单 4.16所示。 程序清单 4.16 获取数据源接口信息 struct sockaddr_can addr; struct ifreq ifr; socklen_t len = sizeof(addr); struct can_frame frame; nbytes = recvfrom(s, &frame, sizeof(struct can_frame), 0, (struct sockaddr*)&addr, &len); /* get interface name of the received CAN frame */ ifr.ifr_ifindex = addr.can_ifindex; ioctl(s, SIOCGIFNAME, &ifr); printf(\"Received a CAN frame from interface %s\ 对于绑定了所有接口的套接字,向某个端口发送数据必须指定接口的详细信息,如程序清单 4.17所示。 程序清单 4.17 指定输出接口的详细信息 strcpy(ifr.ifr_name, \"can0\"); ioctl(s, SIOCGIFINDEX, &ifr); addr.can_ifindex = ifr.ifr_ifindex; addr.can_family = AF_CAN; nbytes = sendto(s, &frame, sizeof(struct can_frame), 0, (struct sockaddr*)&addr, sizeof(addr)); 4. 使用过滤器 在上面的阶绍中,我们从CAN接口中接收所有的数据帧,也不管我们是不是感兴趣。如果我们只想要指定ID的数据帧,那我们需要使用过虑器。 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 36 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 原始套接字选项CAN_RAW_FILTER CAN_RAW套接字的接收可以使用CAN_RAW_FILTER套接字选项指定的多个过滤规则。过滤规则定义在/include/linux/can.h中,如程序清单 4.18所示。 程序清单 4.18 can_filter的定义 struct can_filter { }; canid_t can_id; canid_t can_mask; 过滤规则的匹配: <接收帧id> & mask == can_id & mask 启用过滤器的示例如程序清单 4.19所示。 程序清单 4.19 启用过滤器示例代码 /* valid bits in CAN ID for frame formats */ #defineCAN_SFF_MASK0x000007FFU #define CAN_EFF_MASK 0x1FFFFFFFU /* 忽略EFF, RTR, ERR标志*/ struct can_filter rfilter[2]; rfilter[0].can_id= 0x123; rfilter[0].can_mask = CAN_SFF_MASK; rfilter[1].can_id= 0x200; rfilter[1].can_mask = 0x700; setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)); /* 标准帧格式(SFF) */ /* 扩展帧格式(EFF) */#defineCAN_ERR_MASK0x1FFFFFFFU 为了在指定的CAN_RAW套接字上禁用接收过滤规则,可以这样: setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0); 在一些极端情况下不需要读取数据,可以把过滤规则清零(所有成员为0),这样原始套接字就会忽略接到的CAN帧。 原始套接字选项CAN_RAW_ERR_FILTER CAN接口驱动可以选择性的产生错误帧,错误帧和正常帧以相同的方式传给应用程序。可能产生的错误被分不同的各类,使用适当的错误掩码可以过滤它们。为了注册所有可能的错误情况,CAN_ERR_MASK这个宏可以用来作为错误掩码。这个错误掩码定义在linux/can/error.h。 使用示例如下: can_err_mask_t err_mask = ( CAN_ERR_TX_TIMEOUT | CAN_ERR_BUSOFF ); setsockopt(s, SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &err_mask, sizeof(err_mask)); 4.6.3 示例程序 socket can的示例程序如程序清单 4.20所示。该程序是把接收到的指定ID的数据帧打印出来,然后把接收到的数据帧发送出去。 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 37 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 程序清单 4.20 socket can示例程序 #include #ifndef AF_CAN #define AF_CAN 29 #endif #ifndef PF_CAN #define PF_CAN AF_CAN #endif static void print_frame(struct can_frame *fr) { } #define errout(_s)fprintf(stderr, \"error class: %s\\n\#define errcode(_d) fprintf(stderr, \"error code: %02x\\n\ static void handle_err_frame(const struct can_frame *fr) { if (fr->can_id & CAN_ERR_TX_TIMEOUT) { } errout(\"CAN_ERR_TX_TIMEOUT\"); int i; printf(\"%08x\\n\//printf(\"%08x\\n\printf(\"dlc = %d\\n\printf(\"data = \"); for (i = 0; i < fr->can_dlc; i++) printf(\"%02x \printf(\"\\n\"); 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 38 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 } if (fr->can_id & CAN_ERR_LOSTARB) { } if (fr->can_id & CAN_ERR_CRTL) { } if (fr->can_id & CAN_ERR_PROT) { } if (fr->can_id & CAN_ERR_TRX) { } if (fr->can_id & CAN_ERR_ACK) { } if (fr->can_id & CAN_ERR_BUSOFF) { } if (fr->can_id & CAN_ERR_BUSERROR) { errout(\"CAN_ERR_BUSERROR\"); } if (fr->can_id & CAN_ERR_RESTARTED) { } errout(\"CAN_ERR_RESTARTED\"); errout(\"CAN_ERR_BUSOFF\"); errout(\"CAN_ERR_ACK\"); errout(\"CAN_ERR_TRX\"); errcode(fr->data[4]); errout(\"CAN_ERR_PROT\"); errcode(fr->data[2]); errcode(fr->data[3]); errout(\"CAN_ERR_CRTL\"); errcode(fr->data[1]); errout(\"CAN_ERR_LOSTARB\"); errcode(fr->data[0]); #define myerr(str)fprintf(stderr, \"%s, %s, %d: %s\\n\ static int test_can_rw(int fd, int master) { int ret, i; struct can_frame fr, frdup; struct timeval tv; 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 39 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 } fd_set rset; while (1) { } return 0; tv.tv_sec = 1; tv.tv_usec = 0; FD_ZERO(&rset); FD_SET(fd, &rset); ret = select(fd+1, &rset, NULL, NULL, NULL); if (ret == 0) { } /* select调用无错返回时,表示有符合规则的数据帧到达*/ ret = read(fd, &frdup, sizeof(frdup)); if (ret < sizeof(frdup)) { } if (frdup.can_id & CAN_ERR_FLAG) { /* 检查数据帧是否错误*/ } print_frame(&frdup);/* 打印数据帧信息*/ ret = write(fd, &frdup, sizeof(frdup));/* 把接收到的数据帧发送出去*/ if (ret < 0) { } myerr(\"write failed\"); return -1; handle_err_frame(&frdup); myerr(\"CAN device error\"); continue; myerr(\"read failed\"); return -1; myerr(\"select time out\"); return -1; int main(int argc, char *argv[]) { int s; int ret; struct sockaddr_can addr; struct ifreq ifr; 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 40 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 int master; srand(time(NULL)); s = socket(PF_CAN, SOCK_RAW, CAN_RAW);/* 创建套接字*/ if (s < 0) { } /* 把套接字绑定到can0接口*/ strcpy(ifr.ifr_name, \"can0\"); ret = ioctl(s, SIOCGIFINDEX, &ifr); if (ret < 0) { } addr.can_family = PF_CAN; addr.can_ifindex = ifr.ifr_ifindex; ret = bind(s, (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) { } /* 设置过滤规则*/ if (1) { struct can_filter filter[2]; /* 第1个规则是可以接收ID为0x200 & 0xFFF的数据帧*/ filter[0].can_id = 0x200 | CAN_EFF_FLAG; filter[0].can_mask = 0xFFF; /* 第2个规则是可以接收ID为0x20F & 0xFFF的数据帧*/ filter[1].can_id = 0x20F | CAN_EFF_FLAG; filter[1].can_mask = 0xFFF; /* 启用过滤规则,只要CAN0接收到的数据帧满足上面2个规则中的任何一个也被接受*/ ret = setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &filter, sizeof(filter)); if (ret < 0) { perror(\"setsockopt failed\"); perror(\"bind failed\"); return 1; perror(\"ioctl failed\"); return 1; perror(\"socket PF_CAN failed\"); return 1; 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 41 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 } } } return 1; test_can_rw(s, master);/*进入测试*/ close(s); return 0; 上述代码在编译后,可以使用广州致远电子股份有限公司的USBCAN或CANNET来测试。 4.7 看门狗使用 4.7.1 概述 Iot-9608有一个可编程看门狗(/dev/watchdog),可用于监测应用程序的运行状况。IoT-9608的看门狗默认超时时间为19秒,超时时间可设置(1~60秒)且不能关闭。其操作步骤如下: 1. 设置超时时间 看门狗默认超时时间为19秒,用户可以将超时时间设置为适合的值,通过ioctl实现,具体命令为:WDIOC_SETTIMEOUT,需要一个参数,即超时时间。使用示例: int timeout = 10; ioctl(wdt_fd, WDIOC_SETTIMEOUT, &timeout); 2. 获取超时时间 通过ioctl以及WDIOC_GETTIMEOUT命令,可以获得看门狗的超时时间。使用示例: timeout = 0; ioctl(wdt_fd, WDIOC_GETTIMEOUT, &timeout); printf(\"The timeout is %d seconds\\n\ 3. 喂狗操作 看门狗被打开后,必须在超时时间内进行喂狗,最简单的喂狗办法就是向看门狗写一个字符(特殊字符除外)。 4.7.2 范例 程序清单 4.21所示是一个非常简单的范例。打开看门狗后,将看门狗超时设置为10秒钟,然后在超时时间内周期性喂狗。运行该程序,系统不会复位。如果调整喂狗周期大于10秒,程序将会引起系统复位。 程序清单 4.21 看门狗用法简单范例 #include 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 42 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 { } //循环喂狗 while(1){ } return 0; write(wdt_fd, \"\\0\ sleep(9);//喂狗时间为9秒,小于10秒;如果喂狗时间大于超时时间,将会发生看门狗复位 timeout = 10; ioctl(wdt_fd, WDIOC_SETTIMEOUT, &timeout); ioctl(wdt_fd, WDIOC_GETTIMEOUT, &timeout); printf(\"The timeout was is %d seconds\\n\printf(WDT \" is opened!\\n\"); wdt_fd = open(WDT, O_WRONLY); if (wdt_fd == -1) { } printf(\"fail to open \"WDT \"!\\n\"); int wdt_fd = -1; int timeout; 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 43 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 5. 系统恢复和更新 5.1 制作SD卡 (1) 先安装HP USB Disk Storage Format Tool软件(安装文件为sp27213.exe)。 (2) 将SD卡插入USB读卡器,并插入电脑。打开软件,选择文件系统类型为FAT32, 并选择快速格式化(Quick Format),如图 5.1所示。 图 5.1 格式化设置 点击Start,开始格式化,确认后等待格式化完成。 (3) 首先将光盘images目录下的MLO复制到SD卡,然后卸载SD卡。 注意:MLO必须第一个被写到SD卡中! (4) 重新将SD卡插入电脑,将images目录下的其它文件复制到SD卡中(无顺序要求),复制完毕后卸载SD卡。 至此,用于恢复出厂固件的SD卡已经制作完成。 5.2 烧写Linux固件 (1) 安装好Tera Term软件,并设置好串口,115200,8n1(也可使用其它串口终端软件, 但是不推荐Windows自带的超级终端,有可能看不到从SD卡启动的输出信息)。 (2) 将串口延长线连接到底板COM0。 (3) 将制作好的SD卡插入底板SD卡插座,设置启动跳线设置CON21为SD卡启动(短接SD和BOOT),然后上电。 如果SD卡制作无误,将在串口看到U-Boot启动界面,在出现“Autobooting in 1 seconds. Enter \"zlg\" to interrupt Autoboot.”字符串的1秒钟之内,输入“zlg”,进入如图 5.2所示的U-Boot菜单界面。 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 44 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 图 5.2 U-Boot菜单界面 交互式菜单如下: [e] Erase NAND Flash [a] Burn all images [b] Burn bootloader [k] Burn kernel [l] Burn logo [r] Reboot [q] exit to cmdline 输入“a”,开始烧写全部固件,烧写完成后再次回到这个交互式界面。输入“r”重启系统。 5.3 升级某个固件 如果仅需更新bootloader、内核、LOGO,则可以单独进行升级更新。在U-Boot菜单界面,选择Burn bootloader、Burn kernel或者Burn logo可以单独更新bootloader、内核或者LOGO。 文件系统一般不需要更换,如果用户确实需要跟换文件系统,则可以重新制作ubifs文件系统并自己进行手动更新,把生成的rootfs.ubifs文件放到sd卡,然后进入开发板的U-Boot命令行模式,执行命令: # run burnsd_rootfs 如图 5.3所示,此时将自动把新的文件系统烧写到开发板上。 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 45 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 图 5.3 更换文件系统 5.4 全自动升级固件 U-Boot支持系统自动升级,只需在已经制作好的TF卡根目录,建立一个update的文件(不需要文件扩展名,空文件或者非空文件都可以)。短接看门狗跳线JP5和Boot跳线JP2(如果NAND能启动,也可以不短接Boot跳线),插上TF卡后重启,将会开始系统自动烧写,烧写完毕自动重启进入系统。 注意:用此方法,烧写完毕后,请立即取下TF卡,否则下次上电将会继续系统烧写。 5.5 其它 LOGO图片只能是8位位图。可在Windows下用画图工具另存为“256色位图“得到,由于颜色丢失带来的一些失真,可进行修复美化处理。 5.6 Tera Term使用说明 (1) 请先安装Tera Term软件。 (2) 创建串口连接。选择FileNew Connection,在弹出界面选择Serial,并下拉选择 合适的串口,如图 5.4所示。 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 46 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 图 5.4 串口连接 (3) 设置串口。选择SetupSerial port,在弹出界面进行串口设置(115200,8n1),如图 5.5所示。 图 5.5 串口设置 之后就可以使用串口了。为了方便下次建立新连接无需再次设置串口,可以将设置进行保存,选择SetupSave setup,然后点击“保存”即可,如图 5.6所示。 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 47 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 图 5.6 保存串口设置 (4) 由于某些原因,可能会出现乱码界面,此时请选择SetupTerminal,在弹出界面 点击OK,按键盘的回车键,刷新界面,界面显示将恢复正常,又或者选择FileDisconnect,先断开串口连接,然后重新选择FileNew Connection建立新连接也可行。 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 48 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 6. 免责声明 本文档提供有关致远电子产品的信息。本文档并未授予任何知识产权的许可,并未以明示或暗示,或以禁止发言或其它方式授予任何知识产权许可。除致远电子在其产品的销售条款和条件中声明的责任之外,致远电子概不承担任何其它责任。并且,致远电子对致远电子产品的销售和/或使用不作任何明示或暗示的担保,包括对产品的特定用途适用性、适销性或对任何专利权、版权或其它知识产权的侵权责任等,均不作担保。致远电子产品并非设计用于医疗、救生或维生等用途。致远电子可能随时对产品规格及产品描述做出修改,恕不另行通知。 IoT-9608套件可能包含某些设计缺陷或错误,一经发现将收入勘误表,并因此可能导致产品与已出版的规格有所差异。如客户索取,可提供最新的勘误表。 在订购产品之前,请您与当地的致远电子销售处或分销商联系,以获取最新的规格说明。本文档中提及的含有订购号的文档以及其它致远电子文献可通过访问广州致远电子股份有限公司的万维网站点获得,网址是: http://www.zlg.cn或致电+86-20-22644254查询。 Copyright © 2013, ZHIYUAN Electronics Stock Co., Ltd. 保留所有权利。 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 49 广州致远电子股份有限公司 IoT-9608 ARM嵌入式工业控制模块 销售与服务网络 广州致远电子股份有限公司 地址:广州市天河区车陂路黄洲工业区7栋2楼 邮编:510660 网址:www.zlg.cn 全国服务电话:400-888-4005 全国销售与服务电话:400-888-4005 销售与服务网络: 广州总公司 广州市天河区车陂路黄洲工业区7栋2楼 电话:(020)28267985 22644261 上海分公司:上海 上海市北京东路668号科技京城东楼12E室 电话:(021)53865521 53083451 北京分公司 北京市海淀区知春路108号豪景大厦A座19层 电话:(010)62536178 62635573 上海分公司:南京 南京市珠江路280号珠江大厦1501室 电话:(025)68123923 68123920 深圳分公司 深圳市福田区深南中路2072号电子大厦12楼 电话:(0755)83640169 83783155 上海分公司:杭州 杭州市天目山路217号江南电子大厦502室 电话:(0571)89719491 89719493 武汉分公司 武汉市洪山区广埠屯珞瑜路158号12128室(华中电脑数码市场) 电话:(027)87168497 87168397 重庆分公司 重庆市九龙坡区石桥铺科园一路二号大西洋国际大厦(赛格电子市场)2705室 电话:(023)68796438 68797619 成都分公司 成都市一环路南二段1号数码科技大厦403室 电话:(028)85439836 85432683 西安办事处 西安市长安北路54号太平洋大厦1201室 电话:(029)87881295 87881296 请您用以上方式联系我们,我们会为您安排样机现场演示,感谢您对我公司产品的关注! 产品用户手册 ©2015 Guangzhou ZHIYUAN Electronics Stock Co., Ltd. 50 因篇幅问题不能全部显示,请点此查看更多更全内容