Jack Huang's Blog


  • 首页

  • 标签

  • 归档

  • 搜索

树莓派学习之USB转串口

发表于 2018-11-05 | 更新于 2022-05-11

最近研究树莓派,需要通过usb转串口去连接树莓派,然后设置其wifi连接。于是将用到计算机硬件知识整理一下,并记录通过usb转串口设置树莓派wifi连接的过程。

硬件知识

计算机硬件常用接口有并口和串口,对应串行通信和并行通信。串行通信(英语:Serial communication)是指在计算机总线或其他数据信道上,每次传输一个比特数据,并连续进行以上单次过程的通信方式。与之对应的是并行通信,它在串行端口上通过一次同时传输若干比特数据的方式进行通信。

串行通信被用于长距离通信以及大多数计算机网络,在这些应用场合里,电缆和同步化使并行通信实际应用面临困难。凭借着其改善的信号完整性和传播速度,串行通信总线正在变得越来越普遍,甚至在短程距离的应用中,其优越性已经开始超越并行总线不需要串行化组件(serializer),并解决了诸如时钟偏移(Clock skew)、互联密度(interconnect density)等缺点。PCI到PCI Express的升级就一个例子。

并口

并行接口,简称并口。并口采用的是25针D形接头。所谓“并行”,是指8位数据同时通过并行线进行传送,这样数据传送速度大大提高,但并行传送的线路长度受到限制,因为长度增加,干扰就会增加,数据也就容易出错,目前,并行接口主要作为打印机端口等。

串口

串口叫做串行接口,也称串行通信接口,即COM口。按电气标准及协议来分包括RS-232-C、RS-422、RS485、USB等。 RS-232-C、RS-422与RS-485标准只对接口的电气特性做出规定,不涉及接插件、电缆或协议。

串行端口可以用于连接外置调制解调器、绘图仪或串行打印机。它也可以控制台连接的方式连接网络设备,例如路由器和交换机,主要用来配置它们。

  • RS-232-C

也称标准接口,是目前最常用的一种串行通讯接口。它是在1970年由美国电子工业协会(EIA)联合贝尔系统、 调制解调器厂家及计算机终端生产厂家共同制定的用于串行通讯的标准。

传统的RS-232-C接口标准有22根线,采用标准25芯D型插头座。自IBM PC/AT开始使用简化了的9芯D型插座。计算机一般有两个串行口:COM1和COM2,9针D形接口通常在计算机后面能看到。现在有很多手机数据线或者物流接收器都采用COM口与计算机相连。

  • RS-422

为改进RS-232通信距离短、速率低的缺点,RS-422定义了一种平衡通信接口,将传输速率提高到10Mb/s,传输距离延长到4000英尺(速率低于100kb/s时),并允许在一条平衡总线上连接最多10个接收器。

  • RS-485

为扩展应用范围,EIA又于1983年在RS-422基础上制定了RS-485 标准,增加了多点、双向通信能力,即允许多个发送器连接到同一条总线上,同时增加了发送器的驱动能力和冲突保护特性,扩展了总线共模范围,后命名为 TIA/EIA-485-A标准。

  • Universal Serial Bus(通用串行总线)

简称USB,是目前计算机上应用较广泛的接口规范,由Intel、Microsoft、Compaq、IBM、NEC、Northern Telcom等几家大厂商发起的新型外设接口标准。USB接口是计算机主板上的一种四针接口,其中中间两个针传输数据,两边两个针给外设供电。USB接口速度快、连接简单、不需要外接电源,传输速度12Mbps,新的USB 2.0可达480Mbps;电缆最大长度5米,USB电缆有4条线:2条信号线,2条电源线,可提供5伏特电源,USB电缆还分屏蔽和非屏蔽两种,屏蔽电缆传输速度可达12Mbps,价格较贵,非屏蔽电缆速度为1.5Mbps,但价格便宜;USB通过串联方式最多可串接127个设备;支持热插拔。最新的规格是USB 3.1。

  • RJ-45接口

是以太网最为常用的接口,RJ45是一个常用名称,指的是由IEC(60)603-7标准化,使用由国际性的接插件标准定义的8个位置(8针)的模块化插孔或者插头。

USB转串口原理

硬件接口电气特性

  • TTL电平:一般用作数字芯片的电平,例如芯片的供电电压是5V,那么高电平就是5V,低电平就是0V,这里所说的电平,就是TTL电平。

  • 232电平:232电平特制电脑串口的电平,-12V左右为正电平,+12V左右为低电平。我们刚才所见到的“USB转串口线”和电脑原生的串口,就是232电平。

USB转串口方法

PC的串口电气特性是232电平,单片机的串口电气特性是TTL电平,这两个就不一样,肯定需要某个芯片或者电路来进行转换匹配才可以通信。这个时候我们就需要TTL转232芯片了,常见的是MAX232,MAX3232等。连接方式如下:

232转TTL

但是随着USB接口的普及,当前计算机已经取消了串口。为实现232到TTL的转换,又需要USB转232。连接方式如下:

USB转232

为简化,可将USB转232和232转TTL集成到一个芯片上。这样的芯片常见的有CH340、PL2303。连接方式如下:

USB转TTL

常见的CH340芯片如下图所示:

USB转TTL

通过USB转串口连接树莓派

下面介绍在Debian Linux主机通过USB转串口连接树莓派的过程。

配置树莓派开启串口通信

将树莓派操作系统镜像烧录到SD卡后,打开boot分区,编辑其config.txt,在其末尾添加如下代码,以开启串口通信权限。

1
enable_uart=1

通过USB转串口物理连接树莓派

通过将USB转串口将Debian主机和树莓派物理连接好之后,给树莓派加电启动。

查看Debian系统能否识别ch340芯片

在官方Linux内核版本中自Kernel2.6以后就默认包含了对CH340/CH341芯片的驱动支持。在系统的默认驱动目录/lib/modules/$(uname -r)/kernel/drivers内可找到ch340芯片的驱动文件ch341.ko。

使用命令lsusb或dmesg查看linux系统是否识别USB转串口硬件。

1
2
3
4
5
6
7
8
~$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 005: ID 0bda:0129 Realtek Semiconductor Corp. RTS5129 Card Reader Controller
Bus 001 Device 004: ID 8087:0a2a Intel Corp.
Bus 001 Device 003: ID 1bcf:2b8a Sunplus Innovation Technology Inc.
Bus 001 Device 006: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
Bus 001 Device 002: ID 046d:c062 Logitech, Inc. M-UAS144 [LS1 Laser Mouse]
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Bus 001 Device 006: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter表明Linux系统识别了usb转串口线缆,芯片类型为HL-340。

‘dmesg’命令显示linux内核的环形缓冲区信息,我们可以从中获得诸如系统架构、cpu、挂载的硬件,RAM等多个运行级别的大量的系统信息。当计算机启动时,系统内核(操作系统的核心部分)将会被加载到内存中。在加载的过程中会显示很多的信息,在这些信息中我们可以看到内核检测硬件设备。运行dmesg,输出如下:

1
2
3
4
5
6
7
8
9
10
11
~$ sudo dmesg | tail
[ 4248.441104] usbcore: registered new interface driver usbserial_generic
[ 4248.441112] usbserial: USB Serial support registered for generic
[ 4248.456079] usbcore: registered new interface driver ch341
[ 4248.456088] usbserial: USB Serial support registered for ch341-uart
[ 4248.456097] ch341 1-3:1.0: ch341-uart converter detected
[ 4248.456464] usb 1-3: ch341-uart converter now attached to ttyUSB0
[ 4284.405593] i2c_hid i2c-ELAN1010:00: i2c_hid_get_input: incomplete report (14/65535)
[ 4284.407844] i2c_hid i2c-ELAN1010:00: i2c_hid_get_input: incomplete report (14/65535)
[ 4657.772761] i2c_hid i2c-ELAN1010:00: i2c_hid_get_input: incomplete report (14/65535)
[ 4657.774969] i2c_hid i2c-ELAN1010:00: i2c_hid_get_input: incomplete report (14/65535)

[ 4248.456097] ch341 1-3:1.0: ch341-uart converter detected;
[ 4248.456464] usb 1-3: ch341-uart converter now attached to ttyUSB0说明linux系统识别了usb转串口适配器,并附加到ttyUSB0文件上。

使用minicom连接树莓派

minicom是linux平台的串行通信程序,类似于windows的超级终端程序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$ usermod -a -G dialout $USER
#首次运行minicom使用-s选项,用于设置串行通信参数
$ minicom -s
+-----[configuration]------+
| Filenames and paths |
| File transfer protocols |
| Serial port setup |
| Modem and dialing |
| Screen and keyboard |
| Save setup as dfl |
| Save setup as.. |
| Exit |
| Exit from Minicom |
+--------------------------+
#通过上下键选择Serial port setup
+----------------------------------- +
| A - Serial Device : /dev/ttyUSB0 |
| B - Lockfile Location : /var/lock |
| C - Callin Program : |
| D - Callout Program : |
| E - Bps/Par/Bits : 115200 8N1 |
| F - Hardware Flow Control : Yes |
| G - Software Flow Control : No |
| |
| Change which setting? |
+----------------------------------+
# 设置Serial Device为/dev/ttyUSB0,然后推出到上一界面,使用enter键Save setup as dfl,保存配置。下次即可直接运行minicom使用之前保存的配置进行串口通信
# 这时候要选择单独Exit(退出),不要选择Exit from Minicom(退出Minicom),不然你就把minicom关了。
# 这时即可连接树莓派。

连接上树莓派后,输入用户名pi和密码raspberry,即可进入系统。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Raspbian GNU/Linux 9 raspberrypi ttyS0                                       
raspberrypi login: pi
Password:
Last login: Tue Oct 9 13:12:40 UTC 2018 on tty1
Linux raspberrypi 4.14.71-v7+ #1145 SMP Fri Sep 21 15:38:35 BST 2018 armv7l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.

Wi-Fi is disabled because the country is not set.
Use raspi-config to set the country before use.

pi@raspberrypi:~$

退出minicom,按Ctrl+A,再按下X键,会提示你是否退出,yes就可以了。

配置树莓派wifi连接

查看周围wifi热点信息

1
pi@raspberrypi:~$ iwlist scan

配置连接到wifi热点

1
2
3
4
5
6
7
8
9
10
11
12
# 编辑wifi文件
pi@raspberrypi:~$ sudo vi /etc/wpa_supplicant/wpa_supplicant.conf
# 在该文件最后添加下面的话
network={
  ssid="WIFINAME"
  psk="password"
}
# 引号部分分别为wifi的名字和密码
# 重启系统
pi@raspberrypi:~$ sudo init 6
# 登录后查看是否连接成功
pi@raspberrypi:~$ ip addr

参考文献

  1. https://www.cnblogs.com/zcshan/archive/2010/12/03/com.html ,by 水寒
  2. https://zh.wikipedia.org/wiki串行端口 , by wikipedia
  3. https://blog.csdn.net/he_wen_jie/article/details/50983076. by hwj666
  4. https://linux.cn/article-3587-1.html , by linux中国
  5. https://blog.csdn.net/JAZZSOLDIER/article/details/70170466 , by SoldierJazz2018
  6. http://blog.51cto.com/irinilu/289622, by feng9422
  7. Pipci. Linux 串口终端调试工具minicom[EB/OL].https://blog.csdn.net/Pipcie/article/details/79379451, 2018-02-26.
  8. https://blog.csdn.net/huayucong/article/details/51376279, by huayucong
  9. USB转串口CH340接线方法,2015-11-03.

树莓派操作系统镜像烧录方法指南

发表于 2018-11-03 | 更新于 2018-11-04

树莓派是一个微型计算机硬件平台,为使其正常工作还需要安装操作系统。通常将树莓派操作系统烧录到SD卡上,再将SD卡插到树莓派上。加电启动后,树莓派就会从SD卡引导启动操作系统,开始工作。这里SD卡就相当于普通计算机的硬盘。下面记录在Debian Linux下烧录树莓派操作系统到SD卡的方法。

镜像烧录工具

Etcher

Etcher是树莓派官方推荐的镜像烧录工具。它采用图形界面,支持Windows、Linux、Mac,使用简单方便,推荐普通用户使用。

dd

Linux的dd命令用于复制文件并对原文件的内容进行转换和格式化处理。dd命令功能很强大的,对于一些比较底层的问题,使用dd命令往往可以得到出人意料的效果。用的比较多的还是用dd来备份裸设备。同样也可用dd命令烧录系统镜像。

使用dd命令必须非常小心,如果输出指定了错误分区,将摧毁该分区的所有数据。

Linux下镜像烧录过程

使用Etcher烧录镜像比较简单,重点介绍使用dd命令烧录镜像的方法。

查找sd卡设备

可使用lsblk或者fdisk命令查找sd卡存储设备。需要注意的是:

  • 块设备以/dev/sdX命名,其中X是小写字母,例如/dev/sda。
  • 测试时发现当计算机只有usb3.0接口时,将不识别usb2.0的sd读卡器。

烧录镜像到sd卡

将镜像烧录到sd卡

使用如下dd命令将树莓派镜像少量到sd卡:

1
dd bs=4M if=2018-10-09-raspbian-stretch.img of=/dev/sdX conv=fsync

其中:

  • if=文件名:输入文件名,缺省为标准输入。即指定源文件。
  • of=文件名:输出文件名,缺省为标准输出。即指定目的文件。
  • bs=bytes:同时设置读入/输出的块大小为bytes个字节。
  • conv=conversion:用指定的参数转换文件。

将压缩镜像烧录到sd卡

当文件系统不支持大于4GB的文件时,可使用利用管道技术烧录镜像,命令如下:

1
unzip -p 2018-10-09-raspbian-stretch.zip | sudo dd of=/dev/sdX bs=4M conv=fsync

检查烧录进度

默认情况下dd命令不给出烧录进度信息,最新的dd提供status=progress选项给出进度信息,命令如下:

1
dd bs=4M if=2018-10-09-raspbian-stretch.img of=/dev/sdX status=progress conv=fsync

或者可使用dcfldd命令替换dd进行烧录操作。

检查镜像是否正确的烧录到sd卡

先使用dd命令将sd卡中内容复制到硬盘,在使用diff或者md5sum检查镜像文件与sd卡内容镜像之间的一致性。

之前dd命令烧录镜像到sd卡完成后会在shell中输出如下结果:

1
2
3
xxx+0 records in
yyy+0 records out
yyyyyyyyyy bytes (yyy kB, yyy KiB) copied, 0.00144744 s, 283 MB/s

xxx是我们需要的,表示读取xxx块记录烧录到sd卡,xxx乘以bs=4M应该等于原始镜像的大小。

使用如下命令复制sd卡内容到硬盘上:

1
2
# 经测试count命令没有其作用,该命令将整个sd内容复制到了硬盘,但我们期望只复制之前烧录到sd卡内容
dd bs=4M if=/dev/sdX of=from-sd-card.img count=xxx

如果from-sd-card.img文件大于原始镜像文件,那么先使用truncate命令将from-sd-card.img缩小到原始镜像文件的大小,命令如下:

1
truncate --reference 2018-10-09-raspbian-stretch.img from-sd-card.img

使用diff命令比较两者直接的一致性,如果不一致,可能烧录过程中有错误。

1
diff -s from-sd-card.img 2018-10-09-raspbian-stretch.img

使用sync命令强制将缓存写入硬盘,然后umount sd卡文件系统,最后移除sd卡。

参考文献

  1. https://www.raspberrypi.org/documentation/installation/installing-images/linux.md, by raspberrypi.
  2. https://blog.csdn.net/liumang_D/article/details/3899462, by liumang_d.
  3. https://linux.cn/article-8024-1.html, by linux中国
  4. https://www.jianshu.com/p/ff09ceffa816, by 二石兄.

树莓派学习笔记

发表于 2018-11-03 | 更新于 2018-12-20

WiringPi简介

WiringPi是应用于树莓派平台的GPIO控制库函数,WiringPi遵守GUN Lv3。wiringPi使用C或者C++开发并且可以被其他语言包转,例如python、ruby或者PHP等。WiringPi中的函数类似于Arduino的wiring系统,这使得熟悉arduino的用户使用wringPi更为方便。

树莓派具有26个普通输入和输出引脚。在这26个引脚中具有8个普通输入和输出管脚,这8个引脚既可以作为输入管脚也可以作为输出管脚。除此之外,树莓派还有一个2线形式的I2C、一个4线形式的SPI和一个UART接口。树莓派上的I2C和SPI接口也可以作为普通端口使用。如果串口控制台被关闭便可以使用树莓派上的UART功能。如果不使用I2C,SPI和UART等复用接口,那么树莓派总共具有8+2+5+2 =17个普通IO。

wiringPi包括一套gpio控制命令,使用gpio命令可以控制树莓派GPIO管脚。用户可以利用gpio命令通过shell脚本控制或查询GPIO管脚。wiringPi是可以扩展的,可以利用wiringPi的内部模块扩展模拟量输入芯片,可以使用MCP23x17/MCP23x08(I2C 或者SPI)扩展GPIO接口。另外可通过树莓派上的串口和Atmega(例如arduino等)扩展更多的GPIO功能。另外,用户可以自己编写扩展模块并把自定义的扩展模块集成到wiringPi中。WiringPi支持模拟量的读取和设置功能,不过在树莓派上并没有模拟量设备。但是使用WiringPi中的软件模块却可以轻松地应用AD或DA芯片。

I2C

I²C(Inter-Integrated Circuit)字面上的意思是集成电路之间,它其实是I²C Bus简称,所以中文应该叫集成电路总线,它是一种串行通信总线,使用多主从架构,由飞利浦公司在1980年代为了让主板、嵌入式系统或手机用以连接低速周边设备而发展。I²C的正确读法为“I平方C”(”I-squared-C”),而“I二C”(”I-two-C”)则是另一种错误但被广泛使用的读法。自2006年10月1日起,使用I²C协议已经不需要支付专利费,但制造商仍然需要付费以获取I²C从属设备地址。

设计说明

I²C只使用两条双向漏极开路(Open Drain)(串行数据(SDA)及串行时钟频率(SCL))并利用电阻将电位上拉。I²C允许相当大的工作电压范围,但典型的电压准位为+3.3V或+5v。

I²C的参考设计使用一个7比特长度的地址空间但保留了16个地址,所以在一组总线最多可和112个节点通信[a]。常见的I²C总线依传输速率的不同而有不同的模式:标准模式(100 Kbit/s)、低速模式(10 Kbit/s),但时钟频率可被允许下降至零,这代表可以暂停通信。而新一代的I²C总线可以和更多的节点(支持10比特长度的地址空间)以更快的速率通信:快速模式(400 Kbit/s)、高速模式(3.4 Mbit/s)。

虽然最大的节点数目是被地址空间所限制住,但实际上也会被总线上的总电容所限制住,一般而言为400 pF。

I²C通信

如上所述,参考设计为使用串行数据线(SDA)和串行时钟线(SCL)、拥有7bit寻址空间的总线。 总线上有两种类型角色的节点:

  • 主节点 - 产生时钟并发起与从节点的通信
  • 从节点 - 接收时钟并响应主节点的寻址

该总线是一种多主控总线,即可以在总线上放置任意多主节点。此外,在停止位(STOP)发出后,一个主节点也可以成为从节点,反之亦然。

总线上有四种不同的操作模式,虽然大部分设备只作为一种角色和使用其中两种操作模式:

  • 主节点发送 - 主节点发送数据给从节点
  • 主节点接收 - 主节点接收从节点数据
  • 从节点发送 - 从节点发送数据给主节点
  • 从节点接收 - 从节点接收主节点数据

一开始,主节点处于主节点发送模式,发送起始位(START),跟着发送希望与之通信的从节点的7bit位地址,最后再发送一个bit读写位,该数据位表示主节点想要与从节点进行读(1)还是写(0)操作。

如果从节点在总线上,它将以ACK字符比特位应答(低有效)该地址。主节点收到应答后,根据它发送的读写位,处于发送模式或者接收模式,从节点则处于对应的相反模式(接收或发送)。

地址和数据首先发送最高有效位。 起始位在SCL位高时,由SDA上电平从高变低表示;停止位在SCL为高时,由SDA上电平从低变高表示。其他SDA上的电平变化在SCL为低时发生。

如果主节点想要向从节点写数据,它将发送一个字节,然后从节点以ACK位应答,如此重复。此时,主节点处于主节点发送模式,从节点处于从节点接收模式。

如果主节点想要读取从节点数据,它将不断接收从节点发送的一个个字节,在收到每个字节后发送ACK进行应答,除了接收到的最后一个字节。此时,主节点处于主节点接收模式,从节点处于从节点发送模式。

此后,主节点要么发送停止位终止传输,要么发送另一个START比特以发起另一次传输(即“组合消息”)。

应用

I²C被应用在简单且其制造成本较传输速度更为重要的外设上。一些常见的应用如下:

  • 为了保存用户的设置而访问NVRAM芯片。
  • 访问低速的数字模拟转换器(DAC)。
  • 访问低速的模拟数字转换器(ADC)。
  • 改变监视器的对比度、色调及色彩平衡设置(视频数据通道)。
  • 改变音量大小。
  • 获取硬件监视及诊断数据,例如中央处理器的温度及风扇转速。
  • 读取实时时钟(Real-time clock)。
  • 在系统设备中用来打开或关闭电源供应。

I²C的另一个强大用途在于微控制器的应用,利用两根通用的输入输出接脚及软件的规划,可以让微控制器控制一个小型网络。

外设可以在系统仍然在运作的同时加入或移出总线,这代表对于有热插拔需求的设备而言是个理想的总线。

像I²C这样的总线之所以流行起来,是因为计算机工程师发现到对于集成电路设计而言,许多的制造成本源自于封装尺寸及接脚数量。更小的包装通常能够减少重量及电源的消耗,这对于移动电话及手持式计算机而言格外重要。

UART

在通信和计算机科学中,Serial communication是一个通用概念,泛指所有的串行的通信协议,如RS232、USB、I2C、SPI、1-Wire、Ethernet等。这里的串行(serial),是相对并行通信(parallel communication)来说的,如下图:

串行与并行通信

理解串行通信的概念之后,大家可能会有疑问:接收方接收到一长串的、表示0/1电平跳变的信号之后,怎么还原出有效的信息呢?有两种方法:

  • 发送端在发送串行数据的同时,提供一个时钟信号,并按照一定的约定(例如在时钟信号的上升沿的时候,将数据发送出去)发送数据,接收端根据发送端提供的时钟信号,以及大家的约定,接收数据。这就是常说的同步串行通信(Synchronous serial communication),I2C、SPI等有时钟信号的协议,都属于这种通信方式。本文不再详述。

  • 发送端在数据发送之前和之后,通过特定形式的信号(例如START信号和STOP信号),告诉接收端,可以开始(或者停止)接收数据了。与此同时,收发两方会约定一个数据发送的速度(就是大名鼎鼎的波特率),发送端在发送START信号之后,就按照固定的节奏发送串行数据,与此同时,接收端在收到START信号之后,也按照固定的节奏接收串行数据。这就是常说的异步串行通信(Asynchronous serial communication),我们本节的主角—-串口通信,就是这种通信方式。

UART(Universal Asynchronous Receiver/Transmitter) 即是规定编码格式、bit rate,产生通信所需的bit流的标准。

SPI

串行外设接口(Serial Peripheral Interface Bus,SPI),是一种用于短程通信的同步串行通信接口规范,主要应用于单片机系统中。类似I²C。 这种接口首先被Motorola(摩托罗拉)公司开发,然后发展成了一种行业规范。典型应用包含SD卡和液晶显示器。 SPI设备之间使用全双工模式通信,包含一个主机和一个或多个从机。主机产生待读或待写的帧数据,多个从机通过一个片选线路 决定哪个来响应主机的请求。 有时SPI接口被称作四线程接口,SPI准确来讲称为同步串行接口,但是与同步串行接口协议(SSI)不同,SSI是一个四线程 同步通信协议,但是使用差分信号输入同时仅提供一个单工通信信道。

接口

SPI总线规定了4个保留逻辑信号接口:

  • SCLK(Serial Clock):串列时脉,由主机发出
  • MOSI(Master Output,Slave Input):主机输出从机输入信号,由主机发出
  • MISO(Master Input,Slave Output):主机输入从机输出信号,由从机发出
  • SS(Slave Selected):选择信号,由主机发出,一般是低电位有效

尽管上面的引脚名称是最常用的,但在过去,有时会使用其他引脚命名约定,因此旧IC产品的SPI端口引脚名称可能有所不同。

1-Wire

1-Wire是Maxim子公司达拉斯半导体的专利技术,仅用单一信号线就可像I²C、SPI一样,传输时钟(clock)又传输数据(data),并且数据传输是双向的。1-Wire使用较低的数据传输速率,通常是用来沟通小型设备,如数字温度计。1-Wire有两种速率:标准模式16kbps,驱动模式142kbps。

单总线只有一根数据线。设备主机或从机通过一个漏极开路或三态端口连接至该数据线,这样允许设备在不发送数据时释放数据总线,以便总线被其它设备所使用。单总线端口为漏极开路其内部等效电路如下图所示。

单总线硬件接口示意图

参考文献

  1. 树莓派学习笔记——wiringPi简介、安装和管脚说明 , by xukai871105.
  2. I²C, by wikipedia.
  3. UART、RS232、TTL关系浅析, by 老狼.
  4. 串行外设接口,by wikipedia.
  5. 1-Wire,by wikipedia.
  6. 1-Wire单总线的基本原理,by ce123.
  7. 解析单总线协议(1-wire),by zhengqijun_.

Debian下编译QGroundControl源码

发表于 2018-11-01 | 更新于 2019-05-13

MAVLink(Micro Air Vehicle Link,微型空中飞行器链路通讯协议)是无人飞行器与地面站之间通讯,以及无人飞行器之间通讯最常用的协议。它已经在PX4、APM、PIXHAWK和Parrot AR.Drone飞控平台上进行了大量测试。

QGroundControl则是一种操纵基于MAVLink通信协议的无人机的跨平台地面站开源软件。下面记录在Debian Linux下从源码编译QGroundControl的过程。

下载源码

1
2
3
4
# 下载QGroundControl源码
git clone --recursive https://github.com/mavlink/qgroundcontrol.git
# 更新子模块
git submodule update

安装编译环境

  • 下载Qt社区版在线安装器,安装5.11.0版本的Qt,安装路径可在/opt下。
1
2
3
4
# 注意要选择安装5.9+以上版本的Qt,因为构建QGC时需要
# 运行qtcreater
$ cd /opt/Qt/Tools/QtCreator/bin/
$ ./qtcreator
  • 安装必要的包
1
sudo apt-get install speech-dispatcher libudev-dev libsdl2-dev
  • 解决编译时libQt5PositioningQuick.so.5不存在的bug
1
2
3
sudo apt-get install libqt5positioningquick5
sudo find /usr/ -name libQt5PositioningQuick.so.5
cp /usr/lib/x86_64-linux-gnu/libQt5PositioningQuick.so.5 /opt/Qt/5.10.0/gcc_64/lib/libQt5PositioningQuick.so.5
  • 将当前用户添加到dialout组,获取串口访问权限
1
2
# 运行QGroundControl需要当前用户拥有串口访问权限
sudo usermod -a -G dialout $USER

编译运行

打开Qt Creater,打开qgroundcontrol.pro工程,构建后运行,即可打开QGroundControl地面站软件。

参考链接

  1. https://blog.csdn.net/hebbely/article/details/79022799, by hebbely
  2. https://dev.qgroundcontrol.com/en/getting_started/, by Dronecode

Linux常用命令用法总结

发表于 2018-11-01 | 更新于 2025-01-17

记录一些常用的linux命令用法,以备查询。

文件管理

校验文件

下载的文件最好校验完整性,防止被人篡改。以sha256sum为例:

1
2
3
4
5
6
7
8
9
# 以下命令将生成树莓派映像的sha256哈希码,从树莓派官网复制该映像sha256哈希码,以便校验。
# 当然通常应该会提供映像的哈希码校验文件。

sha256sum 2018-10-09-raspbian-stretch.zip >2018-10-09-raspbian-stretch.zip.sha256sum

# 使用下面校验文件的完整性,如果成功则映像与官方一致,未被篡改。
# 注意被校验文件与校验文件应放在同一个目录。

sha256sum -c 2018-10-09-raspbian-stretch.zip.sha256sum

转换和复制文件命令

Linux的dd命令用于复制文件并对原文件的内容进行转换和格式化处理。

1
2
3
4
5
6
7
8
9
10
11
读指定物理扇区:
dd if=<源设备> of=<输出设备或文件> skip=<指定扇区值> bs=512 count=1

写指定物理扇区:
dd if=<输入设备或文件> of=<输出设备> seek=<指定扇区值> bs=512 count=1

读取sd启动扇区示例:
dd if=/dev/mmcblk0 of=mbrsd.data bs=512 count=1

制作光盘iso镜像
dd if=/dev/cdrom of=/home/hch/drone.iso status=progress conv=fsync

查找文件

1
2
3
4
5
# find基本语法:find [PATH] [option] [action]

find /usr/lib -name libQt5Xml.so
# 使用通配符
find /usr/lib -name "*ssl*"

查找文件内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# grep基本用法:
grep "let's find something" file.[txt,json,js,md,etc]

# 大小写不敏感搜索
grep -i "REact" compiler/apps/playground/app/index.tsx
grep -i "Operation not supported on socket" system.log

# 多模式搜索
grep -e "error" -e "404" system.log

# 统计字符串匹配次数
grep -c "React" compiler/apps/playground/app/index.tsx

# 文件夹递归搜索,-o 仅输出匹配行,-r 递归搜索目录及其子目录
grep -o -r "fs" node_modules | wc -l

批量处理指定文件

1
2
3
4
5
6
7
8
# Find all .txt files and delete them
find . -name "*.txt" | xargs rm

# Creates each directory listed in the file.
cat dirs.txt | xargs mkdir

# Compresses all .log files in the current directory
ls *.log | xargs gzip

批量转换文件格式

1
2
3
4
5
6
7
# 将png格式图像转换为jpg
# -1 – 告诉 ls 每行列出一个图像名称的选项标识
# -n – 指定最多参数个数,例子中为 1
# -c – 指示 bash 运行给定的命令
# ${0%.png}.jpg – 设置新转换的图像文件的名字,% 符号用来删除源文件的扩展名

ls -1 *.png | xargs -n 1 bash -c 'convert "$0" "${0%.png}.jpg"'

终端下载

1
2
3
4
5
6
7
8
9
10
11
12
# 逐条下载uri.txt文件中每一行uri
wget -i uri.txt

# 跳过前1000条再下载
awk 'NR>=1000' url.txt | wget -i -

# install proxy
wget --no-check-certificate https://raw.githubusercontent.com/jwchenzju/teddysunss/master/shadowsocks.sh

chmod +x shadowsocks.sh

./shadowsocks.sh 2>&1 | tee shadowsocks.log

终端中打开文件管理器

1
2
使用gnome文件管理器打开当前文件夹
nautilus ./

统计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 统计文件行数
wc -l file

统计某文件夹下文件的个数
ls -l |grep "^-"|wc -l

统计某文件夹下目录的个数
ls -l |grep "^d"|wc -l

统计文件夹下文件的个数,包括子文件夹里的
ls -lR|grep "^-"|wc -l

# 统计文件或文件夹大小
du -a -h -d 1 ./

# 统计文件状态信息
stat file.txt

压缩和解压文件

1
2
3
4
5
6
7
# tar命令
tar zxvf FileName.tar #解压
tar czvf FileName.tar DirName #压缩

# zip命令
unzip FileName.zip #解压
zip -r FileName.zip DirName #压缩

SSH 连接、远程上传下载文件

1
2
3
4
5
6
7
8
9
10
11
# SSH 远程登入 Ubuntu 机 
ssh username@192.168.0.1

# 将 文件/文件夹 从远程 Ubuntu 机拷至本地(scp)
scp -r username@192.168.0.1:/home/username/remotefile.txt remotefile.txt

# 将 文件/文件夹 从本地拷至远程 Ubuntu 机(scp)
scp -r localfile.txt username@192.168.0.1:/home/username/

# rsync大文件断电续传,远程服务器需安装rsync
rsync -P --rsh=ssh root@192.168.0.1:/root/fgdata.tar fgdata.tar

系统管理

修改用户

1
2
# 将用户$USER添加到dialout用户组,以获取串口访问权限
sudo usermod -a -G dialout $USER

特殊符号用法

1
2
3
4
5
6
7
8
9
#| 管道 (pipeline),是 UNIX 系统,基础且重要的观念。连结上个指令的标准输出,做为下个指令的标准输入。
who | wc -l

#! 惊叹号(negate or reverse),通常它代表反逻辑的作用,譬如条件侦测中,用 != 来代表"不等于"
#下例代表显示除了a0, a1 .... a9 这几个文件的其他文件。
ls a[!0-9]

#& 后台工作,单一个& 符号,且放在完整指令列的最后端,即表示将该指令列放入后台中工作。
tar cvfz data.tar.gz data > /dev/null &

系统服务管理

1
2
3
4
5
# service命令用于对系统服务进行管理,比如启动(start)、停止(stop)、重启(restart)、查看状态(status)等。
# service命令本身是一个shell脚本,它在/etc/init.d/目录查找指定的服务脚本,然后调用该服务脚本来完成任务。

# 查看系统所有服务状态
service --status-all

查询本机公网IP

1
2
curl ifconfig.me
curl ipinfo.io

查看环境变量

1
export

查看端口占用情况

1
2
3
4
5
6
7
8
lsof -i:8080:查看8080端口占用

netstat -tunlp | grep 端口号
-t (tcp) 仅显示tcp相关选项
-u (udp)仅显示udp相关选项
-n 拒绝显示别名,能显示数字的全部转化为数字
-l 仅列出在Listen(监听)的服务状态
-p 显示建立相关链接的程序名

Vim使用方法

  • 正向搜索字符串

在普通模式下,按下 / 键,然后输入你要查找的字符串,最后按下 Enter 键。

1
/function
  • 反向搜索字符串

与正向查找相似,使用 ? 键进行反向查找。

1
?error
  • 替换字符串

在命令模式下,替换字符串。

1
:%s/apple/orange/gc

参考链接

  1. 初窥Linux 之 我最常用的20条命令,by ljianhui.
  2. Linux的五个查找命令,by 阮一峰.
  3. shell脚本中一些特殊符号, by 阿笨猫.
  4. vultr proxy
  5. proxychains配置,by Verne.
  6. 10 Essential Terminal Commands Every Developer Should Know,by Trevor I. Lasn.
  7. Vim 查找字符串(超详细),by quanxiaoha.

使用tensorflow_object_detection_api训练自定义模型

发表于 2018-10-20 | 更新于 2018-10-21

近期研究目标对象检测和识别,发现谷歌开源的基于tensorflow的object detection api模型效果不错,于是git clone下来测试一下。下面记录我在debian linux上安装配置object detection api模型,构建自定义数据集,训练和测试object detection api模型的过程,以及整个过程中遇到的一下问题,需要注意的事项。

准备工作

docker安装

TensorFlow 程序在 GPU 上的运行速度通常要比在 CPU 上快得多,在系统满足NVIDIA 软件要求的前提下,推荐使用支持 GPU 的 TensorFlow。

官方推荐使用Docker简化TensorFlow的GPU支持配置,这样只需要linux主机安装好Nvidia GPU驱动即可。

  1. 安装docker
    安装docker的方法可参考链接1。

  2. 安装nvidia-docker

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # Add the package repositories
    curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
    curl -s -L https://nvidia.github.io/nvidia-docker/debian9/nvidia-docker.list | \
    sudo tee /etc/apt/sources.list.d/nvidia-docker.list
    sudo apt-get update

    # Install nvidia-docker2 and reload the Docker daemon configuration
    sudo apt-get install -y nvidia-docker2
    sudo service docker restart
  3. 下载最新支持GPU和Python3的tensorflow映像[2]

    1
    docker pull tensorflow/tensorflow:latest-gpu-py3
  4. 测试tensorflow映像

    1
    2
    docker run --runtime=nvidia -it --rm tensorflow/tensorflow:latest-gpu-py3 \
    python -c "import tensorflow as tf; print(tf.contrib.eager.num_gpus())"

下载TFModel库及其相关库

1
2
3
4
# 基于tensorflow的模型和例子
git clone https://github.com/tensorflow/models.git
# raccoon数据集,可参考其中生成TFRecord格式数据的方法
git clone https://github.com/datitran/raccoon_dataset.git

安装Python虚拟环境管理工具

1
2
3
4
# 具体安装配置过程参见链接3
sudo pip3 install virtualenv
sudo pip3 install virtualenvwrapper
mkvirtualenv object-detection --python=/usr/bin/python3# 创建python3虚拟环境

数据标注

以分类几何形状为例,收集相关图片后,需要对它们进行标注。推荐使用 LabelImg 进行标注,生成的文件是 PASCAL VOC 的 xml 格式。这个工具还可以加载标注文件,检查标注结果[3]。

1
2
3
4
5
6
7
8
9
git clone https://github.com/tzutalin/labelImg.git
workon object-detection
# 启动python3虚拟环境
workon object-detection
# 安装配置labelImg
sudo apt-get install pyqt5-dev-tools
sudo pip3 install -r requirements/requirements-linux-python3.txt
make qt5py3
python3 labelImg.py

除了标注图片,还需创建一个 .pbtxt 文件用来说明标注的分类。例如:

1
2
3
4
5
6
7
8
9
10
11
12
item {
id: 1
name: 'circle'
}
item {
id: 2
name: 'square'
}
item {
id: 3
name: 'triangle'
}

需要特别注意以下两点:

  • name 不支持直接写中文,需要 UTF-8 编码
  • id 从 1 开始编号,不能从 0 开始编号。

数据准备

标注好的数据是图片文件(.jpg)和标注文件(.xml),而 TensorFlow 不能直接用这些数据作为输入,还需要转成 TFRecord 格式。可采用两种方法生成TFRecord格式数据:

  • tensorflow/models中方法

项目中使用create_pascal_tf_record.py, create_pet_tf_record.py生成TFrecord 格式数据

  • raccoon_dataset中方法

项目中使用xml_to_csv.py把xml合并成一个CSV文件,使用split labels.ipynb 随机划分训练集和测试集,以及使用generate_tfrecord.py 生成相对应的 TFRecord 训练集和测试集。

1
2
3
4
5
6
7
8
9
workon object-detection
# 将生成geometry_labels.csv
python xml_to_csv.py
# 打开split labels.ipynb生产训练集train_labels.csv和测试集test_labels.csv
jupyter notebook
# 创建训练用TFRecord文件:
python generate_tfrecord.py --csv_input=data/train_labels.csv --output_path=training/geometry_train.record
# 创建测试用TFRecord文件:
python generate_tfrecord.py --csv_input=data/test_labels.csv --output_path=training/geometry_test.record

第二种方法比较直观,因此我采用第二种方法生产TFRecord数据。

安装配置

安装TFModel依赖

1
2
3
4
5
6
7
8
9
10
11
12
workon object-detection
# For CPU
pip install tensorflow
# For GPU
pip install tensorflow-gpu

pip install --user Cython
pip install --user contextlib2
pip install --user pillow
pip install --user lxml
pip install --user jupyter
pip install --user matplotlib

安装COCO API

1
2
3
4
git clone https://github.com/cocodataset/cocoapi.git
cd cocoapi/PythonAPI
make
cp -r pycocotools <path_to_tensorflow>/models/research/

编译Protobuf

1
2
3
4
5
6
# From tensorflow/models/research/
wget -O protobuf.zip https://github.com/google/protobuf/releases/download/v3.0.0/protoc-3.0.0-linux-x86_64.zip
unzip protobuf.zip

# From tensorflow/models/research/
./bin/protoc object_detection/protos/*.proto --python_out=.

添加库到PYTHONPATH

1
2
3
# From tensorflow/models/research/
# 每次调用TFModel的Object Detection API之前都要设置
export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim

安装测试

1
2
# if all tests is ok, the installation is no problem.
python object_detection/builders/model_builder_test.py

模型训练

数据准备

  1. 将label_map文件、训练用TFRecord文件、测试用TFRecord文件复制到tensorflow/models/research/object_detection/data文件夹下。
    1
    2
    3
    4
    5
    # 推荐的数据目录结构
    + data
    - geometry.pbtxt
    - geometry_test.record
    - geometry_train.record
  2. 下载COCO预训练模型用于迁移学习
    1
    2
    3
    # From tensorflow/models/research/object-detection
    wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2018_01_28.tar.gz
    tar -xvf ssd_mobilenet_v1_coco_2018_01_28.tar.gz
  3. 修改解压后模型文件夹中pipeline.config

解压ssd_mobilenet_v1_coco_2018_01_28模型后会看到一个 .config 文件,里面包含有模型的参数,训练的参数,评估的参数等。这里需要修改到的有,

  • 模型参数中的 num_classes,改成你的类别数,
  • 训练参数中的 fine_tune_checkpoint,采用迁移学习,这里路径的指向刚才下载的Pre-train模型,比如 ssd_mobilenet_v1_coco_11_06_2017/model.ckpt
  • train_input_reader 下面的 input_path,改成你的训练数据,例如 data/train.record。label_map_path,改成你的 pbtxt 文件路径,例如 data/object.pbtxt
  • eval_input_reader 下面的 input_path,也需要改成你的测试集,例如 data/test.record。同样,label_map_path,也改成你的 pbtxt 文件路径,例如 data/object.pbtxt
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    //pipeline.config修改示例
    model {
    ssd {
    num_classes: 3
    ...
    }
    }
    train_config {
    ...
    fine_tune_checkpoint: "object_detection/ssd_mobilenet_v1_coco_2018_01_28/model.ckpt"
    from_detection_checkpoint: true
    num_steps: 50000
    }
    train_input_reader {
    label_map_path: "object_detection/data/geometry.pbtxt"
    tf_record_input_reader {
    input_path: "object_detection/data/geometry_train.record"
    }
    }
    eval_input_reader {
    label_map_path: "object_detection/data/geometry.pbtxt"
    shuffle: false
    num_epochs: 1
    num_readers: 1
    tf_record_input_reader {
    input_path: "object_detection/data/geometry_test.record"
    }
    sample_1_of_n_examples: 1
    }

    训练数据

    在GPU上训练TFModel,与在CPU上训练TFModel相比,要快五倍左右,因此推荐在GPU上训练TFModel。
  1. 启动docker
    1
    2
    # 启动docker,并使用-v参数将目录/home/$USER挂载到容器上
    docker run --runtime=nvidia -v /home/$USER:/home/$USER -it tensorflow/tensorflow:latest-gpu-py3 bash
  2. 执行训练
    1
    2
    3
    4
    # From tensorflow/models/research/
    export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim
    # 开始训练
    python object_detection/model_main.py --pipeline_config_path=object_detection/ssd_mobilenet_v1_coco_2018_01_28/pipeline.config --model_dir=object_detection/ssd_mobilenet_v1_coco_2018_01_28/saved_model/ --num_train_steps=50000 --alsologtostderr
  3. 使用tensorboard查看训练进度
    1
    2
    # From tensorflow/models/research/
    tensorboard --logdir=object_detection/ssd_mobilenet_v1_coco_2018_01_28/saved_model/
    在CPU上训练只需执行第二步和第三步。

导出模型

1
2
# From tensorflow/models/research/
python object_detection/export_inference_graph.py --input_type=image_tensor --pipeline_config_path=object_detection/ssd_mobilenet_v1_coco_2018_01_28/pipeline.config --trained_checkpoint_prefix=object_detection/ssd_mobilenet_v1_coco_2018_01_28/saved_model/model.ckpt-50000 --output_directory=../../../../ssd_mobilenet_v1_coco_2018_01_28

运行完命令后模型就导出到 ssd_mobilenet_v1_coco_2018_01_28 文件夹中,其中的frozen_inference_graph.pb即是所需模型。 需要注意的是,参数中的 –trained_checkpoint_prefix 是需要指定到单个模型的,例如 model.ckpt-50000,这个50000就是训练了 50000 步后自动保存模型。

参考文献

  1. https://huangwang.github.io/2018/10/18/Debian-Linux下安装Docker的方法/, by jack huang
  2. https://www.tensorflow.org/install/docker?hl=zh-cn , by tensorflow.
  3. https://huangwang.github.io/2018/10/09/Virtualenv简易教程/ , by jack huang
  4. https://laddiexu.github.io/tech/2017/11/04/TF-ODYourData.html , by 菁菁者莪
  5. https://blog.csdn.net/xunan003/article/details/78720189?utm_source=blogxgwz2, by xunan003

Docker使用帮助

发表于 2018-10-19 | 更新于 2018-10-20

Docker是一个开放源代码软件项目,让应用程序布署在软件容器下的工作可以自动化进行,借此在Linux操作系统上,提供一个额外的软件抽象层,以及操作系统层虚拟化的自动管理机制。

Docker与传统虚拟机如virtualbox、vmware相比,占用资源少,更加轻便,启动快,更适用于解决软件环境配置难题。

基本概念

  1. 镜像

    Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

  2. 容器

镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

  1. 仓库

镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。

一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。

通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。

使用方法

操作镜像

获取镜像

Docker Hub 上有大量的高质量的镜像可以用,使用docker pull命令拉取镜像。

1
2
3
4
// 拉取镜像
$ docker pull ubuntu:16.04
// 以该镜像启动容器
$ docker run -it --rm ubuntu:16.04 bash

docker run 就是运行容器的命令,其参数含义如下:

  • -it:这是两个参数,一个是 -i:交互式操作,一个是 -t 终端。我们这里打算进入 bash 执行一些命令并查看返回结果,因此我们需要交互式终端。
  • –rm:这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动 docker rm。
  • ubuntu:16.04:这是指用 ubuntu:16.04 镜像为基础来启动容器。
  • bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 bash。

列出镜像

1
docker image ls

删除镜像

删除本地镜像格式如下:

1
docker image rm [选项] <镜像1> [<镜像2> ...]

以删除hello-world镜像为例:

1
docker image rm hello-world

操作容器

启动容器

1
2
3
4
// 新建并启动容器
docker run ubuntu:14.04 /bin/echo 'Hello world'
// 启动已终止容器
docker container start

后台运行

1
2
3
4
5
6
7
// 后台运行容器
$ docker run -d ubuntu:17.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"
// 通过 docker container ls 命令来查看容器信息
$ docker container ls

// 通过 docker container logs 命令获取容器的输出信息
$ docker container logs [container ID or NAMES]

终止容器

1
docker container stop

进入容器

在使用 -d 参数时,容器启动后会进入后台。

某些时候需要进入容器进行操作,包括使用 docker attach 命令或 docker exec 命令,推荐大家使用 docker exec 命令。

1
2
3
4
$ docker run -dit ubuntu
$ docker container ls
$ docker exec -i 69d1 bash
$ docker exec -it 69d1 bash

如果从这个 stdin 中 exit,不会导致容器的停止。这就是为什么推荐大家使用 docker exec 的原因。

删除容器

1
2
3
4
5
// 删除一个处于终止状态的容器
$ docker container rm trusting_newton

// 清理所有处于终止状态的容器
docker container prune

参考文献

  1. https://yeasy.gitbooks.io/docker_practice/introduction/what.html
  2. http://www.ruanyifeng.com/blog/2018/02/docker-tutorial.html ,by 阮一峰
  3. https://zh.wikipedia.org/wiki/Docker ,by wikipedia.

Debian_Linux下安装Docker的方法

发表于 2018-10-18

Docker是一个开放源代码软件项目,让应用程序布署在软件容器下的工作可以自动化进行,借此在Linux操作系统上,提供一个额外的软件抽象层,以及操作系统层虚拟化的自动管理机制。

Docker利用Linux核心中的资源分离机制,例如cgroups,以及Linux核心名字空间(name space),来创建独立的软件容器(containers)。这可以在单一Linux实体下运作,避免启动一个虚拟机造成的额外负担。Linux核心对名字空间的支持完全隔离了工作环境中应用程序的视野,包括进程树、网上、用户ID与挂载文件系统,而核心的cgroup提供资源隔离,包括CPU、存储器、block I/O与网上。

下面即记录在Debian Linux下按照Docker社区版的方法。

前期准备

添加Docker的pgp key。

1
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -

配置Docker的Apt仓库。

1
echo 'deb https://download.docker.com/linux/debian stretch stable' | sudo tee /etc/apt/sources.list.d/docker.list

更新Apt仓库

1
sudo apt-get update

安装Docker

1
2
3
4
5
6
// 清除之前安装的Docker版本
apt-get remove docker docker-engine docker.io
// 在安装最新的Docker社区版
apt-get install docker-ce
// 测试docker
docker run hello-world

以非root用户管理docker

1
2
sudo groupadd docker
sudo usermod -aG docker $USER

参考文献

  1. https://zh.wikipedia.org/wiki/Docker ,by wikipedia.

tensorflow学习笔记

发表于 2018-10-14 | 更新于 2022-02-05

TensorFlow™ 是一个开放源代码软件库,用于进行高性能数值计算。借助其灵活的架构,用户可以轻松地将计算工作部署到多种平台(CPU、GPU、TPU)和设备(桌面设备、服务器集群、移动设备、边缘设备等)。TensorFlow™ 最初是由 Google Brain 团队(隶属于 Google 的 AI 部门)中的研究人员和工程师开发的,可为机器学习和深度学习提供强力支持,并且其灵活的数值计算核心广泛应用于许多其他科学领域。

tensorflow入门

tensorflow实现机器学习的基本步骤如下:

  1. 定义模型,建立数据流图
  2. 定义loss,并指定优化器
  3. 传入数据并进行训练
  4. 使用测试集进行评测

通用代码框架

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import tensorflow as tf

# 初始化变量和模型参数,定义训练闭环中的运算

def inference(X):
# 计算推断模型在数据X上的输出,并将结果返回

def loss(X,Y):
# 依据训练数据X及其期望输出Y计算损失

def inputs():
# 读取或生成训练数据X及其期望输出Y

def train(total_loss):
# 依据计算的总损失训练或调整模型参数

def evaluate(sess,X,Y):
# 对训练得到的模型进行评估

# 在一个会话对象中启动数据流图,搭建流程
with tf.Session() as sess:
tf.initialize_all_variables().run()

X,Y=inputs()

total_loss=loss(X,Y)
train_op=train(total_loss)

coord=tf.train.Coordinator()
threads=tf.train.start_queue_runners(sess=sess,coord=coord)

# 实际的训练迭代次数
training_steps=1000
for step in range(training_steps):
sess.run([train_op])
# 出于调试和学习的目的,查看损失在训练过程中递减的情况
if step % 10 =0:
print "loss: ",sess.run([total_loss])

evaluate(sess,X,Y)

coord.request_stop()
coord.join(threads)
sess.close()

保存训练检查点

借助tf.train.Saver类可创建检查点文件,将数据流图中变量保存至其中。修改后框架如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 模型定义代码
# 创建一个Saver对象
saver=tf.train.Saver()

# 在会话对象中启动数据流图,搭建流程
with tf.Session() as sess:
# 模型设置

# 实际的训练闭环
for step in range(training_steps):
sess.run([train_op])

if step % 1000 ==0
# 将创建遵循命名模板为my-model-{step}的检查点文件,默认保存最近的5个文件
saver.save(sess,'my-model',global_step=step)

# 模型评估

saver.save(sess,'my-model',global_step=training_steps)
sess.close()

如果希望从检查点恢复,则使用tf.train.get_checkpoint_state方法验证检查点文件的存在,并使用tf.train.Saver.restore方法恢复变量值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
with tf.Session() as sess:
# 模型设置

initial_step=0

# 验证之前是否已经保存了检查点文件
ckpt=tf.train.get_checkpoint_state(os.path.dirname(__file__))
if ckpt and ckpt.model_checkpoint_path:
# 从检查点恢复模型参数
saver.restore(sess,ckpt.model_checkpoint_path)
initial_step=int(ckpt.model_checkpoint_path.rsplite('_',1)[1])

# 实际的训练闭环
for step in range(initial_step, training_steps):
...

参考文献

  1. TensorFlow指南,by tensorflow.
  2. 尝试理解 shape 的用法,by mcoder.
  3. Python中的列表(list),元组(Tuple),字典(Dict)和集合(Set),by liuyanfeier.
  4. 使用list和tuple,by liaoxuefeng.
  5. Python的reshape(-1,1),by lxlong89940101.
  6. numpy.array,by numpy.
  7. TensorFlow 官方文档中文版,by pythontab.
  8. numpy.array shape (R, 1) and (R,) 的区别,by 时间被海绵吃了2.
  9. tf.variable_scope中的reuse,by 超级无敌小小顺利.
  10. Tensorflow共享变量机制理解与应用,by BetterManPeter.
  11. tf.reduce_mean()函数解析(最清晰的解释),by 我是管小亮.
  12. 深度解析OPENAI-MADDPG,by 起点教程.
  13. diagonal Gaussian policies的一些理解,by Intuition.
  14. 强化学习随机策略之高斯似然数原理与代码实现,by 神奇的战士.
  15. 数学基础——浅谈似然,by shidata.
  16. gym中的discrete类、box类和multidiscrete类简介和使用,by iitter.
  17. OPENAI Baeslines 详解(零)综述,by zachary2wave.
  18. 强化学习Gym库学习实践(一),by 愣娃RC.
  19. Gym使用简介,by Lisnol.
  20. 左右互搏,self-play,《Emergent Complexity via Multi-Agent Competition》,by 王小惟 Weixun.
  21. 多智能体深度强化学习——MADDPG算法代码分析(tensorflow),by RavenRaaven.
  22. 多元高斯分布以及高斯分布微分熵,by 侠肝义胆陈浩天.
  23. tf.split 与 tf.squeeze 用法,by 应钟有微.
  24. 碎片化学习之数学(二):Categorical Distribution,by 李新春.
  25. Distribution is all you need:这里有12种做ML不可不知的分布,by 机器之心.
  26. tensorflow中axis理解非常重要,by 爱视觉.
  27. tensorflow中四种不同交叉熵函数tf.nn.softmax_cross_entropy_with_logits(),by iotstu.
  28. TF里几种loss和注意事项,by 崔权.
  29. Softmax函数和Sigmoid函数的区别与联系初识CV,by 初识CV.
  30. 损失函数|交叉熵损失函数,by 飞鱼Talk.
  31. tf.random_uniform的使用,by UESTC_C2_403.
  32. sparse_softmax_cross_entropy_with_logits与softmax_cross_entropy_with_logits,by 光彩照人.
  33. 关于LogSumExp,by Hurry Z.
  34. softmax 与 log sum exp,by 我要给主播生猴子.

Python常用库简介

发表于 2018-10-14 | 更新于 2018-12-05

Python的高效开发建立在大量常用库基础上,因此掌握常用的Python库十分必要。下面简单介绍Python的各类常用库。

常用标准库

  • os: 访问操作系统功能模块
  • sys: 访问一些环境变量和与 Python 解释器交互
  • datetime: 日期时间处理
  • collections: 高级数据结构,有序字典,队列等等
  • uuid: 生成 UUID 模块
  • random: 随机数生成模块
  • re: 正则表达式模块
  • json: JSON 处理模块
  • pdb: 单步调试模块

科学计算

  • scipy:基于Python的matlab实现,旨在实现matlab的所有功能。包含Numpy、Ipython、Pandas、Matplotlib、Sympy等常用库
  • numpy: 基于Python的科学计算第三方库,提供了矩阵,线性代数,傅立叶变换等等的解决方案
  • pandas: 支持表格等多维数据
  • matplotlib: 用Python实现的类matlab的第三方库,用以绘制一些高质量的数学二维图形

命令交互

  • ipython: 交互命令行,适合科学计算
  • jupyter: ipython notebook 的延伸,可以直接放在github上
  • argparse:(Python 标准库)用于命令项选项与参数解析的模块

爬虫相关

  • urllib: (Python 标准库),接受URL请求的相关模块
  • http: (Python 标准库),处理所有客户端–服务器http请求的具体细节
  • requests: 第三方库,人性化的HTTP请求库,比urllib更好用
  • pillow: 处理验证码
  • rsa: 处理加密问题
  • BeautifulSoup:解析html文档为用户提供需要抓取的数据
  • lxml: 是基于 libxml2 这一 XML 解析库的 Python 封装,解析速度比 Beautiful Soup 更快

环境管理

  • virtualenv:创建独立 Python 环境的工具
  • virtualenvwrapper:virtualenv 的一组扩展

包管理

  • pip:Python 包和依赖关系管理工具
  • conda:跨平台,Python 二进制包管理工具

并发和并行

  • threading:(Python 标准库)更高层的线程接口
  • multiprocessing:(Python 标准库) 基于进程的“线程”接口

日志

  • logging:(Python 标准库) 为 Python 提供日志功能。

兼容性

  • six:Python 2 和 3 的兼容性工具

计算机视觉

  • opencv

机器学习

  • tensorflow

参考文献

  1. Python 笔记四:Python的常用库收集, by brandonxiang
上一页1…495051…54下一页

Jack Huang

535 日志
69 标签
© 2026 Jack Huang
由 Hexo 强力驱动
|
主题 — NexT.Muse