<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>树莓派 &#8211; 编码无悔 /  Intent &amp; Focused</title>
	<atom:link href="https://www.codelast.com/tag/%e6%a0%91%e8%8e%93%e6%b4%be/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.codelast.com</link>
	<description>最优化之路</description>
	<lastBuildDate>Sun, 06 Sep 2026 17:55:06 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1</generator>
	<item>
		<title>[原创] 通过串口终端连接树莓派(CH340)</title>
		<link>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e9%80%9a%e8%bf%87%e4%b8%b2%e5%8f%a3%e7%bb%88%e7%ab%af%e8%bf%9e%e6%8e%a5%e6%a0%91%e8%8e%93%e6%b4%bech340/</link>
					<comments>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e9%80%9a%e8%bf%87%e4%b8%b2%e5%8f%a3%e7%bb%88%e7%ab%af%e8%bf%9e%e6%8e%a5%e6%a0%91%e8%8e%93%e6%b4%bech340/#respond</comments>
		
		<dc:creator><![CDATA[learnhard]]></dc:creator>
		<pubDate>Sun, 06 Sep 2026 17:55:06 +0000</pubDate>
				<category><![CDATA[Raspberry Pi/树莓派]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[CH340]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[串口]]></category>
		<category><![CDATA[树莓派]]></category>
		<guid isPermaLink="false">https://www.codelast.com/?p=14268</guid>

					<description><![CDATA[<section data-tool="markdown2wechat编辑器" data-website="https://aizhuanqian.com" id="nice" style="font-size: 16px; padding: 0px 10px; line-height: 1.6; letter-spacing: 0px; word-break: break-word; overflow-wrap: break-word; font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &#34;PingFang SC&#34;, Cambria, Cochin, Georgia, Times, &#34;Times New Roman&#34;, serif;">
<ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px;">
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);">背景：你是否遇到过&#34;树莓派的WiFi连不上网络，有线连接树莓派也不具备条件&#34;的情况？这个时候，你想通过终端连接到树莓派上还剩下哪些选择？串口就是其中一个可行的办法。对大多数人来说，这种连接方法都算比较少见，但它确实是一个在网络断链时的好方法。</section>
</li>
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);">目标：让 macOS 通过 USB-TTL (CH340) 模块连接树莓派 GPIO 串口，获得一个<strong style="font-weight: bold; color: black;">完全不依赖网络</strong>的终端/登录通道（等同于 SSH 控制台，但走串口线）。</section>
</li>
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);">树莓派版本：3B Rev 1.2</section>
</li>
</ul>
<hr data-tool="mdnice编辑器" style="height: 1px; margin: 0; margin-top: 10px; margin-bottom: 10px; border: none; border-top: 1px solid black;" />
<h2 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 22px;">
	<span class="content">1. 先认识 CH340 模块：它是什么，能帮我们做什么</span></h2>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 20px;">
	<span class="content">1.1 CH340 是什么</span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	CH340 是一颗国产的&#34;USB 转串口&#34;芯片（这类芯片也常被叫做 USB-UART 桥接芯片）。市面上卖的那种USB-TTL 小板，核心就是这颗芯片，板上通常还会引出一排针脚，标着 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">VCC / 5V / 3V3 / TXD / RXD / GND</code>。<br />
	<span id="more-14268"></span><br />
	下面是我用AI绘制的CH340模块3D图：<br />
	<a href="https://www.codelast.com/" target="_blank"><img decoding="async" alt="CH340" src="https://www.codelast.com/wp-content/uploads/2026/09/CH340_1.jpg" style="width: 900px; height: 485px;" /></a></p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	下面是我的实拍图：<br />
	<a href="https://www.codelast.com/" target="_blank"><img decoding="async" alt="CH340" src="https://www.codelast.com/wp-content/uploads/2026/09/CH340_2.jpg" style="width: 500px; height: 166px;" /></a></p>
<p>	<a href="https://www.codelast.com/" target="_blank"><img decoding="async" alt="CH340" src="https://www.codelast.com/wp-content/uploads/2026/09/CH340_3.jpg" style="width: 500px; height: 189px;" /></a><br />
	它做的事情可以一句话讲清楚：<strong style="font-weight: bold;">把你的电脑 USB 口变成一个&#34;串口&#34;</strong>。电脑这边看到的是一个串口设备，另一端（比如树莓派、单片机）看到的是标准的串口信号，CH340 负责在两者之间翻译数据。这样电脑就能通过串口协议和另一台设备互相收发数据了。</p>
<h4 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 18px;">
	<span class="content">关于驱动</span></h4>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	三个主流系统（Windows / macOS / Linux）都有 CH340 的驱动，多数情况下插上就能用，不需要手动装。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	macOS 这边，驱动生效的标志是：系统里出现一个叫 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">/dev/cu.usbserial-XXX</code></p>&#8230; <a href="https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e9%80%9a%e8%bf%87%e4%b8%b2%e5%8f%a3%e7%bb%88%e7%ab%af%e8%bf%9e%e6%8e%a5%e6%a0%91%e8%8e%93%e6%b4%bech340/" class="read-more">Read More </a></section>]]></description>
										<content:encoded><![CDATA[<section data-tool="markdown2wechat编辑器" data-website="https://aizhuanqian.com" id="nice" style="font-size: 16px; padding: 0px 10px; line-height: 1.6; letter-spacing: 0px; word-break: break-word; overflow-wrap: break-word; font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;">
<ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px;">
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);">背景：你是否遇到过&quot;树莓派的WiFi连不上网络，有线连接树莓派也不具备条件&quot;的情况？这个时候，你想通过终端连接到树莓派上还剩下哪些选择？串口就是其中一个可行的办法。对大多数人来说，这种连接方法都算比较少见，但它确实是一个在网络断链时的好方法。</section>
</li>
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);">目标：让 macOS 通过 USB-TTL (CH340) 模块连接树莓派 GPIO 串口，获得一个<strong style="font-weight: bold; color: black;">完全不依赖网络</strong>的终端/登录通道（等同于 SSH 控制台，但走串口线）。</section>
</li>
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);">树莓派版本：3B Rev 1.2</section>
</li>
</ul>
<hr data-tool="mdnice编辑器" style="height: 1px; margin: 0; margin-top: 10px; margin-bottom: 10px; border: none; border-top: 1px solid black;" />
<h2 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 22px;">
	<span class="content">1. 先认识 CH340 模块：它是什么，能帮我们做什么</span></h2>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 20px;">
	<span class="content">1.1 CH340 是什么</span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	CH340 是一颗国产的&quot;USB 转串口&quot;芯片（这类芯片也常被叫做 USB-UART 桥接芯片）。市面上卖的那种USB-TTL 小板，核心就是这颗芯片，板上通常还会引出一排针脚，标着 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">VCC / 5V / 3V3 / TXD / RXD / GND</code>。<br />
	<span id="more-14268"></span><br />
	下面是我用AI绘制的CH340模块3D图：<br />
	<a href="https://www.codelast.com/" target="_blank"><img decoding="async" alt="CH340" src="https://www.codelast.com/wp-content/uploads/2026/09/CH340_1.jpg" style="width: 900px; height: 485px;" /></a></p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	下面是我的实拍图：<br />
	<a href="https://www.codelast.com/" target="_blank"><img decoding="async" alt="CH340" src="https://www.codelast.com/wp-content/uploads/2026/09/CH340_2.jpg" style="width: 500px; height: 166px;" /></a></p>
<p>	<a href="https://www.codelast.com/" target="_blank"><img decoding="async" alt="CH340" src="https://www.codelast.com/wp-content/uploads/2026/09/CH340_3.jpg" style="width: 500px; height: 189px;" /></a><br />
	它做的事情可以一句话讲清楚：<strong style="font-weight: bold;">把你的电脑 USB 口变成一个&quot;串口&quot;</strong>。电脑这边看到的是一个串口设备，另一端（比如树莓派、单片机）看到的是标准的串口信号，CH340 负责在两者之间翻译数据。这样电脑就能通过串口协议和另一台设备互相收发数据了。</p>
<h4 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 18px;">
	<span class="content">关于驱动</span></h4>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	三个主流系统（Windows / macOS / Linux）都有 CH340 的驱动，多数情况下插上就能用，不需要手动装。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	macOS 这边，驱动生效的标志是：系统里出现一个叫 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">/dev/cu.usbserial-XXX</code> 的设备文件。你可以把它理解成&quot;串口的门牌号&quot;&mdash;&mdash;终端程序（比如我们后面要用的 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">screen</code>）就是靠打开这个文件来跟串口通信的。名字里的 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">XXX</code> 是一串数字，每次插拔可能不一样。所以你插上 CH340 后，先执行下面这条命令确认一下设备在不在：</p>
<section class="code-snippet__fix code-snippet__js" data-tool="mdnice编辑器" style="font-size: 14px; margin: 10px 0; display: block; color: #333; position: relative; background-color: rgba(0,0,0,0.03); border: 1px solid #f0f0f0; border-radius: 2px; display: flex; line-height: 20px; word-wrap: break-word !important;">
<ul class="code-snippet__line-index code-snippet__js" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; counter-reset: line; flex-shrink: 0; height: 100%; padding: 1em; list-style-type: none; padding: 16px; margin: 0;">
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
</ul>
<pre class="code-snippet__js" data-lang="bash" style="margin-bottom: 10px; margin-top: 0px; overflow-x: auto; padding: 16px; padding-left: 0; white-space: normal; flex: 1; -webkit-overflow-scrolling: touch;">
<code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">ls /dev/cu.usbserial*</span></code></pre>
</section>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	能看到类似 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">/dev/cu.usbserial-110</code> 的输出，就说明驱动没问题，可以继续往下走了。如果什么输出都没有，那多半是驱动没装好。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a></p>
<h4 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 18px;">
	<span class="content">关于电平（电压标准）</span></h4>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	串口信号的电平有两种常见标准：5V 和 3.3V。树莓派的 GPIO 是 <strong style="font-weight: bold;">3.3V</strong> 逻辑，所以接树莓派时要注意别让 5V 电平直接灌进 GPIO 引脚。CH340 小板一般 3.3V/5V 都兼容，本文的接法只用到 TXD、RXD、GND 三根线，不涉及供电脚，所以只要别把 5V 引脚接到树莓派上就行（后面 2 章会细说）。</p>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 20px;">
	<span class="content">1.2 用它连树莓派，具体能做什么</span></h3>
<section class="table-container" data-tool="mdnice编辑器" style="overflow-x: auto;">
<table>
<thead>
<tr style="border: 0; border-top: 1px solid #ccc; background-color: white;">
<th style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; text-align: left; background-color: rgb(240, 240, 240); min-width: 85px;">
				用途</th>
<th style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; text-align: left; background-color: rgb(240, 240, 240); min-width: 85px;">
				说明</th>
</tr>
</thead>
<tbody style="border: 0;">
<tr style="border: 0; border-top: 1px solid #ccc; background-color: white;">
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				<strong style="font-weight: bold;">断网时的兜底登录</strong></td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				树莓派网络出问题（WiFi 连不上、网线也没条件）时，这是唯一还能进系统改配置、查日志的办法，也是本文的核心场景</td>
</tr>
<tr style="border: 0; border-top: 1px solid #ccc; background-color: #F8F8F8;">
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				<strong style="font-weight: bold;">看启动早期日志</strong></td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				GPIO 串口在系统启动很早期就能输出文字，内核启动卡住时靠它看看到底死在哪一步</td>
</tr>
<tr style="border: 0; border-top: 1px solid #ccc; background-color: white;">
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				<strong style="font-weight: bold;">给单片机下载/调试程序</strong></td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				Arduino、STM32、ESP32 这类板子常用串口烧录程序、打印调试信息</td>
</tr>
<tr style="border: 0; border-top: 1px solid #ccc; background-color: #F8F8F8;">
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				<strong style="font-weight: bold;">在没网络时传小文件</strong></td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				可以用 base64 之类的文本协议走串口慢慢传，9600 波特率下大约 0.8KB/s，只适合传很小的文件</td>
</tr>
<tr style="border: 0; border-top: 1px solid #ccc; background-color: white;">
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				<strong style="font-weight: bold;">接其他 TTL 串口外设</strong></td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				GPS 模块、蓝牙模块、需要 AT 指令的模块等，很多都是串口接口，可以共用这套接线思路</td>
</tr>
<tr style="border: 0; border-top: 1px solid #ccc; background-color: #F8F8F8;">
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				<strong style="font-weight: bold;">学习串口原理</strong></td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				串口是最基础的通信接口，折腾一遍能搞明白 tty、波特率、流控这些概念</td>
</tr>
</tbody>
</table>
</section>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 20px;">
	<span class="content">1.3 为什么把它定位成&quot;备用通道&quot;，而不是日常主力</span></h3>
<ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px;">
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);">慢。9600 波特率换算下来每秒大约只有 0.8KB，敲命令、改配置够用，传文件会等到怀疑人生；</section>
</li>
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);">电脑得用一根 USB 线物理连着树莓派附近，人不在旁边就用不了；</section>
</li>
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);">日常调试当然还是 WiFi/网线 SSH 舒服，串口的意义在于：<strong style="font-weight: bold; color: black;">当网络这条路彻底断了，你还有一条路能进系统</strong>。</section>
</li>
</ul>
<hr data-tool="mdnice编辑器" style="height: 1px; margin: 0; margin-top: 10px; margin-bottom: 10px; border: none; border-top: 1px solid black;" />
<h2 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 22px;">
	<span class="content">2. 硬件准备与接线</span></h2>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 20px;">
	<span class="content">2.1 需要准备的东西</span></h3>
<section class="table-container" data-tool="mdnice编辑器" style="overflow-x: auto;">
<table>
<thead>
<tr style="border: 0; border-top: 1px solid #ccc; background-color: white;">
<th style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; text-align: left; background-color: rgb(240, 240, 240); min-width: 85px;">
				部件</th>
<th style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; text-align: left; background-color: rgb(240, 240, 240); min-width: 85px;">
				说明</th>
</tr>
</thead>
<tbody style="border: 0;">
<tr style="border: 0; border-top: 1px solid #ccc; background-color: white;">
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				CH340 USB-TTL 小板</td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				网上很常见，板上一排针脚通常标着 5V、VCC、3V3、TXD、RXD、GND</td>
</tr>
<tr style="border: 0; border-top: 1px solid #ccc; background-color: #F8F8F8;">
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				杜邦线</td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				母对母，准备 3~4 根</td>
</tr>
<tr style="border: 0; border-top: 1px solid #ccc; background-color: white;">
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				一台电脑（本文以 macOS 为例）</td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				装好 CH340 驱动，插上后能看到<code>/dev/cu.usbserial-XXX</code> 设备</td>
</tr>
</tbody>
</table>
</section>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 20px;">
	<span class="content">2.2 <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 接线规则：交叉 + 共地（最容易错的一步）</span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	先解释一下串口的两根数据线：</p>
<ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px;">
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);"><strong style="font-weight: bold; color: black;">TXD</strong>：发送（Transmit）&mdash;&mdash;这根线负责&quot;说&quot;；</section>
</li>
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);"><strong style="font-weight: bold; color: black;">RXD</strong>：接收（Receive）&mdash;&mdash;这根线负责&quot;听&quot;。</section>
</li>
</ul>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	通信要成立，必须<strong style="font-weight: bold;">一方的发送接到另一方的接收</strong>，也就是交叉接：</p>
<section class="table-container" data-tool="mdnice编辑器" style="overflow-x: auto;">
<table>
<thead>
<tr style="border: 0; border-top: 1px solid #ccc; background-color: white;">
<th style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; text-align: left; background-color: rgb(240, 240, 240); min-width: 85px;">
				CH340 小板</th>
<th style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; text-align: left; background-color: rgb(240, 240, 240); min-width: 85px;">
				树莓派 40-pin 排针</th>
</tr>
</thead>
<tbody style="border: 0;">
<tr style="border: 0; border-top: 1px solid #ccc; background-color: white;">
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				GND</td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				Pin 6 / 9 / 14 / 20 / 25 / 30 / 34 / 39（这些全是 GND，任选一个）</td>
</tr>
<tr style="border: 0; border-top: 1px solid #ccc; background-color: #F8F8F8;">
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				TXD（发送）</td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				Pin 10，也就是树莓派的 RXD / GPIO15</td>
</tr>
<tr style="border: 0; border-top: 1px solid #ccc; background-color: white;">
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				RXD（接收）</td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				Pin 8，也就是树莓派的 TXD / GPIO14</td>
</tr>
<tr style="border: 0; border-top: 1px solid #ccc; background-color: #F8F8F8;">
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				VCC / 3V3 / 5V</td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				<strong style="font-weight: bold;">一律不接</strong></td>
</tr>
</tbody>
</table>
</section>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	三个容易踩的坑：</p>
<ol data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px;">
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);"><strong style="font-weight: bold; color: black;">TXD 和 RXD 必须交叉，绝不能 TXD 对 TXD。</strong> 如果接成 TXD 对 TXD，两边都在&quot;说&quot;、没人&quot;听&quot;，结果就是完全收不到任何数据。记住这个画面：两个人都只对着对方说话、却都把耳朵捂上，谁也听不见谁。</section>
</li>
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);"><strong style="font-weight: bold; color: black;">GND 必须共地。</strong> 意思是 CH340 的地线和树莓派的地线要连在一起，让两边有共同的电压参考点。如果不共地，表现是完全没有输出，或者收到一堆乱码（最常见的现象是收到 0 字节）。这一步看着不起眼，实际上一大半&quot;没反应&quot;的问题都出在它身上。</section>
</li>
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);"><strong style="font-weight: bold; color: black;">不要把 VCC / 3V3 / 5V 接到树莓派上。</strong> 树莓派自己有电源，CH340 小板靠 USB 口供电，两边电源脚对接会造成双电源冲突，严重时可能烧东西。</section>
</li>
</ol>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	另外，杜邦线插拔多了容易接触不良。如果怀疑接触问题，换一根线、或者重新插紧往往就好了。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a></p>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 20px;">
	<span class="content">2.3 接线示意图</span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	下面这张图把树莓派 40-pin 排针全部画出来了。排针是竖着排列的：左边一列是奇数号 1、3、5&hellip;，右边一列是偶数号 2、4、6&hellip;，从上往下递增。蓝色高亮的是我们真正用到的三个脚。<br />
	<a href="https://www.codelast.com/" target="_blank"><img decoding="async" alt="" src="https://www.codelast.com/wp-content/uploads/2026/09/CH340_and_rpi.jpg" style="width: 835px; height: 1354px;" /></a></p>
<p>	<span style="letter-spacing: 0px;">图中三个高亮触点分别是：</span></p>
<ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px;">
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);"><strong style="font-weight: bold; color: black;">Pin 8</strong>：树莓派的 TXD（GPIO14）&mdash;&mdash;接 CH340 的 RXD；</section>
</li>
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);"><strong style="font-weight: bold; color: black;">Pin 10</strong>：树莓派的 RXD（GPIO15）&mdash;&mdash;接 CH340 的 TXD；</section>
</li>
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);"><strong style="font-weight: bold; color: black;">Pin 20</strong>：GND&mdash;&mdash;图里选它只作示例，实际上树莓派上一堆 GND 脚（Pin 6/9/14/20/25/30/34/39）任选一个接都行。</section>
</li>
</ul>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	再次强调：<strong style="font-weight: bold;">CH340 的 TXD 必须接树莓派的 RXD，CH340 的 RXD 必须接树莓派的 TXD</strong>，其他引脚一律不接。</p>
<hr data-tool="mdnice编辑器" style="height: 1px; margin: 0; margin-top: 10px; margin-bottom: 10px; border: none; border-top: 1px solid black;" />
<h2 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 22px;">
	<span class="content">3. 树莓派端要改的配置</span></h2>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	要让树莓派通过 GPIO 串口提供登录服务，需要改三个系统文件。因为本文假设的场景是&quot;树莓派已经没有任何网络连接&quot;，所以先讲怎么在没有网络的情况下修改这些文件，再逐个讲每个文件改什么。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a></p>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 20px;">
	<span class="content">3.1 没有网络时怎么改系统文件（拔卡方式）</span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	先认识要改的三个文件：</p>
<section class="table-container" data-tool="mdnice编辑器" style="overflow-x: auto;">
<table>
<thead>
<tr style="border: 0; border-top: 1px solid #ccc; background-color: white;">
<th style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; text-align: left; background-color: rgb(240, 240, 240); min-width: 85px;">
				文件</th>
<th style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; text-align: left; background-color: rgb(240, 240, 240); min-width: 85px;">
				所在分区</th>
<th style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; text-align: left; background-color: rgb(240, 240, 240); min-width: 85px;">
				作用</th>
</tr>
</thead>
<tbody style="border: 0;">
<tr style="border: 0; border-top: 1px solid #ccc; background-color: white;">
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				<code>/boot/firmware/config.txt</code></td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				boot 分区（FAT32）</td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				启用 GPIO 串口、决定用哪个 UART（3.2 节）</td>
</tr>
<tr style="border: 0; border-top: 1px solid #ccc; background-color: #F8F8F8;">
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				<code>/boot/firmware/cmdline.txt</code></td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				boot 分区（FAT32）</td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				让内核把启动日志输出到串口，并定好波特率（3.3 节）</td>
</tr>
<tr style="border: 0; border-top: 1px solid #ccc; background-color: white;">
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				<code>/etc/systemd/system/serial-getty@*.service.d/override.conf</code></td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				系统分区（ext4）</td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				让系统在串口上启动登录程序（3.4 节）</td>
</tr>
</tbody>
</table>
</section>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	这里有个背景知识需要先说明：树莓派的 SD 卡（TF 卡）其实分成两个分区。一个是 <strong style="font-weight: bold;">boot 分区</strong>，格式是 FAT32，里面放的是开机要用的配置文件（<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">config.txt</code>、<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">cmdline.txt</code> 都在这里）；另一个是 <strong style="font-weight: bold;">系统分区</strong>，格式是 ext4，装着整个操作系统。FAT32 分区在任何电脑上都能直接读写，而 ext4 分区普通电脑默认是看不到的。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	拔卡修改的具体步骤：</p>
<ol data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px;">
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);"><strong style="font-weight: bold; color: black;">关机断电</strong>：先在树莓派上正常关机，然后断开电源。切记不能带电拔卡，容易损坏文件系统；</section>
</li>
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);"><strong style="font-weight: bold; color: black;">取出 TF 卡</strong>，用读卡器插到电脑上；</section>
</li>
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);"><strong style="font-weight: bold; color: black;">改 boot 分区的文件</strong>：boot 分区是 FAT32，插上后电脑会直接识别。macOS 下它会自动挂载成一个盘，一般叫 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">/Volumes/bootfs</code>，直接用文本编辑器打开里面的 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">config.txt</code>、<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">cmdline.txt</code> 修改保存就行；Windows、Linux 同理，打开 TF 卡对应的盘符/挂载点就能看到这两个文件；</section>
</li>
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);"><strong style="font-weight: bold; color: black;">系统分区里的文件</strong>：如果你需要改第三个文件（<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">serial-getty</code> 的 override），它在 ext4 系统分区里，普通电脑默认看不到。macOS 要用 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">debugfs</code> 之类的 ext4 工具（需要 root 权限），Windows 可以用 ext2fsd 之类的软件。<strong style="font-weight: bold; color: black;">如果觉得这一步麻烦，可以先跳过它</strong>&mdash;&mdash;先只改 boot 分区里的两个文件，等接上串口发现确实登录不了，再回头处理 3.4 节的问题；</section>
</li>
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);"><strong style="font-weight: bold; color: black;">安全弹出 TF 卡</strong>（macOS 里右键推出），插回树莓派，重新上电。</section>
</li>
</ol>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	两个容易困惑的点，提前说明：</p>
<ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px;">
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);"><strong style="font-weight: bold; color: black;">路径差异</strong>：新版 Raspberry Pi OS（Debian 12/13）里，boot 分区在系统内挂在 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">/boot/firmware/</code>；老版本是挂在 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">/boot/</code>。但不管系统内路径怎么写，<strong style="font-weight: bold; color: black;">文件本身就在 boot 分区根目录里</strong>&mdash;&mdash;你拔卡插电脑后，直接看盘符根目录下有没有 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">config.txt</code> 就行，不用管 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">/boot/firmware</code> 这种路径。</section>
</li>
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);"><strong style="font-weight: bold; color: black;">全新卡 vs 用过的卡</strong>：如果你是刚烧录好系统、还没第一次开机的卡，也可以插电脑直接改 boot 分区，效果和改 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">/boot/firmware/</code> 一样；如果是已经用过的卡，改之前一定要先正常关机再拔。</section>
</li>
</ul>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 20px;">
	<span class="content">3.2 启用 GPIO 串口，并决定用哪个 UART</span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	树莓派 GPIO 上引出的串口默认是关闭的，需要在 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">/boot/firmware/config.txt</code> 里打开它。用文本编辑器打开这个文件，在文件末尾追加：</p>
<section class="code-snippet__fix code-snippet__js" data-tool="mdnice编辑器" style="font-size: 14px; margin: 10px 0; display: block; color: #333; position: relative; background-color: rgba(0,0,0,0.03); border: 1px solid #f0f0f0; border-radius: 2px; display: flex; line-height: 20px; word-wrap: break-word !important;">
<ul class="code-snippet__line-index code-snippet__js" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; counter-reset: line; flex-shrink: 0; height: 100%; padding: 1em; list-style-type: none; padding: 16px; margin: 0;">
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
</ul>
<pre class="code-snippet__js" data-lang="ini" style="margin-bottom: 10px; margin-top: 0px; overflow-x: auto; padding: 16px; padding-left: 0; white-space: normal; flex: 1; -webkit-overflow-scrolling: touch;">
<code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">enable_uart=1</span></code></pre>
</section>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	光打开还不够，树莓派 3 上有个特殊情况需要决定：这颗芯片其实有<strong style="font-weight: bold;">两个串口硬件</strong>&mdash;&mdash;一个叫 <strong style="font-weight: bold;">PL011</strong>（质量好、波特率准，但默认分配给蓝牙用），一个叫 <strong style="font-weight: bold;">mini-UART</strong>（功能弱一些、波特率会随 CPU 频率漂移）。GPIO 引出的串口到底用哪个，由要不要给蓝牙让路决定。有三个方案：</p>
<section class="table-container" data-tool="mdnice编辑器" style="overflow-x: auto;">
<table>
<thead>
<tr style="border: 0; border-top: 1px solid #ccc; background-color: white;">
<th style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; text-align: left; background-color: rgb(240, 240, 240); min-width: 85px;">
				方案</th>
<th style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; text-align: left; background-color: rgb(240, 240, 240); min-width: 85px;">
				config.txt 里的写法</th>
<th style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; text-align: left; background-color: rgb(240, 240, 240); min-width: 85px;">
				结果</th>
</tr>
</thead>
<tbody style="border: 0;">
<tr style="border: 0; border-top: 1px solid #ccc; background-color: white;">
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				1. 关闭蓝牙，串口用最好的 PL011</td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				<code>dtoverlay=disable-bt</code></td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				GPIO 串口是<code>/dev/ttyAMA0</code>（PL011，波特率最准），但蓝牙彻底没了</td>
</tr>
<tr style="border: 0; border-top: 1px solid #ccc; background-color: #F8F8F8;">
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				2. 串口用 PL011、蓝牙挤到 mini-UART</td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				<code>dtoverlay=miniuart-bt</code></td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				理论可行，但在部分树莓派 3 上会导致蓝牙固件加载失败，<strong style="font-weight: bold;">不推荐</strong></td>
</tr>
<tr style="border: 0; border-top: 1px solid #ccc; background-color: white;">
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				3. 什么都不加，维持默认</td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				（不加 dtoverlay）</td>
<td style="border-style: solid; border-color: rgb(204, 204, 204); padding: 5px 10px; min-width: 85px;">
				蓝牙正常用 PL011；GPIO 串口退而求其次用 mini-UART，即<code>/dev/ttyS0</code></td>
</tr>
</tbody>
</table>
</section>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	怎么选，取决于你要不要蓝牙：</p>
<ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px;">
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);"><strong style="font-weight: bold; color: black;">还要用蓝牙</strong>：选方案 3。GPIO 串口会是 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">/dev/serial0 -&gt; ttyS0</code>（mini-UART）。因为 mini-UART 的波特率会随 CPU 频率漂移，建议把波特率定在 9600 这种低速档，或者去固定 CPU 频率，否则可能出现乱码；</section>
</li>
<li>
<section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; color: rgb(1, 1, 1);"><strong style="font-weight: bold; color: black;">不需要蓝牙，只想要最稳定的串口</strong>：选方案 1。GPIO 串口是 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">/dev/serial0 -&gt; ttyAMA0</code>（PL011），波特率精确，省心。</section>
</li>
</ul>
<blockquote data-tool="mdnice编辑器" style="font-size: 0.9em; overflow: auto; border-left: 3px solid rgba(0, 0, 0, 0.4); background: rgba(0, 0, 0, 0.05); color: rgb(106, 115, 125); padding: 10px 10px 10px 20px; margin-bottom: 20px; margin-top: 20px;">
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0px; color: black; line-height: 26px;">
		后面各小节的命令都以 <strong style="font-weight: bold;">方案 3（设备名 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">ttyS0</code>）</strong> 为例。如果你选了方案 1，把命令里出现的 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">ttyS0</code> 全部换成 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">ttyAMA0</code> 即可。</p>
</blockquote>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	顺带一提：<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">/dev/serial0</code> 是一个软链接，它总是指向&quot;当前 GPIO 串口实际对应的那个设备&quot;（<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">ttyS0</code> 或 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">ttyAMA0</code>），所以不确定时先执行 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">ls -l /dev/serial0</code> 看一眼它指向谁，心里就有数了。</p>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 20px;">
	<span class="content">3.3 让内核把启动信息输出到串口（顺便定波特率）</span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	Linux 内核启动时的日志默认是输出到屏幕的。我们希望它同时也输出到 GPIO 串口，这样就算树莓派没接屏幕，也能从串口看到启动过程。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	这个行为由 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">/boot/firmware/cmdline.txt</code> 控制。用文本编辑器打开它，确认里面有这样一段（注意是 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">serial0</code>，不是别的）：</p>
<section class="code-snippet__fix code-snippet__js" data-tool="mdnice编辑器" style="font-size: 14px; margin: 10px 0; display: block; color: #333; position: relative; background-color: rgba(0,0,0,0.03); border: 1px solid #f0f0f0; border-radius: 2px; display: flex; line-height: 20px; word-wrap: break-word !important;">
<ul class="code-snippet__line-index code-snippet__js" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; counter-reset: line; flex-shrink: 0; height: 100%; padding: 1em; list-style-type: none; padding: 16px; margin: 0;">
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
</ul>
<pre class="code-snippet__js" data-lang="" style="margin-bottom: 10px; margin-top: 0px; overflow-x: auto; padding: 16px; padding-left: 0; white-space: normal; flex: 1; -webkit-overflow-scrolling: touch;">
<code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">console=serial0,9600</span></code></pre>
</section>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">serial0</code> 就是 GPIO 串口的软链接名，<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">9600</code> 是波特率。如果文件里同时有 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">console=tty1</code> 之类的（那是输出到本地屏幕的），不要删掉它们，只把 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">serial0</code> 这一段波特率定为 9600 就好。</p>
<blockquote data-tool="mdnice编辑器" style="font-size: 0.9em; overflow: auto; border-left: 3px solid rgba(0, 0, 0, 0.4); background: rgba(0, 0, 0, 0.05); color: rgb(106, 115, 125); padding: 10px 10px 10px 20px; margin-bottom: 20px; margin-top: 20px;">
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0px; color: black; line-height: 26px;">
		波特率这个东西，后面会反复强调：<strong style="font-weight: bold;">发送端和接收端必须用同一个波特率</strong>，否则收到的就是乱码。</p>
</blockquote>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 20px;">
	<span class="content">3.4 让系统在串口上启动登录程序（serial-getty）</span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	前面两步只是让内核往串口输出日志，但光有日志还不能登录。要登录，系统里得有一个程序在串口上等着，显示 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">login:</code> 提示符、接受你输入用户名密码&mdash;&mdash;这个程序叫 <strong style="font-weight: bold;">getty</strong>，对应的系统服务是 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">serial-getty@&lt;串口设备&gt;.service</code>。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	树莓派系统在检测到 GPIO 串口启用后，一般会自动启动对应的 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">serial-getty</code> 服务。但有一个很常见的坑：<strong style="font-weight: bold;">getty 的波特率必须和内核 console 的波特率一致</strong>（都是 9600）。如果登录提示符不出现，多半就是 getty 没启动，或者波特率不对。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	手动确认/修正的方法是给 getty 写一个配置文件，强制指定设备和波特率。在树莓派上创建 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">/etc/systemd/system/serial-getty@ttyS0.service.d/override.conf</code>（目录可能要自己建）：</p>
<section class="code-snippet__fix code-snippet__js" data-tool="mdnice编辑器" style="font-size: 14px; margin: 10px 0; display: block; color: #333; position: relative; background-color: rgba(0,0,0,0.03); border: 1px solid #f0f0f0; border-radius: 2px; display: flex; line-height: 20px; word-wrap: break-word !important;">
<ul class="code-snippet__line-index code-snippet__js" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; counter-reset: line; flex-shrink: 0; height: 100%; padding: 1em; list-style-type: none; padding: 16px; margin: 0;">
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
</ul>
<pre class="code-snippet__js" data-lang="ini" style="margin-bottom: 10px; margin-top: 0px; overflow-x: auto; padding: 16px; padding-left: 0; white-space: normal; flex: 1; -webkit-overflow-scrolling: touch;">
<code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">[Service]</span></code><code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">ExecStart=</span></code><code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">ExecStart=-/sbin/agetty --noclear --keep-baud ttyS0 9600 vt100</span></code></pre>
</section>
<blockquote data-tool="mdnice编辑器" style="font-size: 0.9em; overflow: auto; border-left: 3px solid rgba(0, 0, 0, 0.4); background: rgba(0, 0, 0, 0.05); color: rgb(106, 115, 125); padding: 10px 10px 10px 20px; margin-bottom: 20px; margin-top: 20px;">
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0px; color: black; line-height: 26px;">
		如果你的 GPIO 串口实际是 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">ttyAMA0</code>（方案 1），就把上面两处 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">ttyS0</code> 换成 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">ttyAMA0</code>，文件名也跟着改成 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">serial-getty@ttyAMA0.service.d/override.conf</code>。</p>
</blockquote>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	然后重新加载 systemd 并启用服务：</p>
<section class="code-snippet__fix code-snippet__js" data-tool="mdnice编辑器" style="font-size: 14px; margin: 10px 0; display: block; color: #333; position: relative; background-color: rgba(0,0,0,0.03); border: 1px solid #f0f0f0; border-radius: 2px; display: flex; line-height: 20px; word-wrap: break-word !important;">
<ul class="code-snippet__line-index code-snippet__js" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; counter-reset: line; flex-shrink: 0; height: 100%; padding: 1em; list-style-type: none; padding: 16px; margin: 0;">
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
</ul>
<pre class="code-snippet__js" data-lang="bash" style="margin-bottom: 10px; margin-top: 0px; overflow-x: auto; padding: 16px; padding-left: 0; white-space: normal; flex: 1; -webkit-overflow-scrolling: touch;">
<code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">sudo systemctl daemon-reload</span></code><code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">sudo systemctl enable --now serial-getty@ttyS0.service</span></code></pre>
</section>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	验证服务确实在跑：</p>
<section class="code-snippet__fix code-snippet__js" data-tool="mdnice编辑器" style="font-size: 14px; margin: 10px 0; display: block; color: #333; position: relative; background-color: rgba(0,0,0,0.03); border: 1px solid #f0f0f0; border-radius: 2px; display: flex; line-height: 20px; word-wrap: break-word !important;">
<ul class="code-snippet__line-index code-snippet__js" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; counter-reset: line; flex-shrink: 0; height: 100%; padding: 1em; list-style-type: none; padding: 16px; margin: 0;">
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
</ul>
<pre class="code-snippet__js" data-lang="bash" style="margin-bottom: 10px; margin-top: 0px; overflow-x: auto; padding: 16px; padding-left: 0; white-space: normal; flex: 1; -webkit-overflow-scrolling: touch;">
<code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">systemctl is-active serial-getty@ttyS0   # 应该输出 active</span></code><code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">systemctl list-units | grep ttyS0        # 能看到 serial-getty 在运行</span></code></pre>
</section>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	到这里，树莓派端的配置就齐了：GPIO 串口已启用、内核往串口输出日志、getty 在串口上等你登录。</p>
<hr data-tool="mdnice编辑器" style="height: 1px; margin: 0; margin-top: 10px; margin-bottom: 10px; border: none; border-top: 1px solid black;" />
<h2 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 22px;">
	<span class="content">4. macOS 这一端怎么连</span></h2>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 20px;">
	<span class="content">4.1 先确认设备名</span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	CH340 插上后 macOS 会自动给它分配一个设备文件，名字是 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">/dev/cu.usbserial-XXXX</code>（也可能是 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">/dev/tty.usbserial-XXXX</code>）。注意末尾那串数字<strong style="font-weight: bold;">每次重新插拔都可能变</strong>（比如这次是 11310，下次变成 11320，再下次是 110），所以别死记一个名字，每次用之前先查一下：</p>
<section class="code-snippet__fix code-snippet__js" data-tool="mdnice编辑器" style="font-size: 14px; margin: 10px 0; display: block; color: #333; position: relative; background-color: rgba(0,0,0,0.03); border: 1px solid #f0f0f0; border-radius: 2px; display: flex; line-height: 20px; word-wrap: break-word !important;">
<ul class="code-snippet__line-index code-snippet__js" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; counter-reset: line; flex-shrink: 0; height: 100%; padding: 1em; list-style-type: none; padding: 16px; margin: 0;">
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
</ul>
<pre class="code-snippet__js" data-lang="bash" style="margin-bottom: 10px; margin-top: 0px; overflow-x: auto; padding: 16px; padding-left: 0; white-space: normal; flex: 1; -webkit-overflow-scrolling: touch;">
<code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">ls /dev/cu.usbserial*</span></code></pre>
</section>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	如果这条命令什么都查不到，说明驱动没装好，去 WCH 官网装 macOS 驱动。</p>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 20px;">
	<span class="content">4.2 用 screen 连上去</span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	macOS 自带的 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">screen</code> 命令就能当串口终端用：</p>
<section class="code-snippet__fix code-snippet__js" data-tool="mdnice编辑器" style="font-size: 14px; margin: 10px 0; display: block; color: #333; position: relative; background-color: rgba(0,0,0,0.03); border: 1px solid #f0f0f0; border-radius: 2px; display: flex; line-height: 20px; word-wrap: break-word !important;">
<ul class="code-snippet__line-index code-snippet__js" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; counter-reset: line; flex-shrink: 0; height: 100%; padding: 1em; list-style-type: none; padding: 16px; margin: 0;">
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
</ul>
<pre class="code-snippet__js" data-lang="bash" style="margin-bottom: 10px; margin-top: 0px; overflow-x: auto; padding: 16px; padding-left: 0; white-space: normal; flex: 1; -webkit-overflow-scrolling: touch;">
<code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">screen /dev/cu.usbserial-110 9600</span></code></pre>
</section>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	格式是 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">screen 设备文件 波特率</code>，把设备名换成你上一步查到的实际名字。连接成功后，按一下回车，应该能看到：</p>
<section class="code-snippet__fix code-snippet__js" data-tool="mdnice编辑器" style="font-size: 14px; margin: 10px 0; display: block; color: #333; position: relative; background-color: rgba(0,0,0,0.03); border: 1px solid #f0f0f0; border-radius: 2px; display: flex; line-height: 20px; word-wrap: break-word !important;">
<ul class="code-snippet__line-index code-snippet__js" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; counter-reset: line; flex-shrink: 0; height: 100%; padding: 1em; list-style-type: none; padding: 16px; margin: 0;">
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
</ul>
<pre class="code-snippet__js" data-lang="" style="margin-bottom: 10px; margin-top: 0px; overflow-x: auto; padding: 16px; padding-left: 0; white-space: normal; flex: 1; -webkit-overflow-scrolling: touch;">
<code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">rpi login:</span></code></pre>
</section>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	输入树莓派的用户名和密码，就进入 shell 了，用法和 SSH 完全一样。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	退出 screen 的方法：先按 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">Ctrl+A</code>，松开后再按 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">K</code>，最后按 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">y</code> 确认退出。</p>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 20px;">
	<span class="content">4.3 不想开终端？也可以用命令直接收发</span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	如果你是脚本/程序要自动化测试串口，不需要交互式终端，可以用下面的方式非交互地验证：</p>
<section class="code-snippet__fix code-snippet__js" data-tool="mdnice编辑器" style="font-size: 14px; margin: 10px 0; display: block; color: #333; position: relative; background-color: rgba(0,0,0,0.03); border: 1px solid #f0f0f0; border-radius: 2px; display: flex; line-height: 20px; word-wrap: break-word !important;">
<ul class="code-snippet__line-index code-snippet__js" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; counter-reset: line; flex-shrink: 0; height: 100%; padding: 1em; list-style-type: none; padding: 16px; margin: 0;">
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
</ul>
<pre class="code-snippet__js" data-lang="bash" style="margin-bottom: 10px; margin-top: 0px; overflow-x: auto; padding: 16px; padding-left: 0; white-space: normal; flex: 1; -webkit-overflow-scrolling: touch;">
<code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">DEV=/dev/cu.usbserial-110                       # 换成你实际的设备名</span></code><code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">stty -f &quot;$DEV&quot; 9600 raw -echo                   # 设置波特率 9600，关闭回显</span></code><code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">(timeout 4 cat &quot;$DEV&quot; &gt; /tmp/rx.txt &amp;)          # 后台启动一个读取，读 4 秒</span></code><code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">printf &#39;\r&#39; &gt; &quot;$DEV&quot;                            # 往串口写一个回车，触发登录提示</span></code><code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">cat /tmp/rx.txt                                 # 查看收到的内容，应该能看到 &quot;rpi login:&quot;</span></code></pre>
</section>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">stty</code> 负责配置串口参数，<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">cat</code> 负责读，<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">printf</code> 负责写&mdash;&mdash;把串口当成一个文件来读写就行。</p>
<hr data-tool="mdnice编辑器" style="height: 1px; margin: 0; margin-top: 10px; margin-bottom: 10px; border: none; border-top: 1px solid black;" />
<h2 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 22px;">
	<span class="content">5. 调试记录：踩过的坑</span></h2>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	下面这些是实际接线、调通过程中遇到的问题。如果你一次就成功了，可以跳过本章；如果哪里不对，按顺序排查通常能解决。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a></p>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 20px;">
	<span class="content">5.1 第一次接上：完全没有输出，或者全是乱码</span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	刚接上时最常见的两个现象：读串口读到 0 字节（什么都没有），或者读到 40~70 字节的乱码。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	按下面的顺序排查：</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	<strong style="font-weight: bold;">第 1 步：先确认 CH340 小板本身是好的（环回测试）</strong></p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	把 CH340 和树莓派的接线全部断开，然后用一根杜邦线把 CH340 板上的 <strong style="font-weight: bold;">TXD 和 RXD 短接</strong>（直接连在一起）。这样一来，CH340 自己发出去的数据会原路回到自己。然后用 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">screen</code> 连上串口随便敲几个字：如果敲什么回显什么，说明 CH340 小板、USB 线、驱动这一整条链路都是好的，问题出在树莓派那一侧。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	不想开终端的话，也可以用命令自动验证：</p>
<section class="code-snippet__fix code-snippet__js" data-tool="mdnice编辑器" style="font-size: 14px; margin: 10px 0; display: block; color: #333; position: relative; background-color: rgba(0,0,0,0.03); border: 1px solid #f0f0f0; border-radius: 2px; display: flex; line-height: 20px; word-wrap: break-word !important;">
<ul class="code-snippet__line-index code-snippet__js" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; counter-reset: line; flex-shrink: 0; height: 100%; padding: 1em; list-style-type: none; padding: 16px; margin: 0;">
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
</ul>
<pre class="code-snippet__js" data-lang="bash" style="margin-bottom: 10px; margin-top: 0px; overflow-x: auto; padding: 16px; padding-left: 0; white-space: normal; flex: 1; -webkit-overflow-scrolling: touch;">
<code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">stty -f $DEV 115200 raw -echo</span></code><code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">(timeout 8 cat $DEV &gt; /tmp/loop.txt &amp;)   # 后台读</span></code><code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">printf &#39;HELLO_LOOP&#39; &gt; $DEV                # 写入一串测试文字</span></code><code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">grep HELLO_LOOP /tmp/loop.txt &amp;&amp; echo OK   # 能在读到的内容里找到它 =&gt; 模块正常</span></code></pre>
</section>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	如果这步通过，说明小板没问题，继续看第 2 步。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	<strong style="font-weight: bold;">第 2 步：检查 GND 是否共地、TXD/RXD 是否交叉</strong></p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	读到的字节数是 0 时，优先怀疑两件事：GND 没接（换一个 GND 引脚试试），或者 TXD/RXD 没交叉。我实际遇到过：把 GND 从 Pin 30 换到 Pin 20 之后，读到的数据从 0 字节一下子变成 182 字节&mdash;&mdash;共地的影响就是这么明显。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	<strong style="font-weight: bold;">第 3 步：把 TXD 和 RXD 两根线对调</strong></p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	如果前面都查过还是没数据，把 TXD、RXD 两根线互换位置再试。很多时候数据从无到有，就差这一下。</p>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 20px;">
	<span class="content">5.2 有数据了，但是全是乱码 &rarr; 波特率不对</span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	现象：能收到数据了，但内容完全没法看，全是乱码；而且换了好几档波特率读出来的都是&quot;长度差不多的乱码&quot;。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	这是因为<strong style="font-weight: bold;">两边的波特率不一致</strong>。串口通信里，发送方和接收方必须用同样的波特率（相当于约定同样的说话语速），否则对方听到的就是无意义的声音。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	推荐用&quot;矩阵测试&quot;来找到正确的波特率：树莓派和 macOS 两边同步切到同一个波特率，树莓派持续发一段特征文字，macOS 在另一边读，看哪一档能读出可读的文本。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	树莓派侧（示例用 9600）：</p>
<section class="code-snippet__fix code-snippet__js" data-tool="mdnice编辑器" style="font-size: 14px; margin: 10px 0; display: block; color: #333; position: relative; background-color: rgba(0,0,0,0.03); border: 1px solid #f0f0f0; border-radius: 2px; display: flex; line-height: 20px; word-wrap: break-word !important;">
<ul class="code-snippet__line-index code-snippet__js" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; counter-reset: line; flex-shrink: 0; height: 100%; padding: 1em; list-style-type: none; padding: 16px; margin: 0;">
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
</ul>
<pre class="code-snippet__js" data-lang="bash" style="margin-bottom: 10px; margin-top: 0px; overflow-x: auto; padding: 16px; padding-left: 0; white-space: normal; flex: 1; -webkit-overflow-scrolling: touch;">
<code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">sudo stty -F /dev/ttyS0 9600 raw -echo        # ttyS0 或 ttyAMA0，按你实际设备名</span></code><code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">for i in 1 2 3 4; do echo -n &quot;MATRIX_BAUD_9600_$i&quot; &gt; /dev/ttyS0; sleep 0.2; done</span></code></pre>
</section>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	macOS 侧：</p>
<section class="code-snippet__fix code-snippet__js" data-tool="mdnice编辑器" style="font-size: 14px; margin: 10px 0; display: block; color: #333; position: relative; background-color: rgba(0,0,0,0.03); border: 1px solid #f0f0f0; border-radius: 2px; display: flex; line-height: 20px; word-wrap: break-word !important;">
<ul class="code-snippet__line-index code-snippet__js" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; counter-reset: line; flex-shrink: 0; height: 100%; padding: 1em; list-style-type: none; padding: 16px; margin: 0;">
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
</ul>
<pre class="code-snippet__js" data-lang="bash" style="margin-bottom: 10px; margin-top: 0px; overflow-x: auto; padding: 16px; padding-left: 0; white-space: normal; flex: 1; -webkit-overflow-scrolling: touch;">
<code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">stty -f $DEV 9600 raw -echo</span></code><code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">(timeout 4 cat $DEV &gt; /tmp/mx.txt &amp;)</span></code><code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">grep MATRIX_BAUD /tmp/mx.txt &amp;&amp; echo 通过</span></code></pre>
</section>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	我实际测试的结果是：<strong style="font-weight: bold;">9600 波特率下两边完全互通，反而 115200 读出来是乱的</strong>&mdash;&mdash;这块 CH340 小板在 115200 这个高速档上精度不稳。所以最后统一把波特率定在 9600（8 数据位、无校验、1 停止位，也就是常说的 8N1），内核 console、getty、macOS 端全部用 9600。</p>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 20px;">
	<span class="content">5.3 能看到内核日志，但没有 login 提示 &rarr; getty 没起来</span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	现象：串口上能看到内核启动的日志，但日志播完就没了，一直没有 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">login:</code> 提示符。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	这说明问题不在硬件，而在系统这边&mdash;&mdash;<strong style="font-weight: bold;">没有程序在串口上等你登录</strong>，也就是 3.4 节说的 getty 没有正确启动，或者它的波特率和 console 不一致。解决办法就是按 3.4 节写好 override 文件、启用对应的 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">serial-getty@&lt;设备&gt;.service</code>。</p>
<h3 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 20px;">
	<span class="content">5.4 换了个 USB 口，就连不上了 &rarr; 设备名变了</span></h3>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	现象：之前明明连得好好的，换了个 USB 口再插，<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">screen</code> 报错 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">[screen is terminating]</code>。</p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	原因在 4.1 节说过：<strong style="font-weight: bold;">设备名末尾的数字每次插拔都可能变</strong>。换了 USB 口，旧名字就失效了。解决办法很简单：重新执行 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; color: #1e6bb8; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">ls /dev/cu.usbserial*</code> 查出新的设备名，用新名字重新连接。</p>
<hr data-tool="mdnice编辑器" style="height: 1px; margin: 0; margin-top: 10px; margin-bottom: 10px; border: none; border-top: 1px solid black;" />
<h2 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; font-size: 22px;">
	<span class="content">6. 最终验证（确认可用）</span></h2>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	配置全部完成后，用下面两条验证整个链路是通的。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a></p>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	交互式验证（macOS 终端里）：</p>
<section class="code-snippet__fix code-snippet__js" data-tool="mdnice编辑器" style="font-size: 14px; margin: 10px 0; display: block; color: #333; position: relative; background-color: rgba(0,0,0,0.03); border: 1px solid #f0f0f0; border-radius: 2px; display: flex; line-height: 20px; word-wrap: break-word !important;">
<ul class="code-snippet__line-index code-snippet__js" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; counter-reset: line; flex-shrink: 0; height: 100%; padding: 1em; list-style-type: none; padding: 16px; margin: 0;">
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
</ul>
<pre class="code-snippet__js" data-lang="bash" style="margin-bottom: 10px; margin-top: 0px; overflow-x: auto; padding: 16px; padding-left: 0; white-space: normal; flex: 1; -webkit-overflow-scrolling: touch;">
<code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">screen /dev/cu.usbserial-110 9600</span></code><code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"># 应该看到 rpi login:，输入用户名密码进入 shell</span></code></pre>
</section>
<p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; margin: 0px; line-height: 26px;">
	非交互式验证（脚本里用）：</p>
<section class="code-snippet__fix code-snippet__js" data-tool="mdnice编辑器" style="font-size: 14px; margin: 10px 0; display: block; color: #333; position: relative; background-color: rgba(0,0,0,0.03); border: 1px solid #f0f0f0; border-radius: 2px; display: flex; line-height: 20px; word-wrap: break-word !important;">
<ul class="code-snippet__line-index code-snippet__js" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: black; counter-reset: line; flex-shrink: 0; height: 100%; padding: 1em; list-style-type: none; padding: 16px; margin: 0;">
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
<li style="list-style-type: none; text-align: right; line-height: 26px; margin: 0px;">
		<span style="min-width: 1.5em; left: -2.5em; counter-increment: line 1; color: rgba(0, 0, 0, 0.3);">ounter(line</span></li>
</ul>
<pre class="code-snippet__js" data-lang="bash" style="margin-bottom: 10px; margin-top: 0px; overflow-x: auto; padding: 16px; padding-left: 0; white-space: normal; flex: 1; -webkit-overflow-scrolling: touch;">
<code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">printf &#39;\r&#39; &gt; $DEV</span></code><code style="border-radius: 0px; white-space: pre; display: flex; position: relative; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; padding: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">timeout 5 cat $DEV        # 应该能看到 &quot;rpi login:&quot;</span></code></pre>
</section>
</section>
<p></p>
<p>
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	<span style="color: rgb(255, 0, 0);">➤➤</span> 版权声明 <span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;<br />
	转载需注明出处：<u><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><em><span style="color: rgb(0, 0, 255);"><strong style="font-size: 16px;"><span style="font-family: arial, helvetica, sans-serif;">codelast.com</span></strong></span></em></a></u>&nbsp;<br />
	感谢关注我的微信公众号（微信扫一扫）：<br />
	<img decoding="async" alt="wechat qrcode of codelast" src="https://www.codelast.com/codelast_wechat_qr_code.jpg" style="color: rgb(77, 77, 77); font-size: 13px; width: 200px; height: 200px;" /><br />
	以及我的微信视频号：</p>
<p style="border: 0px; font-size: 13px; margin: 0px 0px 9px; outline: 0px; padding: 0px; color: rgb(77, 77, 77);">
	<img decoding="async" alt="" src="https://www.codelast.com/wechat_shipinhao_qr_code.jpg" style="text-align: center; width: 200px; height: 199px;" /></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e9%80%9a%e8%bf%87%e4%b8%b2%e5%8f%a3%e7%bb%88%e7%ab%af%e8%bf%9e%e6%8e%a5%e6%a0%91%e8%8e%93%e6%b4%bech340/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[原创] 在树莓派的Ubuntu MATE 18.04系统上连接WiFi</title>
		<link>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be%e7%9a%84ubuntu-mate-18-04%e7%b3%bb%e7%bb%9f%e4%b8%8a%e8%bf%9e%e6%8e%a5wifi/</link>
					<comments>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be%e7%9a%84ubuntu-mate-18-04%e7%b3%bb%e7%bb%9f%e4%b8%8a%e8%bf%9e%e6%8e%a5wifi/#respond</comments>
		
		<dc:creator><![CDATA[learnhard]]></dc:creator>
		<pubDate>Thu, 05 Dec 2019 16:59:55 +0000</pubDate>
				<category><![CDATA[Raspberry Pi/树莓派]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Ubuntu MATE]]></category>
		<category><![CDATA[WiFi]]></category>
		<category><![CDATA[树莓派]]></category>
		<guid isPermaLink="false">https://www.codelast.com/?p=11223</guid>

					<description><![CDATA[<p>
要查看更多树莓派相关文章，请点击<a href="https://www.codelast.com/?p=5013" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">这里</span></a>。</p>
<p>树莓派3B(V1.2)有板载WiFi模块，而<a href="https://ubuntu-mate.org/raspberry-pi/" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">Ubuntu MATE</span></a> 18.04也支持它，下面来看看怎么在命令行启用。<br />
<span id="more-11223"></span></p>
<div>
	<span style="color: rgb(255, 0, 0);"><span style="background-color: rgb(0, 255, 0);">▶▶</span></span>&#160;修改网络配置文件，添加WiFi配置内容</div>
<blockquote>
<div>
		cd /etc/netplan</div>
</blockquote>
<div>
	里面只有一个文件：</div>
<blockquote>
<div>
		01-network-manager-all.yaml</div>
</blockquote>
<div>
	备份，然后编辑它：</div>
<blockquote>
<div>
		sudo cp 01-network-manager-all.yaml 01-network-manager-all.yaml.bak<br />
		sudo vim.tiny 01-network-manager-all.yaml</div>
</blockquote>
<div>
	下面的<span style="color:#0000ff;">蓝色</span>部分，是我新添加的内容：</div>
<blockquote>
<div>
		# Let NetworkManager manage all devices on this system</div>
<div>
		network:</div>
<div>
		&#160; version: 2</div>
<div>
		&#160; renderer: NetworkManager</div>
<div>
		<span style="color:#0000ff;">&#160; # below are WiFi info</span></div>
<div>
		<span style="color:#0000ff;">&#160; wifis:</span></div>
<div>
		<span style="color:#0000ff;">&#160; &#160; wlan0:</span></div>
<div>
		<span style="color:#0000ff;">&#160; &#160; &#160; optional: true</span></div>
<div>
		<span style="color:#0000ff;">&#160; &#160; &#160; access-points:</span></div>
<div>
		<span style="color:#0000ff;">&#160; &#160; &#160; &#160; &#34;MyWiFi&#34;:</span></div>
<div>
		<span style="color:#0000ff;">&#160; &#160; &#160; &#160; &#160; password: &#34;my_password&#34;</span></div>
<div>
		<span style="color:#0000ff;">&#160; &#160; &#160; dhcp4: true</span></div>
</blockquote>
<div>
	&#160;</div>
<div>
	其中的&#34;<span style="color:#ff0000;">wlan0</span>&#34;是用 iwconfig&#160;命令得到的网卡名；&#34;<span style="color:#0000ff;">MyWiFi</span>&#34;，则是我的无线网络的SSID；&#34;<span style="color: rgb(0, 0, 255);">my_password</span>&#34;是无线网络的密码。这些参数要根据实际情况修改。</div>
<div>
	保存文件，接着就可以测试这个配置了。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a></div>&#8230; <a href="https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be%e7%9a%84ubuntu-mate-18-04%e7%b3%bb%e7%bb%9f%e4%b8%8a%e8%bf%9e%e6%8e%a5wifi/" class="read-more">Read More </a>]]></description>
										<content:encoded><![CDATA[<p>
要查看更多树莓派相关文章，请点击<a href="https://www.codelast.com/?p=5013" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">这里</span></a>。</p>
<p>树莓派3B(V1.2)有板载WiFi模块，而<a href="https://ubuntu-mate.org/raspberry-pi/" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">Ubuntu MATE</span></a> 18.04也支持它，下面来看看怎么在命令行启用。<br />
<span id="more-11223"></span></p>
<div>
	<span style="color: rgb(255, 0, 0);"><span style="background-color: rgb(0, 255, 0);"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span></span>&nbsp;修改网络配置文件，添加WiFi配置内容</div>
<blockquote>
<div>
		cd /etc/netplan</div>
</blockquote>
<div>
	里面只有一个文件：</div>
<blockquote>
<div>
		01-network-manager-all.yaml</div>
</blockquote>
<div>
	备份，然后编辑它：</div>
<blockquote>
<div>
		sudo cp 01-network-manager-all.yaml 01-network-manager-all.yaml.bak<br />
		sudo vim.tiny 01-network-manager-all.yaml</div>
</blockquote>
<div>
	下面的<span style="color:#0000ff;">蓝色</span>部分，是我新添加的内容：</div>
<blockquote>
<div>
		# Let NetworkManager manage all devices on this system</div>
<div>
		network:</div>
<div>
		&nbsp; version: 2</div>
<div>
		&nbsp; renderer: NetworkManager</div>
<div>
		<span style="color:#0000ff;">&nbsp; # below are WiFi info</span></div>
<div>
		<span style="color:#0000ff;">&nbsp; wifis:</span></div>
<div>
		<span style="color:#0000ff;">&nbsp; &nbsp; wlan0:</span></div>
<div>
		<span style="color:#0000ff;">&nbsp; &nbsp; &nbsp; optional: true</span></div>
<div>
		<span style="color:#0000ff;">&nbsp; &nbsp; &nbsp; access-points:</span></div>
<div>
		<span style="color:#0000ff;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;MyWiFi&quot;:</span></div>
<div>
		<span style="color:#0000ff;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; password: &quot;my_password&quot;</span></div>
<div>
		<span style="color:#0000ff;">&nbsp; &nbsp; &nbsp; dhcp4: true</span></div>
</blockquote>
<div>
	&nbsp;</div>
<div>
	其中的&quot;<span style="color:#ff0000;">wlan0</span>&quot;是用 iwconfig&nbsp;命令得到的网卡名；&quot;<span style="color:#0000ff;">MyWiFi</span>&quot;，则是我的无线网络的SSID；&quot;<span style="color: rgb(0, 0, 255);">my_password</span>&quot;是无线网络的密码。这些参数要根据实际情况修改。</div>
<div>
	保存文件，接着就可以测试这个配置了。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	<span style="color: rgb(255, 0, 0);"><span style="background-color: rgb(0, 255, 0);"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span></span>&nbsp;测试配置</div>
<blockquote>
<div>
		sudo netplan --debug try</div>
</blockquote>
<div>
	会输出一堆信息，部分内容如下：</div>
<blockquote>
<div>
		DEBUG:New interfaces: set()</div>
<div>
		** (generate:1387): DEBUG: 00:07:20.808: Processing input file /etc/netplan/01-network-manager-all.yaml..</div>
<div>
		** (generate:1387): DEBUG: 00:07:20.809: starting new processing pass</div>
<div>
		** (generate:1387): DEBUG: 00:07:20.809: wlan0: adding wifi AP &#39;MyWiFi&#39;</div>
<div>
		** (generate:1387): DEBUG: 00:07:20.809: wlan0: setting default backend to 2</div>
<div>
		** (generate:1387): DEBUG: 00:07:20.810: Configuration is valid&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>
<div>
		** (generate:1387): DEBUG: 00:07:20.810: Generating output files..</div>
<div>
		** (generate:1387): DEBUG: 00:07:20.810: networkd: definition wlan0 is not for us (backend 2)</div>
<div>
		DEBUG:no netplan generated networkd configuration exists</div>
<div>
		DEBUG:netplan generated NM configuration changed, restarting NM</div>
<div>
		DEBUG:wlan0 not found in {}</div>
<div>
		(...中间省略...)</div>
<div>
		DEBUG:Skipping non-physical interface: lo</div>
<div>
		DEBUG:Skipping non-physical interface: eth0</div>
<div>
		DEBUG:{}</div>
<div>
		DEBUG:netplan triggering .link rules for lo</div>
<div>
		DEBUG:netplan triggering .link rules for eth0</div>
<div>
		DEBUG:netplan triggering .link rules for wlan0</div>
<div>
		Do you want to keep these settings?</div>
<div>
		(...后面省略...)</div>
</blockquote>
<div>
	&nbsp;</div>
<div>
	如果不出错的话，回车就会保存刚才添加的配置（如果不回车，过一段时间之后会自动revert到修改之前的版本）。</div>
<div>
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a></div>
<div>
	为确保成功，再执行一遍：</div>
<blockquote>
<div>
		sudo netplan --debug generate</div>
</blockquote>
<div>
	输出：</div>
<blockquote>
<div>
		DEBUG:command generate: running [&#39;/lib/netplan/generate&#39;]</div>
<div>
		** (generate:1579): DEBUG: 00:13:42.069: Processing input file /etc/netplan/01-network-manager-all.yaml..</div>
<div>
		** (generate:1579): DEBUG: 00:13:42.070: starting new processing pass</div>
<div>
		** (generate:1579): DEBUG: 00:13:42.070: wlan0: adding wifi AP &#39;MyWiFi&#39;</div>
<div>
		** (generate:1579): DEBUG: 00:13:42.070: wlan0: setting default backend to 2</div>
<div>
		** (generate:1579): DEBUG: 00:13:42.070: Configuration is valid</div>
<div>
		** (generate:1579): DEBUG: 00:13:42.070: Generating output files..</div>
<div>
		** (generate:1579): DEBUG: 00:13:42.070: networkd: definition wlan0 is not for us (backend 2)</div>
</blockquote>
<div>
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a></div>
<div>
	最后应用配置：</div>
<blockquote>
<div>
		sudo netplan --debug apply</div>
</blockquote>
<div>
	&nbsp;</div>
<div>
	如果上面的命令不出错一切正常，现在可以重启树莓派了：</div>
<blockquote>
<div>
		sudo shutdown -r now</div>
</blockquote>
<div>
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a></div>
<div>
	<span style="color: rgb(255, 0, 0);"><span style="background-color: rgb(0, 255, 0);"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span></span>&nbsp;一些问题<br />
	如果不能连接WiFi，要看你的树莓派能不能扫描到你在配置文件中设置的SSID，可以用下面的命令查看树莓派能扫描到哪些SSID：</div>
<blockquote>
<div>
		sudo iw dev wlan0 scan | grep SSID</div>
</blockquote>
<div>
	输出类似于：</div>
<blockquote>
<div>
		SSID: ChinaNet-HG5o</div>
<div>
		SSID: ASUS-HuHu</div>
<div>
		SSID: TP-LINK_6D7F</div>
</blockquote>
<div>
	如果你设置的SSID是公开的，并且不在这个列表中，那么树莓派就连不上了。</div>
<div>
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;版权声明&nbsp;<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;<br />
	转载需注明出处：<u><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><em><span style="color: rgb(0, 0, 255);"><strong style="font-size: 16px;"><span style="font-family: arial, helvetica, sans-serif;">codelast.com</span></strong></span></em></a></u>&nbsp;<br />
	感谢关注我的微信公众号（微信扫一扫）：</p>
<p style="border: 0px; font-size: 13px; margin: 0px 0px 9px; outline: 0px; padding: 0px; color: rgb(77, 77, 77);">
		<img decoding="async" alt="wechat qrcode of codelast" src="https://www.codelast.com/codelast_wechat_qr_code.jpg" style="width: 200px; height: 200px;" /></p>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be%e7%9a%84ubuntu-mate-18-04%e7%b3%bb%e7%bb%9f%e4%b8%8a%e8%bf%9e%e6%8e%a5wifi/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[原创] 树莓派：这个世界是你们的，是我们的，但终究是Python的！</title>
		<link>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e6%a0%91%e8%8e%93%e6%b4%be%ef%bc%9a%e8%bf%99%e4%b8%aa%e4%b8%96%e7%95%8c%e6%98%af%e4%bd%a0%e4%bb%ac%e7%9a%84%ef%bc%8c%e6%98%af%e6%88%91%e4%bb%ac%e7%9a%84%ef%bc%8c%e4%bd%86/</link>
					<comments>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e6%a0%91%e8%8e%93%e6%b4%be%ef%bc%9a%e8%bf%99%e4%b8%aa%e4%b8%96%e7%95%8c%e6%98%af%e4%bd%a0%e4%bb%ac%e7%9a%84%ef%bc%8c%e6%98%af%e6%88%91%e4%bb%ac%e7%9a%84%ef%bc%8c%e4%bd%86/#respond</comments>
		
		<dc:creator><![CDATA[learnhard]]></dc:creator>
		<pubDate>Sat, 30 Nov 2019 18:13:05 +0000</pubDate>
				<category><![CDATA[Raspberry Pi/树莓派]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[GPIO]]></category>
		<category><![CDATA[pigpio]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[树莓派]]></category>
		<guid isPermaLink="false">https://www.codelast.com/?p=11141</guid>

					<description><![CDATA[<p>
要查看更多树莓派相关文章，请点击<a href="https://www.codelast.com/?p=5013" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">这里</span></a>。</p>
<p>很多年前我刚开始玩树莓派的时候，Python还是个&#8220;很不火&#8221;的编程语言，而如今Python借着深度学习(Deep Learning)的东风，已经毫无疑问地成了世界上最耀眼的明日之星；想当年我刚开始玩树莓派的时候，使用<a href="http://wiringpi.com/" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">WiringPi</span></a>开发库、在C++下开发GPIO应用是一个比较明智的选择，而如今树莓派上的Pyhton GPIO库已经百花齐放，并且多个树莓派的OS都已经内置了一或多个Python GPIO开发包，真正做到了：你只要装好系统，就马上能用Python写程序操作GPIO，立等可用。<br />
<span id="more-11141"></span><br />
C++编译一个简单的GPIO程序都要写Makefile，修改一点东西也得重新编译；而Python直接在交互模式下就可以测试GPIO，方便得让你想哭。相比之下，对一般的GPIO应用而言，我真的找不到什么理由再去用C++ &#38; WiringPi来做。此外还有最重要的一点：树莓派在教育领域的广泛应用，使得Python成为了最合适的教育工具。儿童是祖国的花朵，如果让小孩子们在树莓派上用C++，这花朵还能好好成长吗？<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
下面就来看看，在Ubuntu MATE 18.04 系统下，用Python来开发一个GPIO应用有多么简单。</p>
<p><span style="color: rgb(255, 0, 0);"><span style="background-color: rgb(0, 255, 0);">▶▶</span></span>&#160;选择哪个GPIO库<br />
之前我已经<a href="https://www.codelast.com/?p=11133" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">装好了Miniconda环境</span></a>，而知名Python GPIO库 RPi.GPIO 在Anaconda上没有Python 3.6的版本，因此我安装了另一个<a href="http://abyz.me.uk/rpi/pigpio/index.html" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">pigpio</span></a>库：</p>
<blockquote>
<div>
		conda install -c cbetters pigpio</div>
</blockquote>
<div>
	如果你装的是Raspbian系统，那么它已经自带了&#160;RPi.GPIO，你啥都不需要做就可以开始上台表演了。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	<span style="color: rgb(255, 0, 0);"><span style="background-color: rgb(0, 255, 0);">▶▶</span></span>&#160;启动 pigpio&#160;的daemon进程<br />
	这是基于 pigpio 的Python程序能work的必要条件：</div>
<blockquote>
<div>
		sudo&#160;pigpiod</div>
</blockquote>
<div>
	如果没有启动它，那么调用了 pigpio 的Python程序运行的时候会报错：
<blockquote>
<div>
			Can&#39;t connect to pigpio at localhost(8888)</div>
<div>
			&#160;</div>
<div>
			Did you start the pigpio daemon?</div></blockquote></div>&#8230; <a href="https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e6%a0%91%e8%8e%93%e6%b4%be%ef%bc%9a%e8%bf%99%e4%b8%aa%e4%b8%96%e7%95%8c%e6%98%af%e4%bd%a0%e4%bb%ac%e7%9a%84%ef%bc%8c%e6%98%af%e6%88%91%e4%bb%ac%e7%9a%84%ef%bc%8c%e4%bd%86/" class="read-more">Read More </a>]]></description>
										<content:encoded><![CDATA[<p>
要查看更多树莓派相关文章，请点击<a href="https://www.codelast.com/?p=5013" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">这里</span></a>。</p>
<p>很多年前我刚开始玩树莓派的时候，Python还是个&ldquo;很不火&rdquo;的编程语言，而如今Python借着深度学习(Deep Learning)的东风，已经毫无疑问地成了世界上最耀眼的明日之星；想当年我刚开始玩树莓派的时候，使用<a href="http://wiringpi.com/" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">WiringPi</span></a>开发库、在C++下开发GPIO应用是一个比较明智的选择，而如今树莓派上的Pyhton GPIO库已经百花齐放，并且多个树莓派的OS都已经内置了一或多个Python GPIO开发包，真正做到了：你只要装好系统，就马上能用Python写程序操作GPIO，立等可用。<br />
<span id="more-11141"></span><br />
C++编译一个简单的GPIO程序都要写Makefile，修改一点东西也得重新编译；而Python直接在交互模式下就可以测试GPIO，方便得让你想哭。相比之下，对一般的GPIO应用而言，我真的找不到什么理由再去用C++ &amp; WiringPi来做。此外还有最重要的一点：树莓派在教育领域的广泛应用，使得Python成为了最合适的教育工具。儿童是祖国的花朵，如果让小孩子们在树莓派上用C++，这花朵还能好好成长吗？<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
下面就来看看，在Ubuntu MATE 18.04 系统下，用Python来开发一个GPIO应用有多么简单。</p>
<p><span style="color: rgb(255, 0, 0);"><span style="background-color: rgb(0, 255, 0);"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span></span>&nbsp;选择哪个GPIO库<br />
之前我已经<a href="https://www.codelast.com/?p=11133" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">装好了Miniconda环境</span></a>，而知名Python GPIO库 RPi.GPIO 在Anaconda上没有Python 3.6的版本，因此我安装了另一个<a href="http://abyz.me.uk/rpi/pigpio/index.html" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">pigpio</span></a>库：</p>
<blockquote>
<div>
		conda install -c cbetters pigpio</div>
</blockquote>
<div>
	如果你装的是Raspbian系统，那么它已经自带了&nbsp;RPi.GPIO，你啥都不需要做就可以开始上台表演了。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	<span style="color: rgb(255, 0, 0);"><span style="background-color: rgb(0, 255, 0);"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span></span>&nbsp;启动 pigpio&nbsp;的daemon进程<br />
	这是基于 pigpio 的Python程序能work的必要条件：</div>
<blockquote>
<div>
		sudo&nbsp;pigpiod</div>
</blockquote>
<div>
	如果没有启动它，那么调用了 pigpio 的Python程序运行的时候会报错：</p>
<blockquote>
<div>
			Can&#39;t connect to pigpio at localhost(8888)</div>
<div>
			&nbsp;</div>
<div>
			Did you start the pigpio daemon? E.g. sudo pigpiod</div>
<div>
			&nbsp;</div>
<div>
			Did you specify the correct Pi host/port in the environment</div>
<div>
			variables PIGPIO_ADDR/PIGPIO_PORT?</div>
<div>
			E.g. export PIGPIO_ADDR=soft, export PIGPIO_PORT=8888</div>
<div>
			&nbsp;</div>
<div>
			Did you specify the correct Pi host/port in the</div>
<div>
			pigpio.pi() function? E.g. pigpio.pi(&#39;soft&#39;, 8888)</div>
</blockquote>
<p>	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	<span style="color: rgb(255, 0, 0);"><span style="background-color: rgb(0, 255, 0);"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span></span>&nbsp;树莓派硬件接线<br />
	这里做一个最简单的实验：用树莓派的GPIO口点亮LED。</p>
<div>
		<a href="https://pinout.xyz" rel="noopener noreferrer" target="_blank">https://pinout.xyz</a>&nbsp;这个网站上有树莓派的引脚分配图。这里我使用树莓派的物理编号为&nbsp;<span style="color:#ff0000;">11&nbsp;</span>的GPIO口，也就是Broadcom命名方式下的 <span style="color:#ff0000;">GPIO 17&nbsp;</span>口。<br />
		<img decoding="async" alt="raspberry pi gpio 17" src="https://www.codelast.com/wp-content/uploads/2019/11/rpi_gpio_17.jpg" style="width: 516px; height: 900px;" /><br />
		<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
		<span style="color: rgb(255, 0, 0);"><span style="background-color: rgb(0, 255, 0);"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span></span>&nbsp;Python程序<br />
		程序这么简单我还能说什么：</p>
<section class="output_wrapper" id="output_wrapper_id" style="font-size: 16px; color: rgb(62, 62, 62); line-height: 1.6; letter-spacing: 0px; font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;">
<pre style="font-size: inherit; color: inherit; line-height: inherit; margin-top: 0px; margin-bottom: 0px; padding: 0px;">
<code class="python language-python hljs" style="margin: 0px 2px; line-height: 18px; font-size: 14px; letter-spacing: 0px; font-family: Consolas, Inconsolata, Courier, monospace; border-radius: 0px; color: rgb(169, 183, 198); background: rgb(40, 43, 46); padding: 0.5em; overflow-wrap: normal !important; word-break: normal !important; overflow: auto !important; display: -webkit-box !important;"><span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(248, 35, 117); word-wrap: inherit !important; word-break: inherit !important;">import</span>&nbsp;pigpio

pi&nbsp;=&nbsp;pigpio.pi()
pi.set_mode(<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(174, 135, 250); word-wrap: inherit !important; word-break: inherit !important;">17</span>,&nbsp;pigpio.OUTPUT)&nbsp;&nbsp;<span class="hljs-comment" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(128, 128, 128); word-wrap: inherit !important; word-break: inherit !important;">#&nbsp;把GPIO&nbsp;17设置成输出模式</span>
pi.write(<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(174, 135, 250); word-wrap: inherit !important; word-break: inherit !important;">17</span>,&nbsp;<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(174, 135, 250); word-wrap: inherit !important; word-break: inherit !important;">1</span>)&nbsp;&nbsp;<span class="hljs-comment" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(128, 128, 128); word-wrap: inherit !important; word-break: inherit !important;">#&nbsp;把GPIO&nbsp;17设置成高电平</span>
</code></pre>
</section>
<p>这代码完全不用做任何解释。<br />
		<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
		<span style="color: rgb(255, 0, 0);"><span style="background-color: rgb(0, 255, 0);"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span></span>&nbsp;效果实拍<br />
		为了兼容性，MP4视频被我转成了体积巨大的gif(我容易吗我)，且看且珍惜：<br />
		<img decoding="async" alt="pigpio control led" src="https://www.codelast.com/wp-content/uploads/2019/11/pigpio_control_led.gif" /><br />
		<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
		<span style="color: rgb(255, 0, 0);"><span style="background-color: rgb(0, 255, 0);"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span></span>&nbsp;总结<br />
		<span style="color:#ff0000;">对树莓派来说：</span><br />
		<span style="background-color:#ffff00;">☞</span> 人生苦短，请你用Python！<br />
		<span style="background-color: rgb(255, 255, 0);">☞</span>&nbsp;在树莓派上折腾GPIO，用Python！<br />
		<span style="background-color: rgb(255, 255, 0);">☞</span>&nbsp;For kids，毫无疑问地选Python！<br />
		<span style="background-color: rgb(255, 255, 0);">☞</span>&nbsp;这个世界是你们的，是我们的，但终究是Python的！</p>
<p>		<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
		<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;版权声明&nbsp;<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;<br />
		转载需注明出处：<u><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><em><span style="color: rgb(0, 0, 255);"><strong style="font-size: 16px;"><span style="font-family: arial, helvetica, sans-serif;">codelast.com</span></strong></span></em></a></u>&nbsp;<br />
		感谢关注我的微信公众号（微信扫一扫）：</p>
<p style="border: 0px; font-size: 13px; margin: 0px 0px 9px; outline: 0px; padding: 0px; color: rgb(77, 77, 77);">
			<img decoding="async" alt="wechat qrcode of codelast" src="https://www.codelast.com/codelast_wechat_qr_code.jpg" style="width: 200px; height: 200px;" /></p>
</p></div>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e6%a0%91%e8%8e%93%e6%b4%be%ef%bc%9a%e8%bf%99%e4%b8%aa%e4%b8%96%e7%95%8c%e6%98%af%e4%bd%a0%e4%bb%ac%e7%9a%84%ef%bc%8c%e6%98%af%e6%88%91%e4%bb%ac%e7%9a%84%ef%bc%8c%e4%bd%86/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[原创] 在树莓派上安装 Miniconda 并创建 Python 3.6环境</title>
		<link>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be%e4%b8%8a%e5%ae%89%e8%a3%85-miniconda-%e5%b9%b6%e5%88%9b%e5%bb%ba-python-3-6%e7%8e%af%e5%a2%83/</link>
					<comments>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be%e4%b8%8a%e5%ae%89%e8%a3%85-miniconda-%e5%b9%b6%e5%88%9b%e5%bb%ba-python-3-6%e7%8e%af%e5%a2%83/#respond</comments>
		
		<dc:creator><![CDATA[learnhard]]></dc:creator>
		<pubDate>Sat, 30 Nov 2019 17:04:31 +0000</pubDate>
				<category><![CDATA[Raspberry Pi/树莓派]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[miniconda]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[树莓派]]></category>
		<guid isPermaLink="false">https://www.codelast.com/?p=11133</guid>

					<description><![CDATA[<p>
要查看更多树莓派相关文章，请点击<a href="https://www.codelast.com/?p=5013" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">这里</span></a>。</p>
<p>在树莓派3上安装Miniconda，并不能安装普通的Linux版，你得安装 for ARM v7&#160;的版本：</p>
<blockquote>
<p>
		wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-armv7l.sh</p>
<div>
		chmod +x Miniconda3-latest-Linux-armv7l.sh</div>
<div>
		./Miniconda3-latest-Linux-armv7l.sh</div>
</blockquote>
<div>
	跟着向导一步步走下去就可以完成安装。<br />
	<span id="more-11133"></span><br />
	这样安装上的miniconda，对应的Python是3.4版本，要安装Python 3.6版本的环境，可以这样操作：
<blockquote>
<div>
			conda config --add channels rpi</div>
<div>
			conda install python=3.6</div>
<div>
			conda create --name py36 python=3.6</div>
</blockquote>
<div>
		<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
		然后就可以进入Python 3.6的环境了：</div>
<blockquote>
<div>
			source activate py36</div>
</blockquote>
<div>
		最后不忘在&#160;.bashrc 中添加命令别名：</div>
<blockquote>
<div>
			alias py36=&#39;source activate py36&#39;</div>
</blockquote>
<div>
		这样就可以用 py36&#160;命令来进入Python 3.6的环境了。
<p>		<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a></p></div></div>&#8230; <a href="https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be%e4%b8%8a%e5%ae%89%e8%a3%85-miniconda-%e5%b9%b6%e5%88%9b%e5%bb%ba-python-3-6%e7%8e%af%e5%a2%83/" class="read-more">Read More </a>]]></description>
										<content:encoded><![CDATA[<p>
要查看更多树莓派相关文章，请点击<a href="https://www.codelast.com/?p=5013" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">这里</span></a>。</p>
<p>在树莓派3上安装Miniconda，并不能安装普通的Linux版，你得安装 for ARM v7&nbsp;的版本：</p>
<blockquote>
<p>
		wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-armv7l.sh</p>
<div>
		chmod +x Miniconda3-latest-Linux-armv7l.sh</div>
<div>
		./Miniconda3-latest-Linux-armv7l.sh</div>
</blockquote>
<div>
	跟着向导一步步走下去就可以完成安装。<br />
	<span id="more-11133"></span><br />
	这样安装上的miniconda，对应的Python是3.4版本，要安装Python 3.6版本的环境，可以这样操作：</p>
<blockquote>
<div>
			conda config --add channels rpi</div>
<div>
			conda install python=3.6</div>
<div>
			conda create --name py36 python=3.6</div>
</blockquote>
<div>
		<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
		然后就可以进入Python 3.6的环境了：</div>
<blockquote>
<div>
			source activate py36</div>
</blockquote>
<div>
		最后不忘在&nbsp;.bashrc 中添加命令别名：</div>
<blockquote>
<div>
			alias py36=&#39;source activate py36&#39;</div>
</blockquote>
<div>
		这样就可以用 py36&nbsp;命令来进入Python 3.6的环境了。</p>
<p>		<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
		<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;版权声明&nbsp;<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;<br />
		转载需注明出处：<u><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><em><span style="color: rgb(0, 0, 255);"><strong style="font-size: 16px;"><span style="font-family: arial, helvetica, sans-serif;">codelast.com</span></strong></span></em></a></u>&nbsp;<br />
		感谢关注我的微信公众号（微信扫一扫）：</p>
<p style="border: 0px; font-size: 13px; margin: 0px 0px 9px; outline: 0px; padding: 0px; color: rgb(77, 77, 77);">
			<img decoding="async" alt="wechat qrcode of codelast" src="https://www.codelast.com/codelast_wechat_qr_code.jpg" style="width: 200px; height: 200px;" /></p>
</p></div>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be%e4%b8%8a%e5%ae%89%e8%a3%85-miniconda-%e5%b9%b6%e5%88%9b%e5%bb%ba-python-3-6%e7%8e%af%e5%a2%83/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[原创] 树莓派的 Ubuntu MATE 18.04 系统无法 apt upgrade 更新的问题</title>
		<link>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e6%a0%91%e8%8e%93%e6%b4%be%e7%9a%84-ubuntu-mate-18-04-%e7%b3%bb%e7%bb%9f%e6%97%a0%e6%b3%95-apt-upgrade-%e6%9b%b4%e6%96%b0%e7%9a%84%e9%97%ae%e9%a2%98/</link>
					<comments>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e6%a0%91%e8%8e%93%e6%b4%be%e7%9a%84-ubuntu-mate-18-04-%e7%b3%bb%e7%bb%9f%e6%97%a0%e6%b3%95-apt-upgrade-%e6%9b%b4%e6%96%b0%e7%9a%84%e9%97%ae%e9%a2%98/#comments</comments>
		
		<dc:creator><![CDATA[learnhard]]></dc:creator>
		<pubDate>Sat, 30 Nov 2019 16:49:44 +0000</pubDate>
				<category><![CDATA[Raspberry Pi/树莓派]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[apt upgrade]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Ubuntu MATE]]></category>
		<category><![CDATA[树莓派]]></category>
		<guid isPermaLink="false">https://www.codelast.com/?p=11129</guid>

					<description><![CDATA[<p>
要查看更多树莓派相关文章，请点击<a href="https://www.codelast.com/?p=5013" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">这里</span></a>。</p>
<p>在树莓派上<a href="https://www.codelast.com/?p=11069" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">安装好Ubuntu MATE</span></a>&#160;18.04之后，我在试图更新系统的时候遇到了 bluez&#160;软件包和&#160;内核固件&#160;冲突，从而导致无法进行下去的问题，本文记录一下现场情况以及解决办法。<br />
<span id="more-11129"></span><br />
更新系统：</p>
<blockquote>
<p>
		sudo apt update<br />
		sudo apt upgrade</p>
</blockquote>
<p>然后就出错了：</p>
<blockquote>
<div>
		正在读取软件包列表... 完成</div>
<div>
		正在分析软件包的依赖关系树</div>
<div>
		正在读取状态信息... 完成</div>
<div>
		正在计算更新... 完成</div>
<div>
		下列软件包将被升级：&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; 0 个</div>
<div>
		&#160; linux-firmware-raspi2</div>
<div>
		升级了 1 个软件包，新安装了 0 个软件包，要卸载 0 个软件包，有 0 个软件包未被升级。</div>
<div>
		需要下载 0 B/3,612 kB 的归档。</div>
<div>
		解压缩后将会空出 35.8 kB 的空间。</div>
<div>
		您希望继续执行吗？ [Y/n]</div>
<div>
		(正在读取数据库 ...</div></blockquote>&#8230; <a href="https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e6%a0%91%e8%8e%93%e6%b4%be%e7%9a%84-ubuntu-mate-18-04-%e7%b3%bb%e7%bb%9f%e6%97%a0%e6%b3%95-apt-upgrade-%e6%9b%b4%e6%96%b0%e7%9a%84%e9%97%ae%e9%a2%98/" class="read-more">Read More </a>]]></description>
										<content:encoded><![CDATA[<p>
要查看更多树莓派相关文章，请点击<a href="https://www.codelast.com/?p=5013" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">这里</span></a>。</p>
<p>在树莓派上<a href="https://www.codelast.com/?p=11069" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">安装好Ubuntu MATE</span></a>&nbsp;18.04之后，我在试图更新系统的时候遇到了 bluez&nbsp;软件包和&nbsp;内核固件&nbsp;冲突，从而导致无法进行下去的问题，本文记录一下现场情况以及解决办法。<br />
<span id="more-11129"></span><br />
更新系统：</p>
<blockquote>
<p>
		sudo apt update<br />
		sudo apt upgrade</p>
</blockquote>
<p>然后就出错了：</p>
<blockquote>
<div>
		正在读取软件包列表... 完成</div>
<div>
		正在分析软件包的依赖关系树</div>
<div>
		正在读取状态信息... 完成</div>
<div>
		正在计算更新... 完成</div>
<div>
		下列软件包将被升级：&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0 个</div>
<div>
		&nbsp; linux-firmware-raspi2</div>
<div>
		升级了 1 个软件包，新安装了 0 个软件包，要卸载 0 个软件包，有 0 个软件包未被升级。</div>
<div>
		需要下载 0 B/3,612 kB 的归档。</div>
<div>
		解压缩后将会空出 35.8 kB 的空间。</div>
<div>
		您希望继续执行吗？ [Y/n]</div>
<div>
		(正在读取数据库 ... 系统当前共安装有 139961 个文件和目录。)</div>
<div>
		正准备解包 .../linux-firmware-raspi2_1.20190215-0ubuntu0.18.04.1_armhf.deb&nbsp; ...</div>
<div>
		正在将 linux-firmware-raspi2 (1.20190215-0ubuntu0.18.04.1) 解包到 (1.20180919-0ubuntu0.18.04.2) 上 ...</div>
<div>
		dpkg: 处理归档 /var/cache/apt/archives/linux-firmware-raspi2_1.20190215-0ubuntu0.18.04.1_armhf.deb (--unpack)时出错：</div>
<div>
		&nbsp;正试图覆盖 /lib/firmware/brcm/BCM43430A1.hcd，它同时被包含于软件包 bluez-firmware 1.2-4+rpt1~bionic1.0</div>
<div>
		dpkg-deb: 错误: 粘贴 subprocess was killed by signal (Broken pipe)</div>
<div>
		在处理时有错误发生：</div>
<div>
		&nbsp;/var/cache/apt/archives/linux-firmware-raspi2_1.20190215-0ubuntu0.18.04.1_armhf.deb</div>
<div>
		^[[A^[[A^[[A^[[A^[[AE: Sub-process /usr/bin/dpkg returned an error code (1)</div>
</blockquote>
<div>
	原因是&ldquo;bluez&rdquo;这个和蓝牙相关的package和linux-firmware-raspi2冲突了。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	如果你不使用树莓派上的蓝牙模块，可以像我一样强行安装：</p>
<blockquote>
<p>
			sudo dpkg -i --force-overwrite /var/cache/apt/archives/linux-firmware-raspi2_1.20190215-0ubuntu0.18.04.1_armhf.deb</p>
</blockquote>
<p>	会输出一堆信息，类似于：</p>
<blockquote>
<div>
			(正在读取数据库 ... 系统当前共安装有 139961 个文件和目录。)</div>
<div>
			正准备解包 .../linux-firmware-raspi2_1.20190215-0ubuntu0.18.04.1_armhf.deb&nbsp; ...</div>
<div>
			正在将 linux-firmware-raspi2 (1.20190215-0ubuntu0.18.04.1) 解包到 (1.20180919-0ubuntu0.18.04.2) 上 ...</div>
<div>
			dpkg: 警告: 由于开启了 --force 选项，以下问题被忽略：</div>
<div>
			dpkg: 警告: 正试图覆盖 /lib/firmware/brcm/BCM43430A1.hcd，它同时被包含于软件包 bluez-firmware 1.2-4+rpt1~bionic1.0</div>
<div>
			dpkg: 警告: 由于开启了 --force 选项，以下问题被忽略：</div>
<div>
			dpkg: 警告: 正试图覆盖 /lib/firmware/brcm/BCM4345C0.hcd，它同时被包含于软件包 bluez-firmware 1.2-4+rpt1~bionic1.0</div>
<div>
			正在设置 linux-firmware-raspi2 (1.20190215-0ubuntu0.18.04.1) ...</div>
</blockquote>
<div>
		然后：</p>
<blockquote>
<p>
				sudo apt-get -f install</p>
</blockquote>
<p>		输出：</p>
<blockquote>
<div>
				正在读取软件包列表... 完成</div>
<div>
				正在分析软件包的依赖关系树</div>
<div>
				正在读取状态信息... 完成</div>
<div>
				升级了 0 个软件包，新安装了 0 个软件包，要卸载 0 个软件包，有 0 个软件包未被升级。</div>
</blockquote></div>
<p>	这就搞定了。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;版权声明&nbsp;<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;<br />
	转载需注明出处：<u><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><em><span style="color: rgb(0, 0, 255);"><strong style="font-size: 16px;"><span style="font-family: arial, helvetica, sans-serif;">codelast.com</span></strong></span></em></a></u>&nbsp;<br />
	感谢关注我的微信公众号（微信扫一扫）：</p>
<p style="border: 0px; font-size: 13px; margin: 0px 0px 9px; outline: 0px; padding: 0px; color: rgb(77, 77, 77);">
		<img decoding="async" alt="wechat qrcode of codelast" src="https://www.codelast.com/codelast_wechat_qr_code.jpg" style="width: 200px; height: 200px;" /></p>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e6%a0%91%e8%8e%93%e6%b4%be%e7%9a%84-ubuntu-mate-18-04-%e7%b3%bb%e7%bb%9f%e6%97%a0%e6%b3%95-apt-upgrade-%e6%9b%b4%e6%96%b0%e7%9a%84%e9%97%ae%e9%a2%98/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title>[原创] 树莓派的 Ubuntu MATE 系统打开 ssh 服务</title>
		<link>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e6%a0%91%e8%8e%93%e6%b4%be%e7%9a%84-ubuntu-mate-%e7%b3%bb%e7%bb%9f%e6%89%93%e5%bc%80-ssh-%e6%9c%8d%e5%8a%a1/</link>
					<comments>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e6%a0%91%e8%8e%93%e6%b4%be%e7%9a%84-ubuntu-mate-%e7%b3%bb%e7%bb%9f%e6%89%93%e5%bc%80-ssh-%e6%9c%8d%e5%8a%a1/#respond</comments>
		
		<dc:creator><![CDATA[learnhard]]></dc:creator>
		<pubDate>Sat, 30 Nov 2019 16:32:07 +0000</pubDate>
				<category><![CDATA[Raspberry Pi/树莓派]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[Ubuntu MATE]]></category>
		<category><![CDATA[树莓派]]></category>
		<guid isPermaLink="false">https://www.codelast.com/?p=11120</guid>

					<description><![CDATA[<p>
要查看更多树莓派相关文章，请点击<a href="https://www.codelast.com/?p=5013" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">这里</span></a>。</p>
<p>在树莓派上<a href="https://www.codelast.com/?p=11069" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">安装好Ubuntu MATE</span></a> 18.04之后，我需要把外挂的显示屏去掉，从此只在command line下使用树莓派，因此要先打开Ubuntu MATE上的ssh服务。<br />
<span id="more-11120"></span><br />
Ubuntu MATE 18.04已经默认安装好了&#160;<span style="color:#0000ff;">openssh-server</span>，因此不需要用&#160;<span style="color:#b22222;">sudo apt install openssh-server</span>&#160;来装了。</p>
<p>接着就是把ssh服务设置成开机自动运行，以及启动ssh服务：</p>
<blockquote>
<div>
		sudo systemctl enable ssh</div>
<div>
		sudo systemctl start ssh</div>
</blockquote>
<div>
	然而你会发现还是无法远程ssh连接到树莓派上。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	这时你需要配置密钥：</div>
<blockquote>
<div>
		sudo dpkg-reconfigure openssh-server</div>
</blockquote>
<div>
	执行这条命令后你什么也不需要做，等着它结束，就会发现已经可以远程ssh连接到树莓派上了。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	<span style="color: rgb(255, 0, 0);">➤➤</span>&#160;版权声明&#160;<span style="color: rgb(255, 0, 0);">➤➤</span>&#160;<br />
	转载需注明出处：<u><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><em><span style="color: rgb(0, 0, 255);"><strong style="font-size: 16px;"><span style="font-family: arial, helvetica, sans-serif;">codelast.com</span></strong></span></em></a></u></div>&#8230; <a href="https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e6%a0%91%e8%8e%93%e6%b4%be%e7%9a%84-ubuntu-mate-%e7%b3%bb%e7%bb%9f%e6%89%93%e5%bc%80-ssh-%e6%9c%8d%e5%8a%a1/" class="read-more">Read More </a>]]></description>
										<content:encoded><![CDATA[<p>
要查看更多树莓派相关文章，请点击<a href="https://www.codelast.com/?p=5013" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">这里</span></a>。</p>
<p>在树莓派上<a href="https://www.codelast.com/?p=11069" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">安装好Ubuntu MATE</span></a> 18.04之后，我需要把外挂的显示屏去掉，从此只在command line下使用树莓派，因此要先打开Ubuntu MATE上的ssh服务。<br />
<span id="more-11120"></span><br />
Ubuntu MATE 18.04已经默认安装好了&nbsp;<span style="color:#0000ff;">openssh-server</span>，因此不需要用&nbsp;<span style="color:#b22222;">sudo apt install openssh-server</span>&nbsp;来装了。</p>
<p>接着就是把ssh服务设置成开机自动运行，以及启动ssh服务：</p>
<blockquote>
<div>
		sudo systemctl enable ssh</div>
<div>
		sudo systemctl start ssh</div>
</blockquote>
<div>
	然而你会发现还是无法远程ssh连接到树莓派上。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	这时你需要配置密钥：</div>
<blockquote>
<div>
		sudo dpkg-reconfigure openssh-server</div>
</blockquote>
<div>
	执行这条命令后你什么也不需要做，等着它结束，就会发现已经可以远程ssh连接到树莓派上了。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;版权声明&nbsp;<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;<br />
	转载需注明出处：<u><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><em><span style="color: rgb(0, 0, 255);"><strong style="font-size: 16px;"><span style="font-family: arial, helvetica, sans-serif;">codelast.com</span></strong></span></em></a></u>&nbsp;<br />
	感谢关注我的微信公众号（微信扫一扫）：</p>
<p style="border: 0px; font-size: 13px; margin: 0px 0px 9px; outline: 0px; padding: 0px; color: rgb(77, 77, 77);">
		<img decoding="async" alt="wechat qrcode of codelast" src="https://www.codelast.com/codelast_wechat_qr_code.jpg" style="width: 200px; height: 200px;" /></p>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e6%a0%91%e8%8e%93%e6%b4%be%e7%9a%84-ubuntu-mate-%e7%b3%bb%e7%bb%9f%e6%89%93%e5%bc%80-ssh-%e6%9c%8d%e5%8a%a1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[原创] Ubuntu MATE 扶一把，我的树莓派3B还能打</title>
		<link>https://www.codelast.com/%e5%8e%9f%e5%88%9b-ubuntu-mate-%e6%89%b6%e4%b8%80%e6%8a%8a%ef%bc%8c%e6%88%91%e7%9a%84%e6%a0%91%e8%8e%93%e6%b4%be3b%e8%bf%98%e8%83%bd%e6%89%93/</link>
					<comments>https://www.codelast.com/%e5%8e%9f%e5%88%9b-ubuntu-mate-%e6%89%b6%e4%b8%80%e6%8a%8a%ef%bc%8c%e6%88%91%e7%9a%84%e6%a0%91%e8%8e%93%e6%b4%be3b%e8%bf%98%e8%83%bd%e6%89%93/#respond</comments>
		
		<dc:creator><![CDATA[learnhard]]></dc:creator>
		<pubDate>Sat, 30 Nov 2019 16:14:33 +0000</pubDate>
				<category><![CDATA[Raspberry Pi/树莓派]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[Etcher]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Raspbian Buster]]></category>
		<category><![CDATA[SD Card Formatter]]></category>
		<category><![CDATA[Ubuntu MATE]]></category>
		<category><![CDATA[树莓派]]></category>
		<guid isPermaLink="false">https://www.codelast.com/?p=11069</guid>

					<description><![CDATA[<p>
要查看更多树莓派相关文章，请点击<a href="https://www.codelast.com/?p=5013" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">这里</span></a>。</p>
<p>廉颇老矣，尚能饭否？<br />
周末在家写代码的时候，斜眼看见躺在我桌子上正在吃灰的<span style="color:#b22222;">树莓派3B</span>（V1.2），我突然想把它的系统更新一下。<br />
时至2019年11月，外面已经是<span style="color:#0000ff;">树莓派4代</span>(2019.06发布)的天下了，而3B这种老型号，最适合拿来做遥控车之类的儿童玩具了。<br />
<span id="more-11069"></span><br />
于是我立即下载了最新的官方推荐OS：<span style="color:#0000ff;">Raspbian Buster</span>(with desktop and recommended software)，搞起。然而刷Raspbian Buster之后是一个悲伤的故事&#8212;&#8212;多次尝试也不能boot；于是我接着换了<a href="https://ubuntu-mate.org/" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">Ubuntu MATE</span></a>系统，用起来一切OK。<br />
下面就把这个过程简单地记录一下。</p>
<p><span style="color:#ff0000;"><span style="background-color:#00ff00;">▶▶</span></span>&#160;软件环境<br />
PC OS：<span style="color:#0000ff;">macOS Catalina(10.15.1)</span><br />
Raspberry Pi OS：<span style="color:#0000ff;">Ubuntu MATE 18.04.2</span><br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
<span style="color: rgb(255, 0, 0);"><span style="background-color: rgb(0, 255, 0);">▶▶</span></span>&#160;格式化TF卡<br />
使用SD协会官方的SD卡格式化工具&#160;<a href="https://www.sdcard.org/downloads/formatter/" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">SD Card Formatter</span></a>&#160;来完成这个任务：<br />
<img decoding="async" alt="sd card formatter" src="https://www.codelast.com/wp-content/uploads/2019/11/sd_card_formatter.png" style="width: 500px; height: 493px;" /><br />
这个软件实在太简单了，选&#8220;<span style="color:#0000ff;">Quick format</span>&#8221;之后点击&#8220;<span style="color:#0000ff;">format</span>&#8221;按钮执行即可，几秒就能完成格式化。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a>&#8230; <a href="https://www.codelast.com/%e5%8e%9f%e5%88%9b-ubuntu-mate-%e6%89%b6%e4%b8%80%e6%8a%8a%ef%bc%8c%e6%88%91%e7%9a%84%e6%a0%91%e8%8e%93%e6%b4%be3b%e8%bf%98%e8%83%bd%e6%89%93/" class="read-more">Read More </a></p>]]></description>
										<content:encoded><![CDATA[<p>
要查看更多树莓派相关文章，请点击<a href="https://www.codelast.com/?p=5013" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">这里</span></a>。</p>
<p>廉颇老矣，尚能饭否？<br />
周末在家写代码的时候，斜眼看见躺在我桌子上正在吃灰的<span style="color:#b22222;">树莓派3B</span>（V1.2），我突然想把它的系统更新一下。<br />
时至2019年11月，外面已经是<span style="color:#0000ff;">树莓派4代</span>(2019.06发布)的天下了，而3B这种老型号，最适合拿来做遥控车之类的儿童玩具了。<br />
<span id="more-11069"></span><br />
于是我立即下载了最新的官方推荐OS：<span style="color:#0000ff;">Raspbian Buster</span>(with desktop and recommended software)，搞起。然而刷Raspbian Buster之后是一个悲伤的故事&mdash;&mdash;多次尝试也不能boot；于是我接着换了<a href="https://ubuntu-mate.org/" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">Ubuntu MATE</span></a>系统，用起来一切OK。<br />
下面就把这个过程简单地记录一下。</p>
<p><span style="color:#ff0000;"><span style="background-color:#00ff00;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span></span>&nbsp;软件环境<br />
PC OS：<span style="color:#0000ff;">macOS Catalina(10.15.1)</span><br />
Raspberry Pi OS：<span style="color:#0000ff;">Ubuntu MATE 18.04.2</span><br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
<span style="color: rgb(255, 0, 0);"><span style="background-color: rgb(0, 255, 0);"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span></span>&nbsp;格式化TF卡<br />
使用SD协会官方的SD卡格式化工具&nbsp;<a href="https://www.sdcard.org/downloads/formatter/" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">SD Card Formatter</span></a>&nbsp;来完成这个任务：<br />
<img decoding="async" alt="sd card formatter" src="https://www.codelast.com/wp-content/uploads/2019/11/sd_card_formatter.png" style="width: 500px; height: 493px;" /><br />
这个软件实在太简单了，选&ldquo;<span style="color:#0000ff;">Quick format</span>&rdquo;之后点击&ldquo;<span style="color:#0000ff;">format</span>&rdquo;按钮执行即可，几秒就能完成格式化。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
<span style="color: rgb(255, 0, 0);"><span style="background-color: rgb(0, 255, 0);"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span></span>&nbsp;把Ubuntu MATE系统写到TF卡上<br />
先下载Ubuntu MATE的系统镜像文件(.img)，再使用开源软件<a href="https://www.balena.io/etcher/" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">Etcher</span></a>把它烧写到TF卡里。<br />
下面的图是以烧写Raspbian Buster为例。<br />
<span style="background-color:#ffff00;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span> 选择要烧写的 .img&nbsp;镜像文件：<br />
<img decoding="async" alt="etcher" src="https://www.codelast.com/wp-content/uploads/2019/11/etcher_1.png" style="width: 700px; height: 417px;" /><br />
<span style="background-color: rgb(255, 255, 0);"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span>&nbsp;点击&ldquo;Flash!&rdquo;按钮开烧写：<br />
<img decoding="async" alt="etcher" src="https://www.codelast.com/wp-content/uploads/2019/11/etcher_2.png" style="width: 700px; height: 414px;" /><br />
<span style="background-color: rgb(255, 255, 0);"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span>&nbsp;静待烧写完成：<br />
<img decoding="async" alt="etcher" src="https://www.codelast.com/wp-content/uploads/2019/11/etcher_3.png" style="width: 700px; height: 417px;" /><br />
<span style="background-color: rgb(255, 255, 0);"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span>&nbsp;烧写完成：<br />
<img decoding="async" alt="etcher" src="https://www.codelast.com/wp-content/uploads/2019/11/etcher_4.png" style="width: 700px; height: 418px;" /><br />
这样就完成了。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
如果不想安装Etcher，非要用麻烦的命令行，不妨尝试一下：<br />
<span style="background-color:#00ffff;">☞</span>&nbsp;用 <span style="color:#0000ff;">diskutil list&nbsp;</span>命令找到TF卡的设备号，假设其为&nbsp;/dev/disk2<br />
<span style="background-color: rgb(0, 255, 255);">☞</span>&nbsp;卸载TF卡：<span style="color:#0000ff;">diskutil unmountDisk /dev/disk2</span><br />
<span style="background-color: rgb(0, 255, 255);">☞</span>&nbsp;用dd命令烧写系统镜像到TF卡中：<span style="color:#0000ff;">sudo dd if=2019-09-25-rpd-x86-buster.iso of=/dev/rdisk2 bs=4M</span></p>
<div>
	注意上面的命令中：</div>
<div>
	目标是 /dev/rdisk2 而不是 /dev/disk2，是因为各种文章都说加一个&ldquo;r&rdquo;可以加快速度，所以就加了。</div>
<div>
	bs=4M 这里，在MacOS下是大写的&ldquo;M&rdquo;而不是小写的&ldquo;m&rdquo;，但在Linux下是小写的m。</div>
<p><span style="color:#b22222;">正因为操作命令行需要人很清醒才不会犯错，因此还是强烈建议使用Etcher，不要用命令行来烧写系统到TF卡！</span><br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
<span style="color: rgb(255, 0, 0);"><span style="background-color: rgb(0, 255, 0);"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span></span>&nbsp;安装Ubuntu MATE系统<br />
由于我烧写到TF卡的Raspbian Buster系统无法boot，并且重新烧写了几次都一样黑屏，因此我放弃了Raspbian，改为使用了Ubuntu MATE。Ubuntu MATE和Ubuntu Desktop的使用体验非常相似，经常使用Ubuntu Desktop的人会很习惯。<br />
把OS镜像烧写到TF卡上，并不代表OS就已经装好了，把TF卡插到树莓派上，通电之后才会真正开始安装过程。在这个过程中，你需要有外接屏幕辅助，由于树莓派是HDMI接口，如果家里有现成的台式机显示器的话，可以拿来一用；或者不太落伍的电视机也行（一般都有HDMI接口）；又或者你可以像我一样，自购树莓派的外挂LCD显示屏模块：<br />
<img decoding="async" alt="lcd" src="https://www.codelast.com/wp-content/uploads/2019/11/lcd_screen_blue.jpg" style="width: 700px; height: 525px;" /><br />
液晶背光亮起的状态：<br />
<img decoding="async" alt="lcd" src="https://www.codelast.com/wp-content/uploads/2019/11/lcd_screen_back.jpg" style="width: 700px; height: 525px;" /><br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
把树莓派接上键盘和鼠标，开始像一台普通电脑一样安装Ubuntu MATE：<br />
<img decoding="async" alt="raspberry pi install ubuntu mate" src="https://www.codelast.com/wp-content/uploads/2019/11/rpi_install_ubuntu_mate_1.jpg" style="width: 700px; height: 446px;" /><br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
<img decoding="async" alt="raspberry pi install ubuntu mate" src="https://www.codelast.com/wp-content/uploads/2019/11/rpi_install_ubuntu_mate_2.jpg" style="width: 700px; height: 441px;" /><br />
液晶屏的驱动板和树莓派用HDMI线连接：<br />
<img decoding="async" alt="raspberry pi install ubuntu mate" src="https://www.codelast.com/wp-content/uploads/2019/11/rpi_install_ubuntu_mate_3.jpg" style="width: 700px; height: 525px;" /><br />
安装Ubuntu MATE的过程除了速度慢些，其他没有任何困难。</p>
<p><span style="color: rgb(255, 0, 0);"><span style="background-color: rgb(0, 255, 0);"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/25b6.png" alt="▶" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span></span>&nbsp;禁用/启用 GUI<br />
作为一个习惯在command line下工作的人，我难道会在乎用Ubuntu MATE的时候有没有图形界面吗？！<br />
我会！<img decoding="async" alt="cheeky" height="24" src="https://www.codelast.com/wp-content/plugins/ck-and-syntaxhighlighter/ckeditor/plugins/smiley/images/6.gif" title="cheeky" width="24" /><br />
但是对树莓派那弱弱的计算资源来说，GUI还是算了吧，毕竟主要还是拿它来玩GPIO的。<br />
所以怎么在Ubuntu MATE启动的时候禁用GUI呢？这样做：</p>
<blockquote>
<p>
		sudo systemctl set-default multi-user.target</p>
</blockquote>
<p>重新启用GUI：</p>
<blockquote>
<p>
		sudo systemctl set-default graphical.target</p>
</blockquote>
<p>这样树莓派的系统就万事俱备了。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;版权声明&nbsp;<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;<br />
转载需注明出处：<u><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><em><span style="color: rgb(0, 0, 255);"><strong style="font-size: 16px;"><span style="font-family: arial, helvetica, sans-serif;">codelast.com</span></strong></span></em></a></u>&nbsp;<br />
感谢关注我的微信公众号（微信扫一扫）：</p>
<p style="border: 0px; font-size: 13px; margin: 0px 0px 9px; outline: 0px; padding: 0px; color: rgb(77, 77, 77);">
	<img decoding="async" alt="wechat qrcode of codelast" src="https://www.codelast.com/codelast_wechat_qr_code.jpg" style="width: 200px; height: 200px;" /></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codelast.com/%e5%8e%9f%e5%88%9b-ubuntu-mate-%e6%89%b6%e4%b8%80%e6%8a%8a%ef%bc%8c%e6%88%91%e7%9a%84%e6%a0%91%e8%8e%93%e6%b4%be3b%e8%bf%98%e8%83%bd%e6%89%93/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[原创] 在树莓派3上使用微软ELL嵌入式学习库(5)</title>
		<link>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e4%bd%bf%e7%94%a8%e5%be%ae%e8%bd%afell%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%935/</link>
					<comments>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e4%bd%bf%e7%94%a8%e5%be%ae%e8%bd%afell%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%935/#respond</comments>
		
		<dc:creator><![CDATA[learnhard]]></dc:creator>
		<pubDate>Sun, 20 Aug 2017 05:12:47 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Raspberry Pi/树莓派]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[Embedded Learning Library]]></category>
		<category><![CDATA[Microsoft ELL]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[机器视觉]]></category>
		<category><![CDATA[树莓派]]></category>
		<guid isPermaLink="false">https://www.codelast.com/?p=9778</guid>

					<description><![CDATA[<p>
OS： Arch Linux ARM<br />
ELL：写本文时GitHub中的最新版<br />
TensorFLow: v1.1.0</p>
<p>本文是<a href="https://www.codelast.com/?p=9609" target="_blank" rel="noopener noreferrer"><span style="background-color: rgb(255, 160, 122);">上一篇文章</span></a>的续文。<br />
微软于2017年6月底发布了一个主要用于嵌入式系统（例如，树莓派，ARM Cortex-M0等）的机器学习库<a href="https://github.com/Microsoft/ELL" target="_blank" rel="noopener noreferrer"><span style="color: rgb(0, 0, 255);"><span style="background-color: rgb(255, 160, 122);">ELL</span></span></a>（<span style="color: rgb(0, 0, 255);">Embedded Learning Library</span>，<span style="color: rgb(0, 0, 255);">嵌入式学习库</span>）。<br />
在之前的文章中，我大费周章，终于在树莓派上把ELL的demo跑起来了，但它实用吗？在本文中，我将简单地测试一下使用Darknet model的inference速度和精度。<br />
<span id="more-9778"></span><br />
<span style="background-color:#00ff00;">『1』</span>对比对象<br />
我之前在树莓派上安装过了<a href="https://github.com/samjabrahams/tensorflow-on-raspberry-pi" target="_blank" rel="noopener noreferrer"><span style="background-color: rgb(255, 160, 122);">TensorFlow on Raspberry Pi</span></a>（Inception v3 model），估计不会有哪个framework能比它更容易部署在树莓派上了&#8212;&#8212;几乎是弹指一挥间就可以完成的零成本工作。所以我就拿它来和ELL进行简单的对比。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
<span style="background-color:#00ff00;">『2』</span>测试数据<br />
我随便找了10张常见物体的图片来做测试。有人会说这么少的样本量能说明什么问题？首先我只想简单快速地测试一下ELL的效果，其次我也没有时间去做严谨的测试。<br />
下面是10张图片，序号依次从1～10：<br />
<a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="ELL test image" src="https://www.codelast.com/wp-content/uploads/2017/08/ell_test_image_1.jpg" style="text-align: center; width: 400px; height: 267px;" /></a></p>
<p><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="ELL test image" src="https://www.codelast.com/wp-content/uploads/2017/08/ell_test_image_2.jpg" style="text-align: center; width: 400px; height: 533px;" /></a></p>
<p><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="ELL test image" src="https://www.codelast.com/wp-content/uploads/2017/08/ell_test_image_3.jpg" style="text-align: center; width: 400px; height: 249px;" /></a></p>
<p><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="ELL test image" src="https://www.codelast.com/wp-content/uploads/2017/08/ell_test_image_4.jpg" style="text-align: center; width: 400px; height: 267px;" /></a></p>
<p><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="ELL test image" src="https://www.codelast.com/wp-content/uploads/2017/08/ell_test_image_5.jpg" style="text-align: center; width: 400px; height: 267px;" /></a></p>
<p><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="ELL test image" src="https://www.codelast.com/wp-content/uploads/2017/08/ell_test_image_6.jpg" style="text-align: center; width: 400px; height: 275px;" /></a></p>
<p><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="ELL test image" src="https://www.codelast.com/wp-content/uploads/2017/08/ell_test_image_7.jpg" style="text-align: center; width: 400px; height: 250px;" /></a></p>
<p><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="ELL test image" src="https://www.codelast.com/wp-content/uploads/2017/08/ell_test_image_8.jpg" style="text-align: center; width: 400px; height: 225px;" /></a></p>
<p><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="ELL test image" src="https://www.codelast.com/wp-content/uploads/2017/08/ell_test_image_9.jpg" style="text-align: center; width: 400px; height: 457px;" /></a></p>
<p><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="ELL test image" src="https://www.codelast.com/wp-content/uploads/2017/08/ell_test_image_10.jpg" style="text-align: center; width: 400px; height: 225px;" /></a></p>
<p><span style="background-color:#00ff00;">『3』</span>测试结果</p>
<ul>
<li>
		速度</li>
</ul>
<p>用图片的平均inference时间来计算速度。Tensorflow的model需要<a href="https://www.codelast.com/?p=8984" target="_blank" rel="noopener noreferrer"><span style="background-color:#ffa07a;">预热</span></a>，我们在预热之后才开始真正算inference时间。同理，ELL的model加载时间也不计算在内。</p>
<table style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 0px; table-layout: fixed; border-collapse: collapse; width: 727px; font-family: sans-serif; font-size: 14px;">
<thead style="margin: 0px; border-width: 0px 0px 2px; border-top-style: initial; border-right-style: initial; border-bottom-style: solid; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-bottom-color: rgb(20, 145, 232); border-left-color: initial; border-image: initial; padding: 0px; background-color: rgb(247, 247, 247);">
<tr style="margin: 0px; border-width: 0px 0px 1px; border-top-style: initial; border-right-style: initial; border-bottom-style: solid; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-bottom-color: rgb(20, 145, 232); border-left-color: initial; border-image: initial; padding: 0px;">
<th style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				说明</th>
<th style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				TensorFlow</th>
<th style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				ELL</th>
</tr>
</thead>
<tbody style="margin: 0px; border: 0px; padding: 0px;">
<tr style="margin: 0px; border-width: 0px 0px 1px; border-top-style: initial; border-right-style: initial; border-bottom-style: solid; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-bottom-color: rgb(20, 145, 232); border-left-color: initial; border-image: initial; padding: 0px;">
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				一张图片的平均推断时间(秒)</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				5.477</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				1.324</td>
</tr>
</tbody>
</table>
<p><span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a>&#8230; <a href="https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e4%bd%bf%e7%94%a8%e5%be%ae%e8%bd%afell%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%935/" class="read-more">Read More </a></p>]]></description>
										<content:encoded><![CDATA[<p>
OS： Arch Linux ARM<br />
ELL：写本文时GitHub中的最新版<br />
TensorFLow: v1.1.0</p>
<p>本文是<a href="https://www.codelast.com/?p=9609" target="_blank" rel="noopener noreferrer"><span style="background-color: rgb(255, 160, 122);">上一篇文章</span></a>的续文。<br />
微软于2017年6月底发布了一个主要用于嵌入式系统（例如，树莓派，ARM Cortex-M0等）的机器学习库<a href="https://github.com/Microsoft/ELL" target="_blank" rel="noopener noreferrer"><span style="color: rgb(0, 0, 255);"><span style="background-color: rgb(255, 160, 122);">ELL</span></span></a>（<span style="color: rgb(0, 0, 255);">Embedded Learning Library</span>，<span style="color: rgb(0, 0, 255);">嵌入式学习库</span>）。<br />
在之前的文章中，我大费周章，终于在树莓派上把ELL的demo跑起来了，但它实用吗？在本文中，我将简单地测试一下使用Darknet model的inference速度和精度。<br />
<span id="more-9778"></span><br />
<span style="background-color:#00ff00;">『1』</span>对比对象<br />
我之前在树莓派上安装过了<a href="https://github.com/samjabrahams/tensorflow-on-raspberry-pi" target="_blank" rel="noopener noreferrer"><span style="background-color: rgb(255, 160, 122);">TensorFlow on Raspberry Pi</span></a>（Inception v3 model），估计不会有哪个framework能比它更容易部署在树莓派上了&mdash;&mdash;几乎是弹指一挥间就可以完成的零成本工作。所以我就拿它来和ELL进行简单的对比。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
<span style="background-color:#00ff00;">『2』</span>测试数据<br />
我随便找了10张常见物体的图片来做测试。有人会说这么少的样本量能说明什么问题？首先我只想简单快速地测试一下ELL的效果，其次我也没有时间去做严谨的测试。<br />
下面是10张图片，序号依次从1～10：<br />
<a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="ELL test image" src="https://www.codelast.com/wp-content/uploads/2017/08/ell_test_image_1.jpg" style="text-align: center; width: 400px; height: 267px;" /></a></p>
<p><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="ELL test image" src="https://www.codelast.com/wp-content/uploads/2017/08/ell_test_image_2.jpg" style="text-align: center; width: 400px; height: 533px;" /></a></p>
<p><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="ELL test image" src="https://www.codelast.com/wp-content/uploads/2017/08/ell_test_image_3.jpg" style="text-align: center; width: 400px; height: 249px;" /></a></p>
<p><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="ELL test image" src="https://www.codelast.com/wp-content/uploads/2017/08/ell_test_image_4.jpg" style="text-align: center; width: 400px; height: 267px;" /></a></p>
<p><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="ELL test image" src="https://www.codelast.com/wp-content/uploads/2017/08/ell_test_image_5.jpg" style="text-align: center; width: 400px; height: 267px;" /></a></p>
<p><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="ELL test image" src="https://www.codelast.com/wp-content/uploads/2017/08/ell_test_image_6.jpg" style="text-align: center; width: 400px; height: 275px;" /></a></p>
<p><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="ELL test image" src="https://www.codelast.com/wp-content/uploads/2017/08/ell_test_image_7.jpg" style="text-align: center; width: 400px; height: 250px;" /></a></p>
<p><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="ELL test image" src="https://www.codelast.com/wp-content/uploads/2017/08/ell_test_image_8.jpg" style="text-align: center; width: 400px; height: 225px;" /></a></p>
<p><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="ELL test image" src="https://www.codelast.com/wp-content/uploads/2017/08/ell_test_image_9.jpg" style="text-align: center; width: 400px; height: 457px;" /></a></p>
<p><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="ELL test image" src="https://www.codelast.com/wp-content/uploads/2017/08/ell_test_image_10.jpg" style="text-align: center; width: 400px; height: 225px;" /></a></p>
<p><span style="background-color:#00ff00;">『3』</span>测试结果</p>
<ul>
<li>
		速度</li>
</ul>
<p>用图片的平均inference时间来计算速度。Tensorflow的model需要<a href="https://www.codelast.com/?p=8984" target="_blank" rel="noopener noreferrer"><span style="background-color:#ffa07a;">预热</span></a>，我们在预热之后才开始真正算inference时间。同理，ELL的model加载时间也不计算在内。</p>
<table style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 0px; table-layout: fixed; border-collapse: collapse; width: 727px; font-family: sans-serif; font-size: 14px;">
<thead style="margin: 0px; border-width: 0px 0px 2px; border-top-style: initial; border-right-style: initial; border-bottom-style: solid; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-bottom-color: rgb(20, 145, 232); border-left-color: initial; border-image: initial; padding: 0px; background-color: rgb(247, 247, 247);">
<tr style="margin: 0px; border-width: 0px 0px 1px; border-top-style: initial; border-right-style: initial; border-bottom-style: solid; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-bottom-color: rgb(20, 145, 232); border-left-color: initial; border-image: initial; padding: 0px;">
<th style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				说明</th>
<th style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				TensorFlow</th>
<th style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				ELL</th>
</tr>
</thead>
<tbody style="margin: 0px; border: 0px; padding: 0px;">
<tr style="margin: 0px; border-width: 0px 0px 1px; border-top-style: initial; border-right-style: initial; border-bottom-style: solid; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-bottom-color: rgb(20, 145, 232); border-left-color: initial; border-image: initial; padding: 0px;">
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				一张图片的平均推断时间(秒)</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				5.477</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				1.324</td>
</tr>
</tbody>
</table>
<p><span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
可见，ELL+Darknet model在速度上有明显优势。</p>
<ul>
<li>
		精度</li>
</ul>
<p>结果有点失望。按输出中概率最大的那个分类来算，ELL使用Darknet model在10张图片上的inference结果非常糟糕，根据人工判断，5张图片分类明显错误，其余5张算是正确&mdash;&mdash;这就有点尴尬了。而相比之下，TensorFlow使用Inception v3 model的情况则好得多，除了一张分类错误，其余9张基本上都算是得出了&ldquo;比较正确&rdquo;的结论。<br />
下面是详细的测试结果：</p>
<table style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 0px; table-layout: fixed; border-collapse: collapse; width: 727px; font-family: sans-serif; font-size: 14px;">
<thead style="margin: 0px; border-width: 0px 0px 2px; border-top-style: initial; border-right-style: initial; border-bottom-style: solid; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-bottom-color: rgb(20, 145, 232); border-left-color: initial; border-image: initial; padding: 0px; background-color: rgb(247, 247, 247);">
<tr style="margin: 0px; border-width: 0px 0px 1px; border-top-style: initial; border-right-style: initial; border-bottom-style: solid; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-bottom-color: rgb(20, 145, 232); border-left-color: initial; border-image: initial; padding: 0px;">
<th style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				图片序号</th>
<th style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				TensorFlow结果</th>
<th style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				ELL结果</th>
</tr>
</thead>
<tbody style="margin: 0px; border: 0px; padding: 0px;">
<tr style="margin: 0px; border-width: 0px 0px 1px; border-top-style: initial; border-right-style: initial; border-bottom-style: solid; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-bottom-color: rgb(20, 145, 232); border-left-color: initial; border-image: initial; padding: 0px;">
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				1</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				Granny Smith(澳大利亚的一种青绿色苹果)</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				banana(香蕉)</td>
</tr>
<tr style="margin: 0px; border-width: 0px 0px 1px; border-top-style: initial; border-right-style: initial; border-bottom-style: solid; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-bottom-color: rgb(20, 145, 232); border-left-color: initial; border-image: initial; padding: 0px;">
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				2</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				mountain bike, all-terrain bike, off-roader</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				chainlink fence(链状栅栏)</td>
</tr>
<tr style="margin: 0px; border-width: 0px 0px 1px; border-top-style: initial; border-right-style: initial; border-bottom-style: solid; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-bottom-color: rgb(20, 145, 232); border-left-color: initial; border-image: initial; padding: 0px;">
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				3</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				cellular telephone, cellular phone, cellphone, cell, mobile phone</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				iPod</td>
</tr>
<tr style="margin: 0px; border-width: 0px 0px 1px; border-top-style: initial; border-right-style: initial; border-bottom-style: solid; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-bottom-color: rgb(20, 145, 232); border-left-color: initial; border-image: initial; padding: 0px;">
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				4</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				tricycle, trike, velocipede</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				ice lolly(冰棍)</td>
</tr>
<tr style="margin: 0px; border-width: 0px 0px 1px; border-top-style: initial; border-right-style: initial; border-bottom-style: solid; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-bottom-color: rgb(20, 145, 232); border-left-color: initial; border-image: initial; padding: 0px;">
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				5</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				warplane, military plane</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				airliner(大型客机)</td>
</tr>
<tr style="margin: 0px; border-width: 0px 0px 1px; border-top-style: initial; border-right-style: initial; border-bottom-style: solid; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-bottom-color: rgb(20, 145, 232); border-left-color: initial; border-image: initial; padding: 0px;">
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				6</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				African elephant, Loxodonta africana</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				African elephant(非洲象)</td>
</tr>
<tr style="margin: 0px; border-width: 0px 0px 1px; border-top-style: initial; border-right-style: initial; border-bottom-style: solid; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-bottom-color: rgb(20, 145, 232); border-left-color: initial; border-image: initial; padding: 0px;">
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				7</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				hair slide(发夹)</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				piggy bank(零钱罐)</td>
</tr>
<tr style="margin: 0px; border-width: 0px 0px 1px; border-top-style: initial; border-right-style: initial; border-bottom-style: solid; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-bottom-color: rgb(20, 145, 232); border-left-color: initial; border-image: initial; padding: 0px;">
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				8</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				notebook, notebook computer</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				notebook(笔记本)</td>
</tr>
<tr style="margin: 0px; border-width: 0px 0px 1px; border-top-style: initial; border-right-style: initial; border-bottom-style: solid; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-bottom-color: rgb(20, 145, 232); border-left-color: initial; border-image: initial; padding: 0px;">
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				9</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				trolleybus, trolley coach, trackless trolley</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				trolleybus(无轨电车)</td>
</tr>
<tr style="margin: 0px; border-width: 0px 0px 1px; border-top-style: initial; border-right-style: initial; border-bottom-style: solid; border-left-style: initial; border-top-color: initial; border-right-color: initial; border-bottom-color: rgb(20, 145, 232); border-left-color: initial; border-image: initial; padding: 0px;">
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				10</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				tabby, tabby cat</td>
<td style="margin: 0px; border-width: 0px; border-style: initial; border-color: initial; padding: 5px 5px 5px 15px; line-height: 2; font-size: 12px; overflow: hidden; min-width: 50px;">
				tabby(虎斑猫)</td>
</tr>
</tbody>
</table>
<p><span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
即使inference速度再快，如此糟糕的准确度也是完全不能接受的。所以，我觉得，要改变这个结果，恐怕我只能用ELL CNTK VGG model再测试一遍了。正如我前面的文章所说，由于我的Ubuntu台式机性能低下，因此，我在台式机上编译ELL CNTK VGG model代码的时候，由于编译任务占用太多OS资源，被kernel自动kill掉了。不得已，我只能使用轻量级的Darknet model。所以在我当前条件下，暂时只能到这里为止了。</p>
<p><span style="background-color: rgb(0, 255, 0);">『4』</span>结论<br />
在ELL+Darknet model的速度确实比较快，但由于精度低的问题，ELL+Darknet model还需改进提高。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;版权声明&nbsp;<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;<br />
转载需注明出处：<u><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><em><span style="color: rgb(0, 0, 255);"><strong style="font-size: 16px;"><span style="font-family: arial, helvetica, sans-serif;">codelast.com</span></strong></span></em></a></u>&nbsp;<br />
感谢关注我的微信公众号（微信扫一扫）：</p>
<p style="border: 0px; font-size: 13px; margin: 0px 0px 9px; outline: 0px; padding: 0px; color: rgb(77, 77, 77);">
	<img decoding="async" alt="wechat qrcode of codelast" src="https://www.codelast.com/codelast_wechat_qr_code.jpg" style="width: 200px; height: 200px;" /></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e4%bd%bf%e7%94%a8%e5%be%ae%e8%bd%afell%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%935/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[原创] ELL（Embedded Learning Library，微软嵌入式学习库）文章合集</title>
		<link>https://www.codelast.com/%e5%8e%9f%e5%88%9b-ell%ef%bc%88embedded-learning-library%ef%bc%8c%e5%be%ae%e8%bd%af%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%93%ef%bc%89%e6%96%87%e7%ab%a0%e5%90%88%e9%9b%86/</link>
					<comments>https://www.codelast.com/%e5%8e%9f%e5%88%9b-ell%ef%bc%88embedded-learning-library%ef%bc%8c%e5%be%ae%e8%bd%af%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%93%ef%bc%89%e6%96%87%e7%ab%a0%e5%90%88%e9%9b%86/#respond</comments>
		
		<dc:creator><![CDATA[learnhard]]></dc:creator>
		<pubDate>Sat, 12 Aug 2017 15:06:47 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Raspberry Pi/树莓派]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[Embedded Learning Library]]></category>
		<category><![CDATA[Microsoft ELL]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[机器视觉]]></category>
		<category><![CDATA[树莓派]]></category>
		<guid isPermaLink="false">https://www.codelast.com/?p=9754</guid>

					<description><![CDATA[<p>微软于2017年6月底发布了一个主要用于嵌入式系统（例如，树莓派，ARM Cortex-M0等）的机器学习库<a href="https://github.com/Microsoft/ELL" rel="noopener noreferrer" target="_blank"><span style="color: rgb(0, 0, 255);"><span style="background-color: rgb(255, 160, 122);">ELL</span></span></a>（<span style="color: rgb(0, 0, 255);">Embedded Learning Library</span>，<span style="color: rgb(0, 0, 255);">嵌入式学习库</span>），旨在把部分云端的机器学习计算转移到嵌入式设备上进行。<br />
本系列文章记录了在树莓派3代上把ELL demo跑起来的过程中遇到的各种问题以及解决办法。</p>
<p><span style="background-color: rgb(0, 255, 0);">➤&#160;</span><a href="https://www.codelast.com/?p=9401" rel="noopener noreferrer" target="_blank">在树莓派3上使用微软ELL嵌入式学习库(1)</a></p>
<p><span style="background-color: rgb(0, 255, 0);">➤&#160;</span><a href="https://www.codelast.com/?p=9635" rel="noopener noreferrer" target="_blank">在树莓派3上使用微软ELL嵌入式学习库(2)</a></p>
<p><span style="background-color: rgb(0, 255, 0);">➤&#160;</span><a href="https://www.codelast.com/?p=9673" rel="noopener noreferrer" target="_blank">在树莓派3上使用微软ELL嵌入式学习库(3)</a></p>
<p><span style="background-color: rgb(0, 255, 0);">➤&#160;</span><a href="https://www.codelast.com/?p=9609" rel="noopener noreferrer" target="_blank">在树莓派3上使用微软ELL嵌入式学习库(4)</a></p>
<p><span style="background-color: rgb(0, 255, 0);">➤&#160;</span><a href="https://www.codelast.com/?p=9778" rel="noopener noreferrer" target="_blank">在树莓派3上使用微软ELL嵌入式学习库(5)</a><br />
<span id="more-9754"></span><br />
<span style="background-color: rgb(0, 255, 0);">➤&#160;</span><a href="https://www.codelast.com/?p=9710" rel="noopener noreferrer" target="_blank">在树莓派3上跑ELL的demo报错：ImportError: build/_darknetReference.so: undefined symbol: cblas_sgemm</a></p>
<p><span style="background-color: rgb(0, 255, 0);">➤&#160;</span><a href="https://www.codelast.com/?p=9594" rel="noopener noreferrer" target="_blank">执行ELL的demo程序cntkDemo.py时程序僵死的问题</a></p>
<p><span style="background-color: rgb(0, 255, 0);">➤&#160;</span><a href="https://www.codelast.com/?p=9473" rel="noopener noreferrer" target="_blank">解决ELL demo的 OpenCV Error: Unspecified error in cvShowImage 错误</a></p>
<p><span style="background-color: rgb(0, 255, 0);">➤&#160;</span><a href="https://www.codelast.com/?p=9505" rel="noopener noreferrer" target="_blank">解决编译ELL的错误：undefined reference to `cblas_xxx&#39;</a></p>
<p><span style="background-color: rgb(0, 255, 0);">➤&#160;</span><a href="https://www.codelast.com/?p=9493" rel="noopener noreferrer" target="_blank">在Ubuntu 14.04系统中为ELL安装Python 3.6&#8212;&#8212;通过miniconda</a></p>
<p><span style="background-color: rgb(0, 255, 0);">➤&#160;</span><a href="https://www.codelast.com/?p=9496" rel="noopener noreferrer" target="_blank">在Ubuntu 14.04中安装gcc 6</a></p>
<p><span style="background-color: rgb(0, 255, 0);">➤&#160;</span><a href="https://www.codelast.com/?p=9464" rel="noopener noreferrer" target="_blank">升级Ubuntu 14.04上的Open MPI到 libmpi.so.12</a>&#8230; <a href="https://www.codelast.com/%e5%8e%9f%e5%88%9b-ell%ef%bc%88embedded-learning-library%ef%bc%8c%e5%be%ae%e8%bd%af%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%93%ef%bc%89%e6%96%87%e7%ab%a0%e5%90%88%e9%9b%86/" class="read-more">Read More </a></p>]]></description>
										<content:encoded><![CDATA[<p>微软于2017年6月底发布了一个主要用于嵌入式系统（例如，树莓派，ARM Cortex-M0等）的机器学习库<a href="https://github.com/Microsoft/ELL" rel="noopener noreferrer" target="_blank"><span style="color: rgb(0, 0, 255);"><span style="background-color: rgb(255, 160, 122);">ELL</span></span></a>（<span style="color: rgb(0, 0, 255);">Embedded Learning Library</span>，<span style="color: rgb(0, 0, 255);">嵌入式学习库</span>），旨在把部分云端的机器学习计算转移到嵌入式设备上进行。<br />
本系列文章记录了在树莓派3代上把ELL demo跑起来的过程中遇到的各种问题以及解决办法。</p>
<p><span style="background-color: rgb(0, 255, 0);">➤&nbsp;</span><a href="https://www.codelast.com/?p=9401" rel="noopener noreferrer" target="_blank">在树莓派3上使用微软ELL嵌入式学习库(1)</a></p>
<p><span style="background-color: rgb(0, 255, 0);">➤&nbsp;</span><a href="https://www.codelast.com/?p=9635" rel="noopener noreferrer" target="_blank">在树莓派3上使用微软ELL嵌入式学习库(2)</a></p>
<p><span style="background-color: rgb(0, 255, 0);">➤&nbsp;</span><a href="https://www.codelast.com/?p=9673" rel="noopener noreferrer" target="_blank">在树莓派3上使用微软ELL嵌入式学习库(3)</a></p>
<p><span style="background-color: rgb(0, 255, 0);">➤&nbsp;</span><a href="https://www.codelast.com/?p=9609" rel="noopener noreferrer" target="_blank">在树莓派3上使用微软ELL嵌入式学习库(4)</a></p>
<p><span style="background-color: rgb(0, 255, 0);">➤&nbsp;</span><a href="https://www.codelast.com/?p=9778" rel="noopener noreferrer" target="_blank">在树莓派3上使用微软ELL嵌入式学习库(5)</a><br />
<span id="more-9754"></span><br />
<span style="background-color: rgb(0, 255, 0);">➤&nbsp;</span><a href="https://www.codelast.com/?p=9710" rel="noopener noreferrer" target="_blank">在树莓派3上跑ELL的demo报错：ImportError: build/_darknetReference.so: undefined symbol: cblas_sgemm</a></p>
<p><span style="background-color: rgb(0, 255, 0);">➤&nbsp;</span><a href="https://www.codelast.com/?p=9594" rel="noopener noreferrer" target="_blank">执行ELL的demo程序cntkDemo.py时程序僵死的问题</a></p>
<p><span style="background-color: rgb(0, 255, 0);">➤&nbsp;</span><a href="https://www.codelast.com/?p=9473" rel="noopener noreferrer" target="_blank">解决ELL demo的 OpenCV Error: Unspecified error in cvShowImage 错误</a></p>
<p><span style="background-color: rgb(0, 255, 0);">➤&nbsp;</span><a href="https://www.codelast.com/?p=9505" rel="noopener noreferrer" target="_blank">解决编译ELL的错误：undefined reference to `cblas_xxx&#39;</a></p>
<p><span style="background-color: rgb(0, 255, 0);">➤&nbsp;</span><a href="https://www.codelast.com/?p=9493" rel="noopener noreferrer" target="_blank">在Ubuntu 14.04系统中为ELL安装Python 3.6&mdash;&mdash;通过miniconda</a></p>
<p><span style="background-color: rgb(0, 255, 0);">➤&nbsp;</span><a href="https://www.codelast.com/?p=9496" rel="noopener noreferrer" target="_blank">在Ubuntu 14.04中安装gcc 6</a></p>
<p><span style="background-color: rgb(0, 255, 0);">➤&nbsp;</span><a href="https://www.codelast.com/?p=9464" rel="noopener noreferrer" target="_blank">升级Ubuntu 14.04上的Open MPI到 libmpi.so.12 版本</a></p>
<p><span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;版权声明&nbsp;<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;<br />
转载需注明出处：<u><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><em><span style="color: rgb(0, 0, 255);"><strong style="font-size: 16px;"><span style="font-family: arial, helvetica, sans-serif;">codelast.com</span></strong></span></em></a></u>&nbsp;<br />
感谢关注我的微信公众号（微信扫一扫）：</p>
<p style="border: 0px; font-size: 13px; margin: 0px 0px 9px; outline: 0px; padding: 0px; color: rgb(77, 77, 77);">
	<img decoding="async" alt="wechat qrcode of codelast" src="https://www.codelast.com/codelast_wechat_qr_code.jpg" style="width: 200px; height: 200px;" /></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codelast.com/%e5%8e%9f%e5%88%9b-ell%ef%bc%88embedded-learning-library%ef%bc%8c%e5%be%ae%e8%bd%af%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%93%ef%bc%89%e6%96%87%e7%ab%a0%e5%90%88%e9%9b%86/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[原创] 在树莓派3上使用微软ELL嵌入式学习库(4)</title>
		<link>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e4%bd%bf%e7%94%a8%e5%be%ae%e8%bd%afell%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%934/</link>
					<comments>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e4%bd%bf%e7%94%a8%e5%be%ae%e8%bd%afell%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%934/#respond</comments>
		
		<dc:creator><![CDATA[learnhard]]></dc:creator>
		<pubDate>Sat, 12 Aug 2017 10:46:44 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Raspberry Pi/树莓派]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[Embedded Learning Library]]></category>
		<category><![CDATA[Microsoft ELL]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[机器视觉]]></category>
		<category><![CDATA[树莓派]]></category>
		<guid isPermaLink="false">https://www.codelast.com/?p=9609</guid>

					<description><![CDATA[<p>
本文是<a href="https://www.codelast.com/?p=9673" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">上一篇文章</span></a>的续文。<br />
微软于2017年6月底发布了一个主要用于嵌入式系统（例如，树莓派，ARM Cortex-M0等）的机器学习库<a href="https://github.com/Microsoft/ELL" rel="noopener noreferrer" target="_blank"><span style="color: rgb(0, 0, 255);"><span style="background-color: rgb(255, 160, 122);">ELL</span></span></a>（<span style="color: rgb(0, 0, 255);">Embedded Learning Library</span>，<span style="color: rgb(0, 0, 255);">嵌入式学习库</span>）。<br />
为了在树莓派上跑起来ELL的demo，需要先在PC上做大量工作，前几篇文章正是记录了这个过程中遇到的种种问题。<br />
从本文开始，我们终于可以把工作转到树莓派上了&#8212;&#8212;不枉前面克服的所有困难，这一刻，我们离成功是如此之近。<br />
注：<span style="color: rgb(0, 0, 255);">本文的所有操作，都是在</span><span style="color:#ff0000;">树莓派</span><span style="color: rgb(0, 0, 255);">上运行的。</span><br />
<span id="more-9609"></span></p>
<ul>
<li>
		<span style="background-color:#dda0dd;">目标及步骤</span></li>
</ul>
<p>在上一篇文章中，我在Ubuntu PC上已经编译出了一个&#160;<span style="color:#0000ff;">compiled_darknetReference_pi3</span> 目录，并且把它拷贝到了树莓派上。现在要做的，就是用这个目录下的文件，编译出一个Python module（<span style="color:#006400;">_darknetReference.so</span>），然后就可以在树莓派上跑ELL的image classification demo了。<br />
但是，在编译这个Python module之前，我们有一些准备工作要做&#8212;&#8212;安装必需的软件。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a></p>
<ul>
<li>
		<span style="background-color:#dda0dd;">安装Python 3.4&#8212;&#8212;通过miniconda</span></li>
</ul>
<p>首先，为什么要在树莓派上安装Python 3.4呢？<br />
因为ELL提供的demo就是一个Python程序，并且它支持的Python版本是3.4。</p>
<p>在<a href="https://www.codelast.com/?p=9493" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">前面的一篇文章</span></a>中，我已经在PC Ubuntu上，通过miniconda安装过了Python 3.6，并且也解释了为什么要通过conda环境来安装Python 3.6，而不是直接在系统里装。<br />
在树莓派上，我们也是出于相同的想法，使用miniconda环境来安装Python 3.4：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &#34;Lucida Console&#34;, &#34;DejaVu Sans Mono&#34;, Monaco, &#34;Courier New&#34;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-armv7l.sh</pre>&#8230; <a href="https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e4%bd%bf%e7%94%a8%e5%be%ae%e8%bd%afell%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%934/" class="read-more">Read More </a>]]></description>
										<content:encoded><![CDATA[<p>
本文是<a href="https://www.codelast.com/?p=9673" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">上一篇文章</span></a>的续文。<br />
微软于2017年6月底发布了一个主要用于嵌入式系统（例如，树莓派，ARM Cortex-M0等）的机器学习库<a href="https://github.com/Microsoft/ELL" rel="noopener noreferrer" target="_blank"><span style="color: rgb(0, 0, 255);"><span style="background-color: rgb(255, 160, 122);">ELL</span></span></a>（<span style="color: rgb(0, 0, 255);">Embedded Learning Library</span>，<span style="color: rgb(0, 0, 255);">嵌入式学习库</span>）。<br />
为了在树莓派上跑起来ELL的demo，需要先在PC上做大量工作，前几篇文章正是记录了这个过程中遇到的种种问题。<br />
从本文开始，我们终于可以把工作转到树莓派上了&mdash;&mdash;不枉前面克服的所有困难，这一刻，我们离成功是如此之近。<br />
注：<span style="color: rgb(0, 0, 255);">本文的所有操作，都是在</span><span style="color:#ff0000;">树莓派</span><span style="color: rgb(0, 0, 255);">上运行的。</span><br />
<span id="more-9609"></span></p>
<ul>
<li>
		<span style="background-color:#dda0dd;">目标及步骤</span></li>
</ul>
<p>在上一篇文章中，我在Ubuntu PC上已经编译出了一个&nbsp;<span style="color:#0000ff;">compiled_darknetReference_pi3</span> 目录，并且把它拷贝到了树莓派上。现在要做的，就是用这个目录下的文件，编译出一个Python module（<span style="color:#006400;">_darknetReference.so</span>），然后就可以在树莓派上跑ELL的image classification demo了。<br />
但是，在编译这个Python module之前，我们有一些准备工作要做&mdash;&mdash;安装必需的软件。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a></p>
<ul>
<li>
		<span style="background-color:#dda0dd;">安装Python 3.4&mdash;&mdash;通过miniconda</span></li>
</ul>
<p>首先，为什么要在树莓派上安装Python 3.4呢？<br />
因为ELL提供的demo就是一个Python程序，并且它支持的Python版本是3.4。</p>
<p>在<a href="https://www.codelast.com/?p=9493" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">前面的一篇文章</span></a>中，我已经在PC Ubuntu上，通过miniconda安装过了Python 3.6，并且也解释了为什么要通过conda环境来安装Python 3.6，而不是直接在系统里装。<br />
在树莓派上，我们也是出于相同的想法，使用miniconda环境来安装Python 3.4：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-armv7l.sh
chmod +x Miniconda3-latest-Linux-armv7l.sh
./Miniconda3-latest-Linux-armv7l.sh</pre>
<p>非常简单就装好了。<br />
注意：和前面的文章里的做法一样，在安装即将结束的时候，我允许miniconda把PATH路径添加到我的 .bashrc 文件中。</p>
<ul>
<li>
		<span style="background-color:#dda0dd;">在conda环境里安装必需的软件包</span></li>
</ul>
<p>可以通过下面的方式，来激活conda环境：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
<span style="color: rgb(255, 176, 84);">source</span> <span style="color: rgb(255, 157, 0);">~</span>/.bashrc
conda create --name py34 python=3
<span style="color: rgb(255, 176, 84);">source</span> activate py34</pre>
<p><span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
在这个conda环境中安装 NumPy 和 OpenCV：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
<span style="color: rgb(225, 239, 255);">(</span>py34<span style="color: rgb(225, 239, 255);">)</span>[root@alarmpi <span style="color: rgb(255, 157, 0);">~</span>]# conda install numpy
<span style="color: rgb(225, 239, 255);">(</span>py34<span style="color: rgb(225, 239, 255);">)</span>[root@alarmpi <span style="color: rgb(255, 157, 0);">~</span>]# conda install -c microsoft-ell opencv</pre>
<p>这个过程基本不会有什么问题和坑。</p>
<ul>
<li>
		<span style="background-color:#dda0dd;">安装OpenBLAS</span></li>
</ul>
<p>在正式开始编译Python module之前，我们事实上还需要安装一个依赖软件：OpenBLAS，如果你是Rabpbian系统，那么通过 apt-get install 就可以安装，但不巧，我用的是Arch Linux ARM系统，没有OpenBLAS可以直接通过 pacman -S（相当于Rabpbian的 apt-get install） 安装，为此，我在Arch Linux ARM上搜了一下：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
[root@alarmpi <span style="color: rgb(255, 157, 0);">~</span>]# pacman -Ss blas
extra/blas 3.7.1-1
    Basic Linear Algebra Subprograms
extra/cblas 3.7.1-1
    C interface to BLAS
extra/liblastfm 1.0.9-2
    A Qt4 C++ library <span style="color: rgb(255, 157, 0);">for</span> <span style="color: rgb(204, 204, 204);">the</span> Last.fm webservices</pre>
<p>相关的package一共就两个：blas和cblas，如果安装了cblas，会自动把blas也装上，因为cblas依赖于blas。<br />
我到底该装哪个呢？没头绪。于是我把blas和cblas都装了，试试看后面的步骤能不能走下去吧！<br />
（但是我想提前剧透一下，这样做后面的路是走不通的，如果不想等的话可以直接看<a href="https://www.codelast.com/?p=9710" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">这个</span></a>链接里的解决方案）<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a></p>
<ul>
<li>
		<span style="background-color:#dda0dd;">安装其他依赖软件</span></li>
</ul>
<p>除了OpenBLAS，还有其他一些依赖软件要安装，它们都是在我跑demo程序挂了之后，根据错误信息发现的，在你的树莓派上，可能你已经装过了，或者在装其他的软件时把依赖也带进去了：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
pacman -S ffmpeg2.8 libpng12</pre>
<p></p>
<ul>
<li>
		<span style="background-color:#dda0dd;">编译Python module</span></li>
</ul>
<p>还记得我们从PC上拷贝过来的&nbsp;compiled_darknetReference_pi3 目录吧？现在要进到这个目录下编译了。需要特别注意的是：编译<span style="color:#ff0000;">不要</span>在miniconda环境下进行。</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
<span style="color: rgb(255, 176, 84);">cd</span> compiled_darknetReference_pi3
mkdir build
<span style="color: rgb(255, 176, 84);">cd</span> build
cmake ..
make</pre>
<p>如果一切顺利，就会在build目录下编译出一个30M大的<span style="color:#006400;">_darknetReference.so</span>文件了。<br />
但这个Python module能work吗？不试你是不知道的，于是跑ELL的demo来测试一下。</p>
<ul>
<li>
		<span style="background-color:#dda0dd;">测试Python module&mdash;&mdash;跑ELL的demo</span></li>
</ul>
<p>激活miniconda环境，把USB摄像头插到树莓派的USB接口上，然后run ELL的demo：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
<span style="color: rgb(225, 239, 255);">(</span>py34<span style="color: rgb(225, 239, 255);">)</span>[root@alarmpi <span style="color: rgb(255, 157, 0);">~</span>]# <span style="color: rgb(255, 176, 84);">cd</span> compiled_darknetReference_pi3
<span style="color: rgb(225, 239, 255);">(</span>py34<span style="color: rgb(225, 239, 255);">)</span>[root@alarmpi <span style="color: rgb(255, 157, 0);">~</span>]# python compiledDarknetDemo.py</pre>
<p>如果你的运气真的特别好，那么这个demo就能跑起来。<br />
在这里，我要特别提一下，我的树莓派OS Arch Linux ARM是没有安装图形界面的，所以在command line下跑上面的demo，会直接报错：</p>
<blockquote>
<p>
		(frame:12648): Gtk-WARNING **: cannot open display:</p>
</blockquote>
<div>
	这个程序里调用了图形界面相关的功能，所以跑不起来是正常的。和PC上的demo程序一样，我对这个程序也做了<a href="https://www.codelast.com/?p=9594" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">类似的改造</span></a>，去掉GUI相关的功能，只把predict结果打印到command line。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	然而就算是做了这样的改造，demo又能跑起来了吗？<br />
	我没那么好的运气。运行 python compiledDarknetDemo.py 之后还是报错：</div>
<blockquote>
<div>
		ImportError: build/_darknetReference.so: undefined symbol: cblas_sgemm</div>
</blockquote>
<div>
	这个问题的根本原因在于：用pacman -S cblas安装的blas不能用&mdash;&mdash;前面已经提前剧透过了。这个问题的解决办法请看<a href="https://www.codelast.com/?p=9710" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">这个</span></a>链接。</p>
<p>	至此，解决了最后这个问题之后，我终于可以在树莓派上把darknet的demo跑起来了，部署ELL到树莓派上的整个过程真的太麻烦了&mdash;&mdash;这主要是各种依赖软件的版本问题导致的。</p>
<p>	在下一篇文章中，我们会简单地看一下ELL在树莓派上的实用性如何&mdash;&mdash;速度以及精度等。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;版权声明&nbsp;<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;<br />
	转载需注明出处：<u><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><em><span style="color: rgb(0, 0, 255);"><strong style="font-size: 16px;"><span style="font-family: arial, helvetica, sans-serif;">codelast.com</span></strong></span></em></a></u>&nbsp;<br />
	感谢关注我的微信公众号（微信扫一扫）：</p>
<p style="border: 0px; font-size: 13px; margin: 0px 0px 9px; outline: 0px; padding: 0px; color: rgb(77, 77, 77);">
		<img decoding="async" alt="wechat qrcode of codelast" src="https://www.codelast.com/codelast_wechat_qr_code.jpg" style="width: 200px; height: 200px;" /></p>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e4%bd%bf%e7%94%a8%e5%be%ae%e8%bd%afell%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%934/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[原创] 在树莓派3上跑ELL的demo报错：ImportError: build/_darknetReference.so: undefined symbol: cblas_sgemm</title>
		<link>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e8%b7%91ell%e7%9a%84demo%e6%8a%a5%e9%94%99%ef%bc%9aimporterror-build_darknetreference-so-undefined-symbol-cblas_sgemm/</link>
					<comments>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e8%b7%91ell%e7%9a%84demo%e6%8a%a5%e9%94%99%ef%bc%9aimporterror-build_darknetreference-so-undefined-symbol-cblas_sgemm/#respond</comments>
		
		<dc:creator><![CDATA[learnhard]]></dc:creator>
		<pubDate>Fri, 11 Aug 2017 11:30:18 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Raspberry Pi/树莓派]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[Embedded Learning Library]]></category>
		<category><![CDATA[Microsoft ELL]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[机器视觉]]></category>
		<category><![CDATA[树莓派]]></category>
		<guid isPermaLink="false">https://www.codelast.com/?p=9710</guid>

					<description><![CDATA[<p>
OS：Arch Linux ARM<br />
gcc version：7.1.1 20170516 (GCC)</p>
<p>微软于2017年6月底发布了一个主要用于嵌入式系统（例如，树莓派，ARM Cortex-M0等）的机器学习库<a href="https://github.com/Microsoft/ELL" target="_blank" rel="noopener noreferrer"><span style="color: rgb(0, 0, 255);"><span style="background-color: rgb(255, 160, 122);">ELL</span></span></a>（<span style="color: rgb(0, 0, 255);">Embedded Learning Library</span>，<span style="color: rgb(0, 0, 255);">嵌入式学习库</span>）。<br />
本文主要介绍了在树莓派上跑ELL的demo程序时，遇到的一个&#8220;<span style="color:#b22222;">undefined symbol: cblas_sgemm</span>&#8221;问题的解决办法。<br />
<span id="more-9710"></span><br />
当我们一切准备工作已经基本完成，在树莓派上跑ELL的demo程序时，可能会报这个错：</p>
<blockquote>
<div>
		(py34)[root@alarmpi compiled_darknetReference_pi3]# python compiledDarknetDemo.py</div>
<div>
		Traceback (most recent call last):</div>
<div>
		File &#34;/root/raspberry-pi/ai/ell-related/compiled_darknetReference_pi3/darknetReference.py&#34;, line 14, in swig_import_helper</div>
<div>
		return importlib.import_module(mname)</div>
<div>
		File &#34;/root/.miniconda3/envs/py34/lib/python3.4/importlib/init.py&#34;,</div></blockquote>&#8230; <a href="https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e8%b7%91ell%e7%9a%84demo%e6%8a%a5%e9%94%99%ef%bc%9aimporterror-build_darknetreference-so-undefined-symbol-cblas_sgemm/" class="read-more">Read More </a>]]></description>
										<content:encoded><![CDATA[<p>
OS：Arch Linux ARM<br />
gcc version：7.1.1 20170516 (GCC)</p>
<p>微软于2017年6月底发布了一个主要用于嵌入式系统（例如，树莓派，ARM Cortex-M0等）的机器学习库<a href="https://github.com/Microsoft/ELL" target="_blank" rel="noopener noreferrer"><span style="color: rgb(0, 0, 255);"><span style="background-color: rgb(255, 160, 122);">ELL</span></span></a>（<span style="color: rgb(0, 0, 255);">Embedded Learning Library</span>，<span style="color: rgb(0, 0, 255);">嵌入式学习库</span>）。<br />
本文主要介绍了在树莓派上跑ELL的demo程序时，遇到的一个&ldquo;<span style="color:#b22222;">undefined symbol: cblas_sgemm</span>&rdquo;问题的解决办法。<br />
<span id="more-9710"></span><br />
当我们一切准备工作已经基本完成，在树莓派上跑ELL的demo程序时，可能会报这个错：</p>
<blockquote>
<div>
		(py34)[root@alarmpi compiled_darknetReference_pi3]# python compiledDarknetDemo.py</div>
<div>
		Traceback (most recent call last):</div>
<div>
		File &quot;/root/raspberry-pi/ai/ell-related/compiled_darknetReference_pi3/darknetReference.py&quot;, line 14, in swig_import_helper</div>
<div>
		return importlib.import_module(mname)</div>
<div>
		File &quot;/root/.miniconda3/envs/py34/lib/python3.4/importlib/init.py&quot;, line 109, in import_module</div>
<div>
		return _bootstrap._gcd_import(name[level:], package, level)</div>
<div>
		File &quot;&quot;, line 2254, in _gcd_import</div>
<div>
		File &quot;&quot;, line 2237, in _find_and_load</div>
<div>
		File &quot;&quot;, line 2226, in _find_and_load_unlocked</div>
<div>
		File &quot;&quot;, line 1191, in _load_unlocked</div>
<div>
		File &quot;&quot;, line 1161, in _load_backward_compatible</div>
<div>
		File &quot;&quot;, line 539, in _check_name_wrapper</div>
<div>
		File &quot;&quot;, line 1715, in load_module</div>
<div>
		File &quot;&quot;, line 321, in _call_with_frames_removed</div>
<div>
		<span style="color:#ff0000;">ImportError: build/_darknetReference.so: undefined symbol: cblas_sgemm</span></div>
<div>
		&nbsp;</div>
<div>
		During handling of the above exception, another exception occurred:</div>
<div>
		&nbsp;</div>
<div>
		Traceback (most recent call last):</div>
<div>
		File &quot;compiledDarknetDemo.py&quot;, line 11, in&nbsp;</div>
<div>
		import darknetReference as model</div>
<div>
		File &quot;/root/raspberry-pi/ai/ell-related/compiled_darknetReference_pi3/darknetReference.py&quot;, line 17, in&nbsp;</div>
<div>
		_darknetReference = swig_import_helper()</div>
<div>
		File &quot;/root/raspberry-pi/ai/ell-related/compiled_darknetReference_pi3/darknetReference.py&quot;, line 16, in swig_import_helper</div>
<div>
		return importlib.import_module(&#39;_darknetReference&#39;)</div>
<div>
		File &quot;/root/.miniconda3/envs/py34/lib/python3.4/importlib/init.py&quot;, line 109, in import_module</div>
<div>
		return _bootstrap._gcd_import(name[level:], package, level)</div>
<div>
		<span style="color:#ff0000;">ImportError: build/_darknetReference.so: undefined symbol: cblas_sgemm</span></div>
</blockquote>
<div>
	<br />
	问题的核心在于标红的那两句。这说明我们在树莓派上编译出来的Python module&nbsp;<span style="color:#0000ff;">_darknetReference.so</span>，在运行时找不到&nbsp;<span style="color:#b22222;">cblas_sgemm</span> 这个函数，这个函数其实是应该在blas库里定义的。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	这说明我用 pacman -S cblas blas 安装的blas库不能用。<br />
	在Arch Linux ARM系统上，检索到的和blas相关的package就只有如下几个：</p>
<pre style="font-size: 0.9333em; width: 828.906px; background: rgb(0, 34, 64); margin-top: 0px; margin-bottom: 0px; font-stretch: normal; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; color: rgb(255, 255, 255);">
[root@alarmpi <span style="color: rgb(255, 157, 0);">~</span>]# pacman -Ss blas
extra/blas 3.7.1-1
    Basic Linear Algebra Subprograms
extra/cblas 3.7.1-1
    C interface to BLAS
extra/liblastfm 1.0.9-2
    A Qt4 C++ library <span style="color: rgb(255, 157, 0);">for</span> <span style="color: rgb(204, 204, 204);">the</span> Last.fm webservices</pre>
<p>
	我试验过，<span style="color:#b22222;">无论是单独安装 blas，还是安装 cblas，或者是两个一起装，最终都不能解决问题</span>。<br />
	下面的这段message，就是在我同时安装了 blas 和 cblas 之后，编译<span style="color: rgb(0, 0, 255);">_darknetReference.so</span>过程中的 cmake 输出：</p>
<blockquote>
<div>
			[root@alarmpi build]# cmake ..</div>
<div>
			-- The C compiler identification is GNU 7.1.1</div>
<div>
			-- The CXX compiler identification is GNU 7.1.1</div>
<div>
			-- Check for working C compiler: /usr/bin/cc</div>
<div>
			-- Check for working C compiler: /usr/bin/cc -- works</div>
<div>
			-- Detecting C compiler ABI info</div>
<div>
			-- Detecting C compiler ABI info - done</div>
<div>
			-- Detecting C compile features</div>
<div>
			-- Detecting C compile features - done</div>
<div>
			-- Check for working CXX compiler: /usr/bin/c++</div>
<div>
			-- Check for working CXX compiler: /usr/bin/c++ -- works</div>
<div>
			-- Detecting CXX compiler ABI info</div>
<div>
			-- Detecting CXX compiler ABI info - done</div>
<div>
			-- Detecting CXX compile features</div>
<div>
			-- Detecting CXX compile features - done</div>
<div>
			-- Looking for pthread.h</div>
<div>
			-- Looking for pthread.h - found</div>
<div>
			-- Looking for pthread_create</div>
<div>
			-- Looking for pthread_create - not found</div>
<div>
			-- Looking for pthread_create in pthreads</div>
<div>
			-- Looking for pthread_create in pthreads - not found</div>
<div>
			-- Looking for pthread_create in pthread</div>
<div>
			-- Looking for pthread_create in pthread - found</div>
<div>
			-- Found Threads: TRUE &nbsp;</div>
<div>
			<span style="color:#0000ff;">-- Blas libraries: /usr/lib/libblas.so</span></div>
<div>
			-- Blas linker flags:&nbsp;</div>
<div>
			-- Blas include directories:&nbsp;</div>
<div>
			<span style="color:#0000ff;">-- Using BLAS include path: /usr/include</span></div>
<div>
			<span style="color:#0000ff;">-- Using BLAS library: /usr/lib/libblas.so</span></div>
<div>
			-- Using BLAS DLLs:&nbsp;</div>
<div>
			-- Found PythonInterp: /usr/bin/python3 (found suitable version &quot;3.6.2&quot;, minimum required is &quot;3.4&quot;)&nbsp;</div>
<div>
			-- Found PythonLibs: /usr/lib/libpython3.6m.so (found suitable version &quot;3.6.2&quot;, minimum required is &quot;3.4&quot;)&nbsp;</div>
<div>
			-- Configuring done</div>
<div>
			-- Generating done</div>
<div>
			-- Build files have been written to: /root/raspberry-pi/ai/ell-related/compiled_darknetReference_pi3/build</div>
</blockquote>
<div>
		注意标蓝的那几句，看似blas依赖都找到了，编译过程也可以成功地执行完，然而编译出来的<span style="color: rgb(0, 0, 255);">_darknetReference.so</span>却不能用。<br />
		奇怪的是，我检查过了安装好的 blas 库文件（.so），它确实是带了&nbsp;cblas_sgemm 函数的，所以为什么编译出来的Python module不能work，我没搞明白：</p>
<blockquote>
<div>
				nm -D /usr/lib/libblas.so | grep cblas_sgemm</div>
<div>
				(输出不为空，例如 &quot;0005f230 T cblas_sgemm&quot;)</div>
</blockquote>
<p></p>
<div>
			<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
			我还试验过只安装 blas，不安装 cblas，那么在 cmake 的输出中，下面这两行你是看不到的：</div>
<blockquote>
<div>
				-- Using BLAS include path: /usr/include</div>
<div>
				-- Using BLAS library: /usr/lib/libblas.so</div>
</blockquote>
<div>
			取而代之的是：</div>
<blockquote>
<div>
				-- Blas include directories:&nbsp;</div>
<div>
				-- BLAS library not found</div>
</blockquote>
<div>
			这说明cmake连blas的依赖都没有找到，显然是不行的。所以不用想也知道结果了：编译出来的<span style="color: rgb(0, 0, 255);">_darknetReference.so</span>也不能用。</div>
</p></div>
<p>
	经历了以上失败的过程，我一度很困惑，经过一番探索，最终找到了可行的解决方案：<span style="color:#b22222;">自己编译安装OpenBLAS，并且在编译ELL的Python module的时候对编译过程略作修改，从而让编译脚本找到正确的blas库</span>。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	二话不说我们马上开始干活：</p>
<ul>
<li>
			<span style="background-color:#dda0dd;">下载OpenBLAS源码 &amp; 编译</span></li>
</ul>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
git clone https://github.com/xianyi/OpenBLAS
<span style="color: rgb(255, 176, 84);">cd</span> OpenBLAS
make</pre>
<p>	最后一段输出信息如下：</p>
<blockquote>
<div>
			......</div>
<div>
			make[1]: Leaving directory &#39;/root/resource/OpenBLAS/exports&#39;</div>
<div>
			&nbsp;</div>
<div>
			&nbsp;OpenBLAS build complete. (BLAS CBLAS)&nbsp;</div>
<div>
			&nbsp;</div>
<div>
			&nbsp; OS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ... Linux &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>
<div>
			&nbsp; Architecture &nbsp; &nbsp; ... arm &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>
<div>
			&nbsp; BINARY &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ... 32bit &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>
<div>
			&nbsp; C compiler &nbsp; &nbsp; &nbsp; ... GCC &nbsp;(command line : gcc) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>
<div>
			&nbsp; Library Name &nbsp; &nbsp; ... libopenblas_armv7p-r0.3.0.dev.a (Multi threaded; Max num-threads is 4)</div>
<div>
			&nbsp;</div>
<div>
			To install the library, you can run &quot;make PREFIX=/path/to/your/installation install&quot;.</div>
</blockquote>
<p>	最后一句提示我们，可以通过 <span style="color:#0000ff;">make PREFIX=路径 install</span>&nbsp;的方式，把编译好的OpenBLAS安装到指定的路径下。</p>
<div>
		<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a></p>
<ul>
<li>
				<span style="background-color:#dda0dd;">安装OpenBlas到自定义的目录下</span></li>
</ul>
<p>		我不想搞乱系统目录，所以就指定了安装目录：</p>
<blockquote>
<div>
				[root@alarmpi OpenBLAS]# make PREFIX=/usr/lib/openblas install</div>
<div>
				make -j 4 -f Makefile.install install &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>
<div>
				make[1]: Entering directory &#39;/root/resource/OpenBLAS&#39; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>
<div>
				Generating openblas_config.h in /usr/lib/openblas/include &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>
<div>
				Generating f77blas.h in /usr/lib/openblas/include &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>
<div>
				Generating cblas.h in /usr/lib/openblas/include &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>
<div>
				Copying the static library to /usr/lib/openblas/lib &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>
<div>
				Copying the shared library to /usr/lib/openblas/lib &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>
<div>
				Generating openblas.pc in /usr/lib/openblas/lib/pkgconfig &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>
<div>
				Generating OpenBLASConfig.cmake in /usr/lib/openblas/lib/cmake/openblas</div>
<div>
				Generating OpenBLASConfigVersion.cmake in /usr/lib/openblas/lib/cmake/openblas</div>
<div>
				Install OK! &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>
<div>
				make[1]: Leaving directory &#39;/root/resource/OpenBLAS&#39;</div>
</blockquote>
<ul>
<li>
				<span style="background-color:#dda0dd;">重新编译_darknetReference.so的一些准备工作</span></li>
</ul>
<div>
			（1）卸载之前安装的 blas、cblas</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
pacman -R blas cblas</pre>
<p>
			（2）把OpenBlas的lib路径添加到LD_LIBRARY_PATH中</div>
<div>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
[root@alarmpi build]# <span style="color: rgb(255, 238, 128);">export</span> LD_LIBRARY_PATH=<span style="color: rgb(204, 204, 204);"><span style="color: rgb(225, 239, 255);">$</span>LD_LIBRARY_PATH</span>:/usr/lib/openblas/lib</pre>
<p>			<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
			（3）修改 <span style="color:#006400;">compiled_darknetReference_pi3/OpenBLASSetup.cmake</span> 文件<br />
			这个文件定义了如何找到 OpenBLAS 的include头文件以及.so文件，所以我把路径&nbsp;<span style="color:#0000ff;">/usr/lib/openblas/include/</span> 添加到blas的search路径中：</p>
<blockquote>
<div>
					set(BLAS_INCLUDE_SEARCH_PATHS</div>
<div>
					&nbsp; &nbsp; /System/Library/Frameworks/Accelerate.framework/Versions/Current/Frameworks/vecLib.framework/Versions/Current/Headers/</div>
<div>
					&nbsp; &nbsp; /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Accelerate.framework/Frameworks/vecLib.framework/Headers/</div>
<div>
					&nbsp; &nbsp; /usr/include</div>
<div>
					&nbsp; &nbsp; /usr/local/include</div>
<div>
					<span style="color:#0000ff;">&nbsp; &nbsp; /usr/lib/openblas/include</span></div>
<div>
					)</div>
</blockquote>
<div>
				蓝色那一句是我加的。</p>
<ul>
<li>
						<span style="background-color:#dda0dd;">重新编译_darknetReference.so</span></li>
</ul>
<p>				cmake的输出大部分与之前相同，不同的是这几句：</p>
<blockquote>
<div>
						-- Blas libraries: /usr/lib/openblas/lib/libopenblas.so</div>
<div>
						-- Blas linker flags:</div>
<div>
						-- Blas include directories:</div>
<div>
						-- Using BLAS include path: /usr/lib/openblas/include</div>
<div>
						-- Using BLAS library: /usr/lib/openblas/lib/libopenblas.so</div>
</blockquote>
<div>
					找到的blas路径都是我安装的OpenBLAS路径，可见以上修改真的生效了。</p>
<p>					最后在miniconda环境下用 <span style="color:#0000ff;">python compiledDarknetDemo.py</span> 测试，发现编译出来的Python module果然work了，问题解决！<br />
					<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
					<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;版权声明&nbsp;<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;<br />
					转载需注明出处：<u><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><em><span style="color: rgb(0, 0, 255);"><strong style="font-size: 16px;"><span style="font-family: arial, helvetica, sans-serif;">codelast.com</span></strong></span></em></a></u>&nbsp;<br />
					感谢关注我的微信公众号（微信扫一扫）：</p>
<p style="border: 0px; font-size: 13px; margin: 0px 0px 9px; outline: 0px; padding: 0px; color: rgb(77, 77, 77);">
						<img decoding="async" alt="wechat qrcode of codelast" src="https://www.codelast.com/codelast_wechat_qr_code.jpg" style="width: 200px; height: 200px;" /></p>
</p></div>
</p></div>
</p></div>
</p></div>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e8%b7%91ell%e7%9a%84demo%e6%8a%a5%e9%94%99%ef%bc%9aimporterror-build_darknetreference-so-undefined-symbol-cblas_sgemm/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[原创] 在树莓派3上使用微软ELL嵌入式学习库(3)</title>
		<link>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e4%bd%bf%e7%94%a8%e5%be%ae%e8%bd%afell%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%933/</link>
					<comments>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e4%bd%bf%e7%94%a8%e5%be%ae%e8%bd%afell%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%933/#respond</comments>
		
		<dc:creator><![CDATA[learnhard]]></dc:creator>
		<pubDate>Tue, 08 Aug 2017 16:01:01 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Raspberry Pi/树莓派]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[Embedded Learning Library]]></category>
		<category><![CDATA[Microsoft ELL]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[机器视觉]]></category>
		<category><![CDATA[树莓派]]></category>
		<guid isPermaLink="false">https://www.codelast.com/?p=9673</guid>

					<description><![CDATA[<p>
本文是<a href="https://www.codelast.com/?p=9635" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">上一篇文章</span></a>的续文。<br />
微软于2017年6月底发布了一个主要用于嵌入式系统（例如，树莓派，ARM Cortex-M0等）的机器学习库<a href="https://github.com/Microsoft/ELL" rel="noopener noreferrer" target="_blank"><span style="color: rgb(0, 0, 255);"><span style="background-color: rgb(255, 160, 122);">ELL</span></span></a>（<span style="color: rgb(0, 0, 255);">Embedded Learning Library</span>，<span style="color: rgb(0, 0, 255);">嵌入式学习库</span>）。<br />
在前几篇文章中，我在Ubuntu PC上对ELL里现成可用的model进行了测试，虽然由于我台式机太老旧的原因，运行速度相当之慢，不过它终究跑通了demo，下一步，我们需要在台式机上，把ELL的model编译到目标平台上&#8212;&#8212;在这里，目标平台指的就是树莓派3。<br />
注：<span style="color: rgb(0, 0, 255);">本文的所有操作，都是在台式机上运行的。</span><br />
<span id="more-9673"></span></p>
<ul>
<li>
		<span style="background-color:#dda0dd;">为目标平台（树莓派）编译代码</span></li>
</ul>
<p>ELL自带了一个非常酷的神经网络模型编译器，它可以为目标平台生成高度优化的代码，从而可以让model在目标平台上以很快的速度运行。<br />
在前面运行 CNTK demo的时候，细心的你一定会发现，demo运行的同时，在&#160;ELL/build/tutorials/vision/gettingStarted/ 目录下生成了一个&#160;vgg16ImageNet.map 文件（如果你使用的是Darknet，生成的就是&#160;darknetReference.map），这个文件是ELL格式的model文件，之后会用到。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
所以二话不说，直接开始编译：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &#34;Lucida Console&#34;, &#34;DejaVu Sans Mono&#34;, Monaco, &#34;Courier New&#34;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
<span style="color: rgb(255, 176, 84);">cd</span> ELL/build
make compiled_vgg16ImageNet_pi3</pre>
<p>我以为这个过程会很顺利，结果呢？我试了很多次，每一次编译经过很长时间的等待之后，都以失败告终，错误信息大概类似于下面这样：</p>
<blockquote>
<div>
		(前面还有很多，省略)</div>
<div>
		[ 85%] Built target trainers</div>
<div>
		[ 96%] Built target common</div>
<div>
		[ 98%] Built target compile</div>
<div>
		[ 98%] Generating /home/codelast/programme/pi/ELL/build/tutorials/vision/gettingStarted/compiled_vgg16ImageNet_pi3/vgg16ImageNet.ll;/home/codelast/programme/pi/ELL/build/tutorials/vision/gettingStarted/compiled_vgg16ImageNet_pi3/vgg16ImageNet.i;/home/codelast/programme/pi/ELL/build/tutorials/vision/gettingStarted/compiled_vgg16ImageNet_pi3/vgg16ImageNet.i.h</div></blockquote>&#8230; <a href="https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e4%bd%bf%e7%94%a8%e5%be%ae%e8%bd%afell%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%933/" class="read-more">Read More </a>]]></description>
										<content:encoded><![CDATA[<p>
本文是<a href="https://www.codelast.com/?p=9635" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">上一篇文章</span></a>的续文。<br />
微软于2017年6月底发布了一个主要用于嵌入式系统（例如，树莓派，ARM Cortex-M0等）的机器学习库<a href="https://github.com/Microsoft/ELL" rel="noopener noreferrer" target="_blank"><span style="color: rgb(0, 0, 255);"><span style="background-color: rgb(255, 160, 122);">ELL</span></span></a>（<span style="color: rgb(0, 0, 255);">Embedded Learning Library</span>，<span style="color: rgb(0, 0, 255);">嵌入式学习库</span>）。<br />
在前几篇文章中，我在Ubuntu PC上对ELL里现成可用的model进行了测试，虽然由于我台式机太老旧的原因，运行速度相当之慢，不过它终究跑通了demo，下一步，我们需要在台式机上，把ELL的model编译到目标平台上&mdash;&mdash;在这里，目标平台指的就是树莓派3。<br />
注：<span style="color: rgb(0, 0, 255);">本文的所有操作，都是在台式机上运行的。</span><br />
<span id="more-9673"></span></p>
<ul>
<li>
		<span style="background-color:#dda0dd;">为目标平台（树莓派）编译代码</span></li>
</ul>
<p>ELL自带了一个非常酷的神经网络模型编译器，它可以为目标平台生成高度优化的代码，从而可以让model在目标平台上以很快的速度运行。<br />
在前面运行 CNTK demo的时候，细心的你一定会发现，demo运行的同时，在&nbsp;ELL/build/tutorials/vision/gettingStarted/ 目录下生成了一个&nbsp;vgg16ImageNet.map 文件（如果你使用的是Darknet，生成的就是&nbsp;darknetReference.map），这个文件是ELL格式的model文件，之后会用到。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
所以二话不说，直接开始编译：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
<span style="color: rgb(255, 176, 84);">cd</span> ELL/build
make compiled_vgg16ImageNet_pi3</pre>
<p>我以为这个过程会很顺利，结果呢？我试了很多次，每一次编译经过很长时间的等待之后，都以失败告终，错误信息大概类似于下面这样：</p>
<blockquote>
<div>
		(前面还有很多，省略)</div>
<div>
		[ 85%] Built target trainers</div>
<div>
		[ 96%] Built target common</div>
<div>
		[ 98%] Built target compile</div>
<div>
		[ 98%] Generating /home/codelast/programme/pi/ELL/build/tutorials/vision/gettingStarted/compiled_vgg16ImageNet_pi3/vgg16ImageNet.ll;/home/codelast/programme/pi/ELL/build/tutorials/vision/gettingStarted/compiled_vgg16ImageNet_pi3/vgg16ImageNet.i;/home/codelast/programme/pi/ELL/build/tutorials/vision/gettingStarted/compiled_vgg16ImageNet_pi3/vgg16ImageNet.i.h</div>
<div>
		OpenBLAS : Your OS does not support AVX instructions. OpenBLAS is using Nehalem kernels as a fallback, which may give poorer performance.</div>
<div>
		[100%] Compiling vgg16ImageNet.ll to /home/codelast/programme/pi/ELL/build/tutorials/vision/gettingStarted/compiled_vgg16ImageNet_pi3/vgg16ImageNet.o for pi3</div>
<div>
		<span style="color:#ff0000;">Killed</span></div>
<div>
		make[3]: *** [tutorials/vision/gettingStarted/compiled_vgg16ImageNet_pi3/vgg16ImageNet.o] Error 137</div>
<div>
		make[3]: *** Deleting file `tutorials/vision/gettingStarted/compiled_vgg16ImageNet_pi3/vgg16ImageNet.o&#39;</div>
<div>
		make[2]: *** [tutorials/vision/gettingStarted/CMakeFiles/compiled_vgg16ImageNet_pi3.dir/all] Error 2</div>
<div>
		make[1]: *** [tutorials/vision/gettingStarted/CMakeFiles/compiled_vgg16ImageNet_pi3.dir/rule] Error 2</div>
<div>
		make: *** [compiled_vgg16ImageNet_pi3] Error 2</div>
</blockquote>
<div>
	注意有一个&ldquo;<span style="color:#ff0000;">Killed</span>&rdquo;，这说明由于编译的过程占用了太多资源，进程被我OS的kernel杀掉了。我说过我用的是一台性能非常差的Ubuntu PC，所以硬件条件限制，遇到这种情况在所难免。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a></p>
<ul>
<li>
			<span style="background-color:#dda0dd;">换Darknet model</span></li>
</ul>
<p>	现在摆在我面前的路有两条：1) 换一台高性能的PC来尝试编译；2) 把CNTK换成轻量级的Darknet。<br />
	ELL的开发者建议使用轻量级的Darknet，而不是用CNTK。所以我就把前面几篇文章中CNTK的测试流程，换成Darknet又走了一遍。<br />
	重新再来一遍，会发现其实非常顺手和简单了：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
<span style="color: rgb(255, 176, 84);">cd</span> build/tutorials/vision/gettingStarted
curl -O https://raw.githubusercontent.com/pjreddie/darknet/master/cfg/darknet.cfg
curl -O https://pjreddie.com/media/files/darknet.weights</pre>
<p>	这样就下载好了Darknet model，你会看到这个model的大小只有28M，而CNTK model（VGG16_ImageNet_Caffe.model）的大小有528M，不是一个数量级的。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	然后把摄像头连接到PC上，就可以跑Darknet的demo了：</p>
<blockquote>
<p>
			<span style="color:#800080;">python</span> darknetDemo.py</p>
</blockquote>
<p>	一切如此简单。BTW，这个demo跑起来确实比CNTK的速度快多了。</p>
<p>	跑Darknet的demo成功之后，我们就可以像前面说的一样，为目标平台（树莓派）编译Darknet的代码了：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
<span style="color: rgb(255, 176, 84);">cd</span> ELL/build
make compiled_darknetReference_pi3</pre>
<p>	这回进程终于没有被kernel kill掉了！看来CNTK的编译过程果然占用了太多OS资源。</p>
<p>	编译成功之后，你可以用任何方式（例如FileZilla，命令行SCP等等），把&nbsp;<span style="color:#0000ff;">ELL/build/tutorials/vision/gettingStarted/compiled_darknetReference_pi3/</span> 这个编译生成的目录，拷贝到树莓派上，我们之后需要在树莓派上，用这个目录下的东西，进一步编译出一个Python module，从而可以在树莓派上跑image classification的demo。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	仔细看一下就会发现，Darknet的这个目录只有区区的29M大小，而CNTK对应的那个目录&nbsp;compiled_vgg16ImageNet_pi3 竟然有3.4G大！这意味着，如果你决定在CNTK一条路上走到黑，那么你树莓派OS的TF卡就必须至少有16G大，否则你很可能由于OS里还要装一些必备软件，从而导致存储不下这个目录了。我之前尝试用CNTK的时候，就遇到了这样的问题，导致我要<a href="https://www.codelast.com/?p=9536" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">用GParted去resize树莓派的TF卡</span></a>。</p>
<p>	至此，我们终于完成了在PC上的所有工作，下一步，我们的工作就要转到树莓派上了，请接着看下一篇文章。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;版权声明&nbsp;<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;<br />
	转载需注明出处：<u><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><em><span style="color: rgb(0, 0, 255);"><strong style="font-size: 16px;"><span style="font-family: arial, helvetica, sans-serif;">codelast.com</span></strong></span></em></a></u>&nbsp;<br />
	感谢关注我的微信公众号（微信扫一扫）：</p>
<p style="border: 0px; font-size: 13px; margin: 0px 0px 9px; outline: 0px; padding: 0px; color: rgb(77, 77, 77);">
		<img decoding="async" alt="wechat qrcode of codelast" src="https://www.codelast.com/codelast_wechat_qr_code.jpg" style="width: 200px; height: 200px;" /></p>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e4%bd%bf%e7%94%a8%e5%be%ae%e8%bd%afell%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%933/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[原创] 在树莓派3上使用微软ELL嵌入式学习库(2)</title>
		<link>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e4%bd%bf%e7%94%a8%e5%be%ae%e8%bd%afell%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%932/</link>
					<comments>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e4%bd%bf%e7%94%a8%e5%be%ae%e8%bd%afell%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%932/#respond</comments>
		
		<dc:creator><![CDATA[learnhard]]></dc:creator>
		<pubDate>Mon, 07 Aug 2017 16:01:19 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Raspberry Pi/树莓派]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[Embedded Learning Library]]></category>
		<category><![CDATA[Microsoft ELL]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[机器视觉]]></category>
		<category><![CDATA[树莓派]]></category>
		<guid isPermaLink="false">https://www.codelast.com/?p=9635</guid>

					<description><![CDATA[<p>
本文是<a href="https://www.codelast.com/?p=9401" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">上一篇文章</span></a>的续文。<br />
微软于2017年6月底发布了一个主要用于嵌入式系统（例如，树莓派，ARM Cortex-M0等）的机器学习库<a href="https://github.com/Microsoft/ELL" rel="noopener noreferrer" target="_blank"><span style="color: rgb(0, 0, 255);"><span style="background-color: rgb(255, 160, 122);">ELL</span></span></a>（<span style="color: rgb(0, 0, 255);">Embedded Learning Library</span>，<span style="color: rgb(0, 0, 255);">嵌入式学习库</span>）。<br />
要在树莓派上使用pre-trained的模型，我们先要在PC上对其进行测试，这个测试说白了就是运行一些Python的demo程序看它们是否能正常工作。而上一篇文章，正是介绍了在Ubuntu PC上的准备工作&#8212;&#8212;如果没有那些准备工作，你连测试的基础条件都不具备。<br />
注：<span style="color: rgb(0, 0, 255);">本文的所有操作，都是在台式机上运行的。</span><br />
<span id="more-9635"></span></p>
<ul>
<li>
		<span style="background-color: rgb(221, 160, 221);">选择模型</span></li>
</ul>
<p>至此，我们终于到模型这一步了。<br />
由于训练机器学习模型的时间通常较长，所以，训练模型这个工作肯定不能放在树莓派上干。我们可以使用别人已经预先训练好的模型来节省时间，ELL文档里推荐了两个：<a href="https://github.com/Microsoft/ELL/blob/master/tutorials/vision/gettingStarted/cntk.md" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">CNTK</span></a>和<a href="https://github.com/Microsoft/ELL/blob/master/tutorials/vision/gettingStarted/darknet.md" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">Darknet</span></a>。<br />
<span style="color: rgb(255, 0, 0);">本文在PC上测试ELL时，将主要使用CNTK；而在树莓派上测试ELL时，出于运行速度等种种原因考虑，不得不使用Darknet（和Darknet相比，CNTK不够轻量级）</span>。</p>
<ul>
<li>
		<span style="background-color: rgb(221, 160, 221);">安装CNTK相关的软件</span></li>
</ul>
<p>在前面的conda环境下，安装CNTK的Python package：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &#34;Lucida Console&#34;, &#34;DejaVu Sans Mono&#34;, Monaco, &#34;Courier New&#34;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
pip install https://cntk.ai/PythonWheel/CPU-Only/cntk-2.0-cp36-cp36m-linux_x86_64.whl</pre>
<p>输出类似于：</p>
<blockquote>
<div>
		Collecting cntk==2.0 from https://cntk.ai/PythonWheel/CPU-Only/cntk-2.0-cp36-cp36m-linux_x86_64.whl</div>
<div>
		&#160; Downloading https://cntk.ai/PythonWheel/CPU-Only/cntk-2.0-cp36-cp36m-linux_x86_64.whl (109.5MB)<br />
		......</div></blockquote>&#8230; <a href="https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e4%bd%bf%e7%94%a8%e5%be%ae%e8%bd%afell%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%932/" class="read-more">Read More </a>]]></description>
										<content:encoded><![CDATA[<p>
本文是<a href="https://www.codelast.com/?p=9401" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">上一篇文章</span></a>的续文。<br />
微软于2017年6月底发布了一个主要用于嵌入式系统（例如，树莓派，ARM Cortex-M0等）的机器学习库<a href="https://github.com/Microsoft/ELL" rel="noopener noreferrer" target="_blank"><span style="color: rgb(0, 0, 255);"><span style="background-color: rgb(255, 160, 122);">ELL</span></span></a>（<span style="color: rgb(0, 0, 255);">Embedded Learning Library</span>，<span style="color: rgb(0, 0, 255);">嵌入式学习库</span>）。<br />
要在树莓派上使用pre-trained的模型，我们先要在PC上对其进行测试，这个测试说白了就是运行一些Python的demo程序看它们是否能正常工作。而上一篇文章，正是介绍了在Ubuntu PC上的准备工作&mdash;&mdash;如果没有那些准备工作，你连测试的基础条件都不具备。<br />
注：<span style="color: rgb(0, 0, 255);">本文的所有操作，都是在台式机上运行的。</span><br />
<span id="more-9635"></span></p>
<ul>
<li>
		<span style="background-color: rgb(221, 160, 221);">选择模型</span></li>
</ul>
<p>至此，我们终于到模型这一步了。<br />
由于训练机器学习模型的时间通常较长，所以，训练模型这个工作肯定不能放在树莓派上干。我们可以使用别人已经预先训练好的模型来节省时间，ELL文档里推荐了两个：<a href="https://github.com/Microsoft/ELL/blob/master/tutorials/vision/gettingStarted/cntk.md" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">CNTK</span></a>和<a href="https://github.com/Microsoft/ELL/blob/master/tutorials/vision/gettingStarted/darknet.md" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">Darknet</span></a>。<br />
<span style="color: rgb(255, 0, 0);">本文在PC上测试ELL时，将主要使用CNTK；而在树莓派上测试ELL时，出于运行速度等种种原因考虑，不得不使用Darknet（和Darknet相比，CNTK不够轻量级）</span>。</p>
<ul>
<li>
		<span style="background-color: rgb(221, 160, 221);">安装CNTK相关的软件</span></li>
</ul>
<p>在前面的conda环境下，安装CNTK的Python package：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
pip install https://cntk.ai/PythonWheel/CPU-Only/cntk-2.0-cp36-cp36m-linux_x86_64.whl</pre>
<p>输出类似于：</p>
<blockquote>
<div>
		Collecting cntk==2.0 from https://cntk.ai/PythonWheel/CPU-Only/cntk-2.0-cp36-cp36m-linux_x86_64.whl</div>
<div>
		&nbsp; Downloading https://cntk.ai/PythonWheel/CPU-Only/cntk-2.0-cp36-cp36m-linux_x86_64.whl (109.5MB)<br />
		......</div>
<div>
		Successfully installed cntk-2.0</div>
</blockquote>
<p>这一步耗时较长，耐心等待吧。<br />
然后回到ELL代码根目录，切换到gettingStarted目录并下载CNTK的ImageNet推断模型：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
<span style="color: rgb(255, 176, 84);">cd</span> build/tutorials/vision/gettingStarted
curl -O https://www.cntk.ai/Models/Caffe_Converted/VGG16_ImageNet_Caffe.model</pre>
<p></p>
<ul>
<li>
		<span style="background-color: rgb(221, 160, 221);">测试模型</span></li>
</ul>
<p>下面可以测试一下模型了：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
<span style="color: rgb(225, 239, 255);">(</span>py36<span style="color: rgb(225, 239, 255);">)</span> [codelast@ gettingStarted]$ python cntkDemo.py</pre>
<p>
如果此时报错：</p>
<div>
<blockquote>
<div>
			Traceback (most recent call last):</div>
<div>
			&nbsp; File &quot;cntkDemo.py&quot;, line 4, in &lt;module&gt;</div>
<div>
			&nbsp; &nbsp; import cv2</div>
<div>
			ImportError: /home/codelast/.miniconda3/envs/py36/lib/python3.6/site-packages/../../libopencv_dnn.so.3.2: undefined symbol: openblas_get_num_threads</div>
</blockquote>
<div>
		那么说明在miniconda环境下没有装openblas，安装方法：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
conda install openblas</pre>
<p>		然后再试。<br />
		<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
		如果遇到&ldquo;ImportError: libmpi_cxx.so.1: cannot open shared object file: No such file or directory&rdquo;这种错误，说明系统里没有安装Open MPI开发包，理论上应该用下面的命令安装：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
sudo apt-get install libopenmpi-dev</pre>
<div>
			但是，当你安装好之后，重新运行<span style="color: rgb(0, 0, 255);">&nbsp;cntkDemo.py</span>，不出意外的话又会遇到&ldquo;ImportError: libmpi.so.12: cannot open shared object file: No such file or directory&rdquo;的错误，这其实是Open MPI版本太低导致的，解决方案请看<a href="https://www.codelast.com/?p=9464" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">这个链接</span></a>。</p>
<p>			解决了那么那么多的问题，现在总可以了吧？再次执行&nbsp;<span style="color: rgb(0, 0, 255);">cntkDemo.py</span>，等待它运行了一段时间之后，一开始看上去还挺正常的，执行到后面又出错了：</p>
<blockquote>
<div>
					...Finished constructing ELL layers.</div>
<div>
					OpenCV Error: Unspecified error (The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script) in cvShowImage, file /feedstock_root/build_artefacts/opencv_1490907195496/work/opencv-3.2.0/modules/highgui/src/window.cpp, line 583</div>
<div>
					Traceback (most recent call last):</div>
<div>
					&nbsp; File &quot;cntkDemo.py&quot;, line 68, in &lt;module&gt;</div>
<div>
					&nbsp; &nbsp; main()</div>
<div>
					&nbsp; File &quot;cntkDemo.py&quot;, line 61, in main</div>
<div>
					&nbsp; &nbsp; cv2.imshow(&#39;frame&#39;, frameToShow)</div>
<div>
					......</div>
</blockquote>
<div>
				这个问题，就是我上一篇文章里所说的，按ELL官方文档里的方法去安装OpenCV会导致的问题，在各种坑中，这是最坑爹的一个了。这个问题的解决办法请看<a href="https://www.codelast.com/?p=9473" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">这个链接</span></a>。<br />
				<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a></div>
</p></div>
<div>
			此时再重新执行&nbsp;<span style="color: rgb(0, 0, 255);">cntkDemo.py</span>，确实不报错了，但是，执行到弹出GUI窗口显示摄像头拍摄的视频流的代码的时候，程序进入假死状态，不能执行后续逻辑。此时我的内心是崩溃的。本着一定要把它搞定的决心，我又做了一些尝试，使得我能够跑起来这个demo，具体请看<a href="https://www.codelast.com/?p=9594" rel="noopener noreferrer" target="_blank"><span style="background-color: rgb(255, 160, 122);">这篇文章</span></a>。</p>
<p>			当在PC上成功地跑起来了CNTK的demo之后，我们就可以认为这个model是work的，然后就要准备把它弄到树莓派上去跑了。<br />
			<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
			<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;版权声明&nbsp;<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;<br />
			转载需注明出处：<u><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><em><span style="color: rgb(0, 0, 255);"><strong style="font-size: 16px;"><span style="font-family: arial, helvetica, sans-serif;">codelast.com</span></strong></span></em></a></u>&nbsp;<br />
			感谢关注我的微信公众号（微信扫一扫）：</p>
<p style="border: 0px; font-size: 13px; margin: 0px 0px 9px; outline: 0px; padding: 0px; color: rgb(77, 77, 77);">
				<img decoding="async" alt="wechat qrcode of codelast" src="https://www.codelast.com/codelast_wechat_qr_code.jpg" style="width: 200px; height: 200px;" /></p>
</p></div>
</p></div>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e4%bd%bf%e7%94%a8%e5%be%ae%e8%bd%afell%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%932/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[原创] 在树莓派3上使用微软ELL嵌入式学习库(1)</title>
		<link>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e4%bd%bf%e7%94%a8%e5%be%ae%e8%bd%afell%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%931/</link>
					<comments>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e4%bd%bf%e7%94%a8%e5%be%ae%e8%bd%afell%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%931/#comments</comments>
		
		<dc:creator><![CDATA[learnhard]]></dc:creator>
		<pubDate>Sun, 06 Aug 2017 16:00:06 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Raspberry Pi/树莓派]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[Embedded Learning Library]]></category>
		<category><![CDATA[Microsoft ELL]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[机器视觉]]></category>
		<category><![CDATA[树莓派]]></category>
		<guid isPermaLink="false">https://www.codelast.com/?p=9401</guid>

					<description><![CDATA[<p>
微软于2017年6月底发布了一个主要用于嵌入式系统（例如，树莓派，ARM Cortex-M0等）的机器学习库<a href="https://github.com/Microsoft/ELL" rel="noopener noreferrer" target="_blank"><span style="color:#0000ff;"><span style="background-color:#ffa07a;">ELL</span></span></a>（<span style="color:#0000ff;">Embedded Learning Library</span>，<span style="color:#0000ff;">嵌入式学习库</span>）。由于嵌入式设备的计算能力较弱，因此在这些设备上执行一些机器学习的任务&#8212;&#8212;例如实时图像分类&#8212;&#8212;通常速度很慢，所以在这种应用场景下，一般的策略是把请求发送到计算能力强大的云端服务器上去执行，嵌入式设备只作为和用户交互的终端，并不执行关键的计算任务。而微软发布的这个ELL，目标在于把云端的计算任务转移到嵌入式设备上，从而可以使得设备无需联网也能执行这些任务。这个目标看起来很诱人，但它要求ELL的计算速度很快、很节省资源，否则耗时将是不可接受的。<br />
<span id="more-9401"></span><br />
我在树莓派3上试验过用Tensorflow来进行图像分类（看这里：<a href="https://www.codelast.com/?p=8941" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">链接1</span></a>，<a href="https://www.codelast.com/?p=8984" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">链接2</span></a>，<a href="https://www.codelast.com/?p=8995" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">链接3</span></a>），结果是：速度很慢，推断一张图片的类别要花4秒多时间。当然，这个时间肯定可以通过优化缩短，并且它使用的是Inception-v3模型，而不是MobileNet之类专门为移动设备设计的模型。<br />
微软的ELL就是为了解决这个痛点而生。<br />
在ELL发布不久后，我很好奇它在树莓派3代上的表现会如何，是不是真的很&#8220;快&#8221;，能达到非常实用的程度呢？<br />
于是，我开始了ELL试用之路。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
首先需要说明的一点是，在开始写文本时，由于ELL刚发布不久，其开发团队对这个项目处于频繁的更新中，所以很多文档、代码可能修改得很快、前后版本相差很大，所以，如果本文陈述的某些内容与你看到的最新版ELL有所不同，请不要觉得奇怪。<br />
此外，在整个测试过程中我遇到了很多坑，ELL文档上有很多没有写清楚、还有些错误的地方，直到后面某一步操作时触发了这些问题才暴露出来，我又不得不回头去看之前的哪一步需要fix问题，所以，如果你也想试一下ELL，那么先看到本文的话，可能会让你少走些弯路。</p>
<p><span style="background-color:#00ff00;">『1』</span>拿ELL来做什么？<br />
首先，我们要拿ELL来实现一个什么功能？<br />
微软官方给出的一个指导文档是《Getting Started with Computer Vision》，也就是说我们要在嵌入式系统上用ELL实现一个机器视觉的应用，以微软官方提供的下面这个图片为例：<br />
<img decoding="async" alt="" src="https://www.codelast.com/wp-content/uploads/ckfinder/images/coffeemug.jpg" style="width: 643px; height: 513px;" /><br />
即：用树莓派的摄像头拍摄一个物体，运行在树莓派上的ELL程序可以识别出它&#8220;是什么&#8221;。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
<span style="background-color:#00ff00;">『2』</span>软硬件准备</p>
<ul>
<li>
		树莓派3代（OS：Arch Linux ARM）</li>
<li>
		用于树莓派的USB摄像头（也可以用和树莓派配套的那个专用摄像头，但价格比较贵，我手上没有）</li>
<li>
		台式机（OS：Ubuntu 14.04 LTS）</li>
</ul>
<p><span style="background-color:#00ff00;">『3』</span>台式机上的准备工作<br />
不要以为我们让模型跑在树莓派上，就没有台式机什么事了。实际上，我们需要先在台式机上做非常多的工作，然后才能在树莓派上跑ELL。<br />
所以，本文讲的就是我们要在台式机上做的那些繁琐工作，<span style="color:#0000ff;">切记：本文的所有操作，都是在台式机上运行的，跟树莓派没有关系</span>。</p>
<ul>
<li>
		<span style="background-color:#dda0dd;">下载ELL的代码</span></li>
</ul>
<p>首先我们从Github上检出ELL的代码，尽管在网页上看ELL的文档更方便一些，但是后面我们是需要用到这份代码的，所以这一步肯定要做：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &#34;Lucida Console&#34;, &#34;DejaVu Sans Mono&#34;, Monaco, &#34;Courier New&#34;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
git clone https://github.com/Microsoft/ELL.git</pre>&#8230; <a href="https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e4%bd%bf%e7%94%a8%e5%be%ae%e8%bd%afell%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%931/" class="read-more">Read More </a>]]></description>
										<content:encoded><![CDATA[<p>
微软于2017年6月底发布了一个主要用于嵌入式系统（例如，树莓派，ARM Cortex-M0等）的机器学习库<a href="https://github.com/Microsoft/ELL" rel="noopener noreferrer" target="_blank"><span style="color:#0000ff;"><span style="background-color:#ffa07a;">ELL</span></span></a>（<span style="color:#0000ff;">Embedded Learning Library</span>，<span style="color:#0000ff;">嵌入式学习库</span>）。由于嵌入式设备的计算能力较弱，因此在这些设备上执行一些机器学习的任务&mdash;&mdash;例如实时图像分类&mdash;&mdash;通常速度很慢，所以在这种应用场景下，一般的策略是把请求发送到计算能力强大的云端服务器上去执行，嵌入式设备只作为和用户交互的终端，并不执行关键的计算任务。而微软发布的这个ELL，目标在于把云端的计算任务转移到嵌入式设备上，从而可以使得设备无需联网也能执行这些任务。这个目标看起来很诱人，但它要求ELL的计算速度很快、很节省资源，否则耗时将是不可接受的。<br />
<span id="more-9401"></span><br />
我在树莓派3上试验过用Tensorflow来进行图像分类（看这里：<a href="https://www.codelast.com/?p=8941" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">链接1</span></a>，<a href="https://www.codelast.com/?p=8984" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">链接2</span></a>，<a href="https://www.codelast.com/?p=8995" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">链接3</span></a>），结果是：速度很慢，推断一张图片的类别要花4秒多时间。当然，这个时间肯定可以通过优化缩短，并且它使用的是Inception-v3模型，而不是MobileNet之类专门为移动设备设计的模型。<br />
微软的ELL就是为了解决这个痛点而生。<br />
在ELL发布不久后，我很好奇它在树莓派3代上的表现会如何，是不是真的很&ldquo;快&rdquo;，能达到非常实用的程度呢？<br />
于是，我开始了ELL试用之路。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
首先需要说明的一点是，在开始写文本时，由于ELL刚发布不久，其开发团队对这个项目处于频繁的更新中，所以很多文档、代码可能修改得很快、前后版本相差很大，所以，如果本文陈述的某些内容与你看到的最新版ELL有所不同，请不要觉得奇怪。<br />
此外，在整个测试过程中我遇到了很多坑，ELL文档上有很多没有写清楚、还有些错误的地方，直到后面某一步操作时触发了这些问题才暴露出来，我又不得不回头去看之前的哪一步需要fix问题，所以，如果你也想试一下ELL，那么先看到本文的话，可能会让你少走些弯路。</p>
<p><span style="background-color:#00ff00;">『1』</span>拿ELL来做什么？<br />
首先，我们要拿ELL来实现一个什么功能？<br />
微软官方给出的一个指导文档是《Getting Started with Computer Vision》，也就是说我们要在嵌入式系统上用ELL实现一个机器视觉的应用，以微软官方提供的下面这个图片为例：<br />
<img decoding="async" alt="" src="https://www.codelast.com/wp-content/uploads/ckfinder/images/coffeemug.jpg" style="width: 643px; height: 513px;" /><br />
即：用树莓派的摄像头拍摄一个物体，运行在树莓派上的ELL程序可以识别出它&ldquo;是什么&rdquo;。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
<span style="background-color:#00ff00;">『2』</span>软硬件准备</p>
<ul>
<li>
		树莓派3代（OS：Arch Linux ARM）</li>
<li>
		用于树莓派的USB摄像头（也可以用和树莓派配套的那个专用摄像头，但价格比较贵，我手上没有）</li>
<li>
		台式机（OS：Ubuntu 14.04 LTS）</li>
</ul>
<p><span style="background-color:#00ff00;">『3』</span>台式机上的准备工作<br />
不要以为我们让模型跑在树莓派上，就没有台式机什么事了。实际上，我们需要先在台式机上做非常多的工作，然后才能在树莓派上跑ELL。<br />
所以，本文讲的就是我们要在台式机上做的那些繁琐工作，<span style="color:#0000ff;">切记：本文的所有操作，都是在台式机上运行的，跟树莓派没有关系</span>。</p>
<ul>
<li>
		<span style="background-color:#dda0dd;">下载ELL的代码</span></li>
</ul>
<p>首先我们从Github上检出ELL的代码，尽管在网页上看ELL的文档更方便一些，但是后面我们是需要用到这份代码的，所以这一步肯定要做：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
git clone https://github.com/Microsoft/ELL.git</pre>
<p></p>
<ul>
<li>
		<span style="background-color:#dda0dd;">安装基础软件依赖</span></li>
</ul>
<p>
	除此之外，编译ELL还对系统有很多软件依赖，例如cmake，llvm之类，具体请看<a href="http://github.com/Microsoft/ELL/blob/master/INSTALL-Ubuntu.md" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">这个</span></a>ELL的文档。整个安装、解决问题的过程真的相当麻烦，要有充分的心理准备。<br />
	<span style="color:#b22222;">第1点注意</span>：cmake要装3.3版的，ELL的文档里没有写，如果你用 apt-get install cmake 安装，那么装上去的版本可能不符合要求，最后一定会出问题，导致整个流程走不下去。<br />
	所以我是这样装的cmake：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
apt-cache show cmake3
sudo apt-get install cmake3</pre>
<p>
	<span style="color: rgb(178, 34, 34);">第2点注意</span>：ELL对gcc版本有要求，但ELL的doc里没写。具体请看<a href="https://www.codelast.com/?p=9496" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">这篇文章</span></a>。</p>
<p><span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a></p>
<ul>
<li>
		<span style="background-color:#dda0dd;">安装Python 3.6&mdash;&mdash;通过miniconda</span></li>
</ul>
<p>为什么要用Python 3.6？因为ELL的demo程序就是Python 3.6的。<br />
根据ELL文档的建议，我们不应该&ldquo;直接&rdquo;在系统里安装Python 3.6，而是通过conda环境来安装，具体请看<a href="https://www.codelast.com/?p=9493" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">这篇文章</span></a>。</p>
<ul>
<li>
		<span style="background-color:#dda0dd;">在miniconda环境下安装必需的软件包</span></li>
</ul>
<p>安装好 miniconda 之后，需要安装 curl，numpy 和 <span style="color:#0000ff;">opencv</span>（如果没有安装过的话）：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
conda install curl
conda install numpy</pre>
<p>你一定感觉很奇怪：上面的命令并没有安装OpenCV啊？！没错，这是因为，按照ELL文档的做法（<span style="color:#008000;">conda install -c conda-forge opencv</span>）安装上的OpenCV是有问题的&mdash;&mdash;至少在我的Ubuntu上不能用。如果你着急的话，可以直接看<a href="https://www.codelast.com/?p=9473" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">这篇文章</span></a>的解决方案；如果你不急的话，可以暂时按ELL文档的说明去安装OpenCV，然后跟着本系列文章的节奏，一点点地发现问题、解决问题（没错，后面的章节还有讲到这个问题）。</p>
<ul>
<li>
		<span style="background-color:#dda0dd;">安装SWIG</span></li>
</ul>
<p>下一步，你需要安装用于生成language binding（语言绑定）的SWIG软件（和conda环境无关）。比如我们要用Python来调用ELL，那么就需要Python binding，诸如此类。<br />
在Ubuntu 14.04上，用 apt-get install swig3.0 安装上的SWIG是3.0.2版本，满足不了ELL要求的&ldquo;version 3.0.12 or later&rdquo;，所以，我们只能自己下载、编译SWIG了：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
wget https://nchc.dl.sourceforge.net/project/swig/swig/swig-3.0.12/swig-3.0.12.tar.gz
tar zxf swig-3.0.12.tar.gz
<span style="color: rgb(255, 176, 84);">cd</span> swig-3.0.12
./configure --without-pcre <span style="color: rgb(255, 157, 0);">&amp;&amp;</span> make <span style="color: rgb(255, 157, 0);">&amp;&amp;</span> sudo make install</pre>
<p></p>
<ul>
<li>
		<span style="background-color:#dda0dd;">编译ELL</span></li>
</ul>
<p>下面可以开始编译ELL了。这里的编译过程<span style="color:#ff0000;">不要</span>在conda环境下执行。<br />
回到之前检出的ELL代码的根目录下，执行下面的命令：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
mkdir build
<span style="color: rgb(255, 176, 84);">cd</span> build
cmake ..
make</pre>
<p>如果不出错，那表明你运气是真的好。<br />
我记得我是编译到61％的时候挂掉的，错误信息如下：</p>
<blockquote>
<div>
		[ 0%] Built target documentation</div>
<div>
		......</div>
<div>
		[ 61%] Linking CXX executable common_test</div>
<div>
		../math/libmath.a(BlasWrapper.cpp.o): In function ell::math::Blas::Copy(int, float const*, int, float*, int)&#39;: BlasWrapper.cpp:(.text+0x31): undefined reference tocblas_scopy&#39;</div>
<div>
		......</div>
<div>
		../math/libmath.a(BlasWrapper.cpp.o): In function ell::math::Blas::Gemm(CBLAS_ORDER, CBLAS_TRANSPOSE, CBLAS_TRANSPOSE, int, int, int, double, double const*, int, double const*, int, double, double*, int)&#39;: BlasWrapper.cpp:(.text+0x471): undefined reference tocblas_dgemm&#39;</div>
<div>
		collect2: error: ld returned 1 exit status</div>
<div>
		make[2]: *** [libraries/common/common_test] Error 1</div>
<div>
		make[1]: *** [libraries/common/CMakeFiles/common_test.dir/all] Error 2</div>
<div>
		make: *** [all] Error 2</div>
</blockquote>
<div>
	这个问题的解决方法请看<a href="https://www.codelast.com/?p=9505" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">这篇文章</span></a>。<br />
	&nbsp;</div>
<ul>
<li>
		<span style="background-color:#dda0dd;">生成Python binding</span></li>
</ul>
<p>接下来，需要配置miniconda里的Python环境：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
<span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">#</span> Create the environment</span>
conda create -n py36 anaconda python=3
<span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">#</span> Activate the environment</span>
<span style="color: rgb(255, 176, 84);">source</span> activate py36
<span style="color: rgb(0, 136, 255); font-style: italic;"><span style="color: rgb(225, 239, 255);">#</span> ELL requires gcc 5 and above for C++14. Upgrade anaconda&#39;s environment to support it.</span>
conda install libgcc</pre>
<p>注意：第二句命令是 <span style="color:#0000ff;">source activate py36</span>，而ELL的文档里是 activate py36，一执行就报错，会提示你要在前面加source。<br />
这一步耗时较长，等它完成之后，我们就可以生成Python binding了。在同一个命令行窗口里（刚激活了py36环境），到之前检出的ELL代码的根目录下，执行下面的命令（其实前3行命令前面已经执行过了，如果没有删除build目录的话可以不再重新执行）：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
mkdir build
<span style="color: rgb(255, 176, 84);">cd</span> build
cmake ..
make _ELL_python </pre>
<p>如果不出错的话，Python binding就生成成功了，但是你如果在 cmake 那一步遇到这样的错误：</p>
<blockquote>
<div>
		CMake Error at CMakeLists.txt:5 (cmake_minimum_required):</div>
<div>
		&nbsp; CMake 3.3 or higher is required. &nbsp;You are running version 2.8.12.2</div>
<div>
		-- Configuring incomplete, errors occurred!</div>
</blockquote>
<p>这就是本文前面的章节说过的cmake版本过低导致的，前面已经说过了如何安装高版本的cmake，这里不再复述。<br />
然后再重新执行cmake及其后步骤，OK的话，就可以测试一下Python binding是否能正常工作。回到ELL代码的根目录，然后：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(0, 34, 64); color: rgb(255, 255, 255);">
<span style="color: rgb(225, 239, 255);">(</span>py36<span style="color: rgb(225, 239, 255);">)</span> [codelast@ ELL]$ <span style="color: rgb(255, 176, 84);">cd</span> build/interfaces/python/test
<span style="color: rgb(225, 239, 255);">(</span>py36<span style="color: rgb(225, 239, 255);">)</span> [codelast@ <span style="color: rgb(255, 176, 84);">test</span>]$ python <span style="color: rgb(255, 176, 84);">test</span>.py</pre>
<p>注意：一定要cd到 build/interface/python/test/ 这个目录下跑test！之所以强调这一点，是因为在ELL代码根目录下，还有一个一模一样的&nbsp;interfaces/python/test/ 目录，如果你弄错了，到这个目录下跑test，会发现console没有任何输出信息，很迷惑人。<br />
正常的test输出信息类似于下面这样：</p>
<blockquote>
<div>
		OpenBLAS : Your OS does not support AVX instructions. OpenBLAS is using Nehalem kernels as a fallback, which may give poorer performance.</div>
<div>
		Testing HingeLoss.Evaluate(2, 1) ... Passed</div>
<div>
		Testing HingeLoss.Evaluate(-2, -1) ... Passed</div>
<div>
		<span style="color:#b22222;">（中间还有很多，此处省略）</span></div>
<div>
		Testing SquaredLoss.GetDerivative(4, 2) ... Passed</div>
<div>
		Testing SquaredLoss.GetDerivative(2, 4) ... Passed</div>
<div>
		functions_test passed</div>
<div>
		[1]<span style="white-space:pre"> </span>One subgraph</div>
<div>
		&nbsp; &nbsp; Subgraph Vertices Edges Cycles</div>
<div>
		&nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; &nbsp;6 &nbsp; &nbsp; &nbsp; &nbsp;8 &nbsp; &nbsp; 3 &nbsp; &nbsp;</div>
<div>
		[2]<span style="white-space:pre"> </span>One subgraph</div>
<div>
		&nbsp; &nbsp; Subgraph Vertices Edges Cycles</div>
<div>
		&nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; &nbsp;6 &nbsp; &nbsp; &nbsp; &nbsp;6 &nbsp; &nbsp; 1 &nbsp; &nbsp;</div>
<div>
		<span style="color:#b22222;">（中间还有很多，此处省略）</span><br />
		[tree_3]<span style="white-space: pre;"> </span>One subgraph</div>
<div>
		&nbsp; &nbsp; Subgraph Vertices Edges Cycles</div>
<div>
		&nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; &nbsp;101 &nbsp; &nbsp; &nbsp;126 &nbsp; 26 &nbsp;&nbsp;</div>
<div>
		model_test passed</div>
<div>
		Model 1 size: 6</div>
<div>
		Model 2 size: 6</div>
<div>
		Model 3 size: 8</div>
<div>
		Tree 0 size: 17</div>
<div>
		Tree 1 size: 45</div>
<div>
		Tree 2 size: 73</div>
<div>
		Tree 3 size: 101</div>
<div>
		Loading file ../../../examples/data/model_1.model</div>
<div>
		Loading file ../../../examples/data/model_2.model</div>
<div>
		common_test passed</div>
<div>
		trainers_test.test -- TBD</div>
<div>
		trainers_test passed</div>
<div>
		predictors_test.test -- TBD</div>
<div>
		predictors_test passed</div>
<div>
		nodes_test.test -- TBD</div>
<div>
		nodes_test passed</div>
<div>
		linear_test.test -- TBD</div>
<div>
		linear_test passed</div>
<div>
		evaluators_test.test -- TBD</div>
<div>
		evaluators_test passed</div>
<div>
		Testing ModelBuilder ... Passed</div>
<div>
		modelbuilder_test passed</div>
</blockquote>
<p>这说明Python binding可以正常工作了。<br />
下面，我们将进入和模型相关的测试，请看<a href="https://www.codelast.com/?p=9635" rel="noopener noreferrer" target="_blank"><span style="background-color:#ffa07a;">后一篇文章</span></a>。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;版权声明&nbsp;<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;<br />
转载需注明出处：<u><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><em><span style="color: rgb(0, 0, 255);"><strong style="font-size: 16px;"><span style="font-family: arial, helvetica, sans-serif;">codelast.com</span></strong></span></em></a></u>&nbsp;<br />
感谢关注我的微信公众号（微信扫一扫）：</p>
<p style="border: 0px; font-size: 13px; margin: 0px 0px 9px; outline: 0px; padding: 0px; color: rgb(77, 77, 77);">
	<img decoding="async" alt="wechat qrcode of codelast" src="https://www.codelast.com/codelast_wechat_qr_code.jpg" style="width: 200px; height: 200px;" /></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8%e6%a0%91%e8%8e%93%e6%b4%be3%e4%b8%8a%e4%bd%bf%e7%94%a8%e5%be%ae%e8%bd%afell%e5%b5%8c%e5%85%a5%e5%bc%8f%e5%ad%a6%e4%b9%a0%e5%ba%931/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>[原创] 在Ubuntu上使用GParted来调整树莓派TF卡的分区大小</title>
		<link>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8ubuntu%e4%b8%8a%e4%bd%bf%e7%94%a8gparted%e6%9d%a5%e8%b0%83%e6%95%b4%e6%a0%91%e8%8e%93%e6%b4%betf%e5%8d%a1%e7%9a%84%e5%88%86%e5%8c%ba%e5%a4%a7%e5%b0%8f/</link>
					<comments>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8ubuntu%e4%b8%8a%e4%bd%bf%e7%94%a8gparted%e6%9d%a5%e8%b0%83%e6%95%b4%e6%a0%91%e8%8e%93%e6%b4%betf%e5%8d%a1%e7%9a%84%e5%88%86%e5%8c%ba%e5%a4%a7%e5%b0%8f/#respond</comments>
		
		<dc:creator><![CDATA[learnhard]]></dc:creator>
		<pubDate>Tue, 18 Jul 2017 17:59:48 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Raspberry Pi/树莓派]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[GParted]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[resize partition]]></category>
		<category><![CDATA[TF卡]]></category>
		<category><![CDATA[树莓派]]></category>
		<category><![CDATA[调整分区大小]]></category>
		<guid isPermaLink="false">https://www.codelast.com/?p=9536</guid>

					<description><![CDATA[<p>
OS：Ubuntu 14.04 LTS</p>
<p>树莓派的操作系统存储在一张TF卡中，如果我们要备份它，只需要简单地在Ubuntu上使用如下命令即可：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &#34;Lucida Console&#34;, &#34;DejaVu Sans Mono&#34;, Monaco, &#34;Courier New&#34;, monospace; background: rgb(255, 255, 255);">
sudo dd <span style="color: rgb(255, 120, 0);">if</span>=/dev/sdb of=<span style="color: rgb(255, 120, 0);">~</span>/raspberry_pi_os_backup</pre>
<p>其中，/dev/sdb 是我的TF卡的设备名称。这样我们就可以把TF卡备份到 raspberry_pi_os_backup 这个文件中了。<br />
<span id="more-9536"></span><br />
如果我们想把该备份恢复到一张新的TF卡上，也只需要在Ubuntu上使用如下命令：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &#34;Lucida Console&#34;, &#34;DejaVu Sans Mono&#34;, Monaco, &#34;Courier New&#34;, monospace; background: rgb(255, 255, 255);">
sudo dd <span style="color: rgb(255, 120, 0);">if</span>=<span style="color: rgb(255, 120, 0);">~</span>/raspberry_pi_os_backup of=/dev/sdb</pre>
<p>其中，/dev/sdb 是我的新TF卡的设备名称。这样就可以把备份的OS写到新TF卡中了。</p>
<p>谁都知道重新安装OS并配置好各种软件的工作量实在是太大了，而上面的方法为我们提供了一个快速复制现有的树莓派系统的途径，因此特别实用。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
但是，这样做有一个问题：假设原系统是装在8G的TF卡上，而新TF卡是16G的，那么，你用上面的方法操作完之后，再把新卡插回同一个树莓派上，再用 <span style="color:#0000ff;">df -h</span> 来查看TF卡容量信息，可能会发现它竟然只有 8G！剩下的8G不知怎么就被&#8220;吃掉&#8221;了。</p>
<p>要解决这个&#8220;诡异&#8221;的问题，其实有一个非常方便的办法，就是在Ubuntu上使用GParted软件来调整TF卡的分区容量。二话不说下面我们就直接开始。<br />
<span style="background-color:#00ff00;">『1』</span>安装GParted软件<br />
一行命令搞定：</p>
<blockquote>
<p>
		sudo apt-get install gparted</p>
</blockquote>
<p><span style="background-color:#00ff00;">『2』</span>准备工作<br />
把新TF卡用USB适配器插到台式机上，打开GParted软件，在软件右上方的下拉框中选择你的TF卡对应的存储设备（我这里是 /dev/sdb），你会看到类似于下面这样的界面：<br />
<a href="https://www.codelast.com" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="gparted resize tf card" src="https://www.codelast.com/wp-content/uploads/2017/07/gparted_resize_tf_card_1.png" style="text-align: center; width: 775px; height: 528px;" /></a><br />
在这里，我的新TF卡是16G的，而备份的树莓派OS是从8G的TF卡备份出来的，所以正如前面所说，有8G被&#8220;吃掉&#8221;了，从GParted里可以清晰地看到那被&#8220;吃掉&#8221;的8G空间，显示成了&#8220;未分配&#8221;空间。我们正是要把这部分空间，和它之前的 /dev/sdb2 分区合并成一个分区，或者说把 /dev/sdb2 分区扩大成整个TF卡的可用空间那么大。<br />
在进一步操作GParted之前，我们需要确保TF卡上的几个分区是&#8220;卸载&#8221;的状态，因为挂载的状态是无法进行后续操作的。<br />
卸载方法是：在除了&#8220;未分配&#8221;之外的其他所有分区上，鼠标右键点击，在弹出的菜单里，只要能看到&#8220;<span style="color:#0000ff;">卸载</span>&#8221;菜单项的，都点击&#8220;卸载&#8221;，这样就OK了。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a>&#8230; <a href="https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8ubuntu%e4%b8%8a%e4%bd%bf%e7%94%a8gparted%e6%9d%a5%e8%b0%83%e6%95%b4%e6%a0%91%e8%8e%93%e6%b4%betf%e5%8d%a1%e7%9a%84%e5%88%86%e5%8c%ba%e5%a4%a7%e5%b0%8f/" class="read-more">Read More </a></p>]]></description>
										<content:encoded><![CDATA[<p>
OS：Ubuntu 14.04 LTS</p>
<p>树莓派的操作系统存储在一张TF卡中，如果我们要备份它，只需要简单地在Ubuntu上使用如下命令即可：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(255, 255, 255);">
sudo dd <span style="color: rgb(255, 120, 0);">if</span>=/dev/sdb of=<span style="color: rgb(255, 120, 0);">~</span>/raspberry_pi_os_backup</pre>
<p>其中，/dev/sdb 是我的TF卡的设备名称。这样我们就可以把TF卡备份到 raspberry_pi_os_backup 这个文件中了。<br />
<span id="more-9536"></span><br />
如果我们想把该备份恢复到一张新的TF卡上，也只需要在Ubuntu上使用如下命令：</p>
<pre style="margin-top: 0px; margin-bottom: 0px; font-stretch: normal; font-size: 0.9333em; line-height: 1.5em; font-family: Consolas, &quot;Lucida Console&quot;, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Courier New&quot;, monospace; background: rgb(255, 255, 255);">
sudo dd <span style="color: rgb(255, 120, 0);">if</span>=<span style="color: rgb(255, 120, 0);">~</span>/raspberry_pi_os_backup of=/dev/sdb</pre>
<p>其中，/dev/sdb 是我的新TF卡的设备名称。这样就可以把备份的OS写到新TF卡中了。</p>
<p>谁都知道重新安装OS并配置好各种软件的工作量实在是太大了，而上面的方法为我们提供了一个快速复制现有的树莓派系统的途径，因此特别实用。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
但是，这样做有一个问题：假设原系统是装在8G的TF卡上，而新TF卡是16G的，那么，你用上面的方法操作完之后，再把新卡插回同一个树莓派上，再用 <span style="color:#0000ff;">df -h</span> 来查看TF卡容量信息，可能会发现它竟然只有 8G！剩下的8G不知怎么就被&ldquo;吃掉&rdquo;了。</p>
<p>要解决这个&ldquo;诡异&rdquo;的问题，其实有一个非常方便的办法，就是在Ubuntu上使用GParted软件来调整TF卡的分区容量。二话不说下面我们就直接开始。<br />
<span style="background-color:#00ff00;">『1』</span>安装GParted软件<br />
一行命令搞定：</p>
<blockquote>
<p>
		sudo apt-get install gparted</p>
</blockquote>
<p><span style="background-color:#00ff00;">『2』</span>准备工作<br />
把新TF卡用USB适配器插到台式机上，打开GParted软件，在软件右上方的下拉框中选择你的TF卡对应的存储设备（我这里是 /dev/sdb），你会看到类似于下面这样的界面：<br />
<a href="https://www.codelast.com" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="gparted resize tf card" src="https://www.codelast.com/wp-content/uploads/2017/07/gparted_resize_tf_card_1.png" style="text-align: center; width: 775px; height: 528px;" /></a><br />
在这里，我的新TF卡是16G的，而备份的树莓派OS是从8G的TF卡备份出来的，所以正如前面所说，有8G被&ldquo;吃掉&rdquo;了，从GParted里可以清晰地看到那被&ldquo;吃掉&rdquo;的8G空间，显示成了&ldquo;未分配&rdquo;空间。我们正是要把这部分空间，和它之前的 /dev/sdb2 分区合并成一个分区，或者说把 /dev/sdb2 分区扩大成整个TF卡的可用空间那么大。<br />
在进一步操作GParted之前，我们需要确保TF卡上的几个分区是&ldquo;卸载&rdquo;的状态，因为挂载的状态是无法进行后续操作的。<br />
卸载方法是：在除了&ldquo;未分配&rdquo;之外的其他所有分区上，鼠标右键点击，在弹出的菜单里，只要能看到&ldquo;<span style="color:#0000ff;">卸载</span>&rdquo;菜单项的，都点击&ldquo;卸载&rdquo;，这样就OK了。<br />
<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a></p>
<div>
	<span style="background-color:#00ff00;">『3』</span>调整分区大小<br />
	右键点击 /dev/sdb2 那个分区，在弹出菜单中选择&ldquo;<span style="color:#0000ff;">更改大小/移动</span>&rdquo;，会弹出下面的对话框：<br />
	<a href="https://www.codelast.com" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="gparted resize tf card" src="https://www.codelast.com/wp-content/uploads/2017/07/gparted_resize_tf_card_2.png" style="text-align: center; width: 554px; height: 315px;" /></a></p>
<p>	通过拉动上方白框里的右箭头，我们就可以调整这个分区的大小了。我把它拉到了最右边，使得这个分区使用全部的可用空间：<br />
	<a href="https://www.codelast.com" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="gparted resize tf card" src="https://www.codelast.com/wp-content/uploads/2017/07/gparted_resize_tf_card_3.png" style="text-align: center; width: 554px; height: 315px;" /></a><br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	之后点击右下方的&ldquo;调整大小/移动&rdquo;按钮，就会回到GParted主界面了：<br />
	<a href="https://www.codelast.com" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="gparted resize tf card" src="https://www.codelast.com/wp-content/uploads/2017/07/gparted_resize_tf_card_4.png" style="text-align: center; width: 775px; height: 528px;" /></a><br />
	此时可以看到，/dev/sdb2 的大小已经扩展到了全部可用空间，之前的&ldquo;未分配&rdquo;空间消失了。<br />
	但是请注意：<span style="color:#ff0000;">此时分区调整实际上还没有生效</span>，左下角的&ldquo;<span style="color:#0000ff;">1个操作待进行</span>&rdquo;提示了这一点。我们需要点击GParted主界面上方的<span style="color:#0000ff;">勾号</span>（<span style="color:#008000;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span>）来执行操作。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	<span style="background-color:#00ff00;">『4』</span>完成操作<br />
	开始执行操作后，一般来说，你应该会看到下面这样的界面：<br />
	<a href="https://www.codelast.com" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="gparted resize tf card" src="https://www.codelast.com/wp-content/uploads/2017/07/gparted_resize_tf_card_5.png" style="text-align: center; width: 700px; height: 317px;" /></a><br />
	但是，GParted也有可能立即报错，告诉你无法执行，此时，如果你右键点击 /dev/sdb2 并在菜单中选择&ldquo;信息&rdquo;，在弹出的对话框中，可能会看到类似于下面这样的信息：</div>
<blockquote>
<div>
		e2label: No such file or directory while trying to open /dev/sdb2</div>
<div>
		Couldn&#39;t find valid filesystem superblock.</div>
<div>
		&nbsp;</div>
<div>
		tune2fs 1.42.9 (4-Feb-2014)</div>
<div>
		&nbsp;</div>
<div>
		tune2fs: No such file or directory while trying to open /dev/sdb2</div>
<div>
		Couldn&#39;t find valid filesystem superblock.</div>
<div>
		&nbsp;</div>
<div>
		Couldn&#39;t find valid filesystem superblock.</div>
<div>
		&nbsp;</div>
<div>
		dumpe2fs 1.42.9 (4-Feb-2014)</div>
<div>
		dumpe2fs: No such file or directory while trying to open /dev/sdb2</div>
<div>
		&nbsp;</div>
<div>
		无法读取此文件系统上的内容!</div>
<div>
		因为此操作可能不可用。</div>
<div>
		原因可能是缺少某个软件包。</div>
<div>
		支持 ext4 文件系统需要下列软件包：e2fsprogs v1.41+。</div>
</blockquote>
<div>
	出现这个错误的话，可能是由于操作不对造成的，并非像错误提示里写的那样缺少软件包（我的Ubuntu上就一个都不缺）&mdash;&mdash;貌似刚把备份的OS恢复到TF卡上，需要重新插拔一次，才能用GParted调整分区大小。<br />
	你可以尝试着把TF卡从Ubuntu台式机上拔掉，然后再重新插入USB接口上，重做一遍试试。<br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	如果一切可以正常进行下去，应该是类似于下面这样的界面：<br />
	<a href="https://www.codelast.com" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="gparted resize tf card" src="https://www.codelast.com/wp-content/uploads/2017/07/gparted_resize_tf_card_6.png" style="text-align: center; width: 724px; height: 567px;" /></a></p>
<p>	全部完成之后：<br />
	<a href="https://www.codelast.com" target="_blank" rel="noopener noreferrer"><img decoding="async" alt="gparted resize tf card" src="https://www.codelast.com/wp-content/uploads/2017/07/gparted_resize_tf_card_7.png" style="text-align: center; width: 724px; height: 567px;" /></a></p>
<p>	此时，再回到GParted主界面，就会看到 /dev/sdb2 已经被成功地调整成了14G大小，并且左下方的&ldquo;<span style="color:#0000ff;">0个操作待进行</span>&rdquo;表明我们真的执行完了调整分区大小的操作：<br />
	<img decoding="async" alt="gparted resize tf card" src="https://www.codelast.com/wp-content/uploads/2017/07/gparted_resize_tf_card_8.png" style="text-align: center; width: 775px; height: 528px;" /><br />
	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" target="_blank" rel="noopener noreferrer"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	<span style="background-color:#00ff00;">『5』</span>在树莓派上验证新卡分区调整结果<br />
	把调整过分区的新TF卡插到树莓派上，成功进入系统！<br />
	再看一下剩余空间：</p>
<blockquote>
<div>
			[root@alarmpi ~]# df -h ./</div>
<div>
			Filesystem &nbsp; &nbsp; &nbsp;Size &nbsp;Used Avail Use% Mounted on</div>
<div>
			/dev/root &nbsp; &nbsp; &nbsp; &nbsp;14G &nbsp;5.1G &nbsp;8.0G &nbsp;39% /</div>
</blockquote>
<p>	搞定。</p>
<p>	<span style="color: rgb(255, 255, 255);">文章来源：</span><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><span style="color: rgb(255, 255, 255);">https://www.codelast.com/</span></a><br />
	<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;版权声明&nbsp;<span style="color: rgb(255, 0, 0);">➤➤</span>&nbsp;<br />
	转载需注明出处：<u><a href="https://www.codelast.com/" rel="noopener noreferrer" target="_blank"><em><span style="color: rgb(0, 0, 255);"><strong style="font-size: 16px;"><span style="font-family: arial, helvetica, sans-serif;">codelast.com</span></strong></span></em></a></u>&nbsp;<br />
	感谢关注我的微信公众号（微信扫一扫）：</p>
<p style="border: 0px; font-size: 13px; margin: 0px 0px 9px; outline: 0px; padding: 0px; color: rgb(77, 77, 77);">
		<img decoding="async" alt="wechat qrcode of codelast" src="https://www.codelast.com/codelast_wechat_qr_code.jpg" style="width: 200px; height: 200px;" /></p>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codelast.com/%e5%8e%9f%e5%88%9b-%e5%9c%a8ubuntu%e4%b8%8a%e4%bd%bf%e7%94%a8gparted%e6%9d%a5%e8%b0%83%e6%95%b4%e6%a0%91%e8%8e%93%e6%b4%betf%e5%8d%a1%e7%9a%84%e5%88%86%e5%8c%ba%e5%a4%a7%e5%b0%8f/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
