除 CPU 外,英特尔® Edison 开发板还包含一个内部微控制器单元 (MCU)。 在本文中,我将从两个方面解释使用内部 MCU 的优势
<strong>实时</strong>
<strong>能效</strong>
MCU 在多款应用中都至关重要。 例如,基于英特尔® Edison 开发板的 Linux* 在与传感器交互时无法提供实时响应。 MCU 支持自 2.1 版开始能够在英特尔® Edison® 开发板固件软件版本上使用。
我们来了解一下英特尔® Edison 计算模块中使用的系统芯片 (SoC):
<center><img src="http://intel.eetrend.com/files/2016-03/wen_zhang_/100001245-1123-cpu.pn…; alt=""></center>
英特尔® Edison 计算模块中的系统芯片包括两个 CPU:
1、双核英特尔® 凌动™ 处理器(500 MHz) 标有主机 CPU。
2、采用 Minute 英特尔® 架构的 MCU (100 MHz)。 标有 MCU。
Minute 英特尔架构内核是一款节能架构,基于英特尔® 486,并额外采用指令,能够与英特尔® 奔腾® 处理器兼容。 MCU 包含丰富的 I/O 子系统(GPIO、I2C、高速 UART、DMA)和 SRAM,并能够访问英特尔® Edison 计算模块上的所有 GPIO 针脚。 适用于代码和数据的总 SRAM 为 192 kb。 MCU 使用 WindRiver 的实时 Viper* 操作系统运行。
MCU 程序支持在 Viper 内核上使用,并可控制连接到 MCU 上的外围设备,而不受英特尔凌动处理器的影响。 例如,它能够控制 GPIO 针脚,与采用 I2C 和 UART 协议的传感器通信,并与英特尔凌动处理器通信。
<strong>为何在英特尔® Edison 上使用 MCU</strong>
使用 MCU 得益于两个原因:提供实时微秒级延迟和高能效。
英特尔凌动处理器和 Yocto Project* 标准 Linux* 分发版不支持即购即用的实时应用。
Linux 应用可能会被调度器先占用,从而造成不可接受且不可预测的延迟,因而不可能提供实时响应。
MCU 运行一个应用和实时操作系统,这使得其有可能提供实时响应。
对于许多通信协议需要严格遵守短时间来执行的传感器,均需要实时响应。
如要在没有内部 MCU 的情况下将这些传感器连接到英特尔® Edison 开发板,您将需要使用外部 MCU。 在这种情况下,所有的传感器通信都在外部 MCU 上进行。 例如,面向英特尔® Edison 开发板的 SparkFun Block* – Arduino 扩展板可提供外部 MCU 功能。 但是,使用外部 MCU 将会增加 BOM 成本并提高解决方案的复杂性。
MCU 可以提高某些应用的能效,在这些应用中, CPU 设置为睡眠状态且 MCU 正在等待外部事件(如当传感器的值上升到超过阈值时)。
当外部事件出现时,MCU 将会唤醒 CPU。 《使用 MCU SDK 和 API: 代码示例》一文中介绍了实施示例。
为了解释如何使用内部 MCU,我们将把超声波测距传感器 HC-SR04 连接到英特尔® Edison 开发板中。 我们将把测量到的距离输出到 Grove* LCD RGB 背光符号显示器中。
<strong>超声波测距传感器 HC-SR04</strong>
<center><img src="http://intel.eetrend.com/files/2016-03/wen_zhang_/100001245-1124-hc-sr0…; alt=""></center>
该传感器有四个针脚:
1、Vcc: 5V
2、Trig: 触发传感器信号。 MCU 向传感器发送 10 us 脉冲。 传感器启动一次测量。
3、回波: 从传感器到 MCU 的回波信号。 脉冲宽度随测量距离成比例增减。
4、Gnd: 接地
图片展示了示波器屏幕上的协议:
<center><img src="http://intel.eetrend.com/files/2016-03/wen_zhang_/100001245-1126-screen…; alt=""></center>
1 个通道: Trig
2 个通道: 回波
MCU 向 Trig 针脚发送一个脉冲。 之后,传感器将相应回波针脚上的脉冲。
脉冲持续时间随测量距离成比例增减。
使用公式来计算距离(位于传感器数据表上):
距离 (cm) = 回波脉冲持续时间 (us) / 58
传感器可以测量从 2 厘米到 400 厘米的距离(如数据表所示)。
不借助微秒级实时延迟,以预估的精确度不可能测量这么短的脉冲的持续时间。 例如,调度器可能预先占用测量流程,测量结果可能无效。
<strong>将 HC-SR04 传感器连接到英特尔® Edison 开发板上的 MCU</strong>
组件:
1、英特尔® Edison 计算模块
2、面向 Arduino 的英特尔® Edison 开发板
3、Grove Basic Shield
4、Grove LCD RGB 背光灯
5、超声波测距传感器 HC-SR04
6、电路试验板
首先,安装适用于 Arduino 的英特尔® Edison 计算模块和英特尔® Edison 开发板。 接下来,将 Grove Base Shield 扩展板连接至适用于 Arduino 的英特尔® Edison 开发板。 将 Grove LCD RGB 背光灯连接至 Grove Basic Shield 上的任意 I2C 端口。
将超声波测距传感器 HC-SR04 连接至 Grove Basic Shield,如下:
1、Vcc 至 +5V
2、Trig 至针脚 3
3、Echo 至针脚 4
4、Gnd 至 Gnd
针脚 3 和 4 随机选择。 针对此目的,您可以使用任意 GPIO 针脚。
<strong>更新英特尔® Edison 开发板固件</strong>
MCU 支持自 2.1 版开始已经添加到英特尔® Edison 开发板固件软件版本中。 如果您有较旧的固件,则需要更新它。
如要获取当前的固件版本,请使用以下命令:
# configure_edison –version
该示例基于固件版本 146。
《刷新英特尔® Edison》一文中提供了固件更新说明。 我更喜欢使用该篇文章中介绍的备用刷新方法。
请在刷新前仔细阅读说明。
<strong>使用以太网通过 USB 连接英特尔® Edison 开发板</strong>
<center><img src="http://intel.eetrend.com/files/2016-03/wen_zhang_/100001245-1127-usb.jp…; alt=""></center>
您必须对网络连接进行配置,使其能够与 MCU SDK 中的英特尔® Edison 开发板相连。
如要做到这一点,请将 USB 连接线与顶部的微型 USB 端口相连,并将微型开关设置到底部位置(朝向微型 USB 端口)。
如要在 Linux 上配置网络:
# ifconfig usb0 192.168.2.2
英特尔® Edison 开发板 IP 地址: 192.168.2.15
如欲了解更多信息,请参阅使用 USB 以太网连接到您的英特尔® Edison 开发板。
<strong>MCU SDK</strong>
开发人员需要 MCU SDK 创建适用于内部 MCU 的应用。 MCU SDK 是一个基于 Eclipse* 的跨平台 IDE。 《安装 MCU SDK》一文中解释了安装流程。
MCU SDK 提供了创建、编译、上传至开发板的功能,并能够调试面向 MCU 的应用。
<strong>与 MCU 通信</strong>
有多个接口可与 Linux 层面的 MCU 进行通信:
/dev/ttymcu0 — 通过该接口与 MCU 传输数据。 可以使用 Linux 的标准读写文件操作进行操作。 MCU 程序可以使用 host_send 和 host_receive 函数。
/dev/ttymcu1 — 使用 debug_print 函数从 MCU 发送调试消息的 接口。
/sys/devices/platform/intel_mcu/log_level — 设置调试消息日志级别的接口(fatal、error、warning、info、debug)。
<strong>使用 MCU 上面向 Arduino 的英特尔® Edison 开发板针脚</strong>
MCU 集成在英特尔® Edison 计算模块中,可以控制 70 针脚 Hirose 模块连接器上的 GPIO。
如要将 MCU 与面向 Arduino 的英特尔® Edison 开发板结合使用,您需要查找英特尔® Edison 计算模块 GPIO 针脚和面向 Arduino 的英特尔® Edison 开发板针脚之间的映射。 配置多路复用器和电平位移器,将英特尔® Edison 计算模块的 GPIO 路由至面向 Arduino 的英特尔® Edison 开发板针脚。
当从 Linux 层面处理时,这些例程将在 MRAA 库中处理。 在使用 MCU 处理时,开发人员需要使用脚本来处理它们(init_DIG.sh、init_i2c8.sh、init_mcu_PWM.sh、set_DIG.sh、read_DIG.sh、init_UART1.sh)
<strong>面向 Linux 的脚本</strong>
下方的 Python* 脚本 show_distance.py 可从内部 MCU 中获取数据,并在 Grove LCD 显示器上显示它们。 我们将使用 UPM 库中的 Jhd1313m1 模块,与 Grove LCD 显示器交互。
show_distance.py (注:所有文件/脚本在本文末尾均存为 .zip 文件)
01 import time
02 import pyupm_i2clcd
03
04 RET_ERROR = -1
05
06 if __name__ == '__main__':
07 lcd = pyupm_i2clcd.Jhd1313m1(6, 0x3E, 0x62)
08 with open('/dev/ttymcu0', 'w+t') as f:
09 while True:
10 f.write('get_distance\n') # Send command to MCU
11 f.flush()
12 line = f.readline() # Read response from MCU, -1 = ERROR
13 value = int(line.strip('\n\r\t '))
14 lcd.clear()
15 if value == RET_ERROR:
16 lcd.setColor(255, 0, 0) # RED
17 lcd.write('ERROR')
18 else:
19 lcd.setColor(0, 255, 0) # GREEN
20 lcd.write('%d cm' % (value,))
21 time.sleep(1)
<strong>MCU 程序</strong>
MCU 程序等待主机 CPU 的 get_distance 命令。 如果程序收到 get_distance 命令,它将会测量距离并向主机 CPU 发送结果(距离以厘米计,如果出现错误则显示 -1)。
针对面向 Arduino 的英特尔® Edison 开发板设置针脚:
# ./init_DIG.sh -o 3 -d output
# ./init_DIG.sh -o 4 -d input
MCU 可与英特尔® Edison 计算模块上的 GPIO 针脚配合使用,该模块在面向 Arduino 的英特尔® Edison 开发板上标有不同的数字。 如欲了解更多信息,请参阅使用 MCU 让 LED 闪烁。
mcu.c (注:所有文件/脚本在本文末尾均存为 .zip 文件)
01 #include "mcu_api.h"
02 #include "mcu_errno.h"
03
04 // Arduino Extension PIN = 3
05 #define TRIG 12
06 // Arduino Extension PIN = 4
07 #define ECHO 129
08
09 // From HC-SR04 datasheet
10 #define MIN_DISTANCE 2
11 #define MAX_DISTANCE 400
12
13 #define MAX_WAIT 10000
14 #define RET_ERROR -1
15
16 int get_distance() {
17 // Send Trig signal to HC-SR04
18 gpio_write(TRIG, 1);
19 mcu_delay(10);
20 gpio_write(TRIG, 0);
21
22 // Read Echo signal from HC-SR04
23 int i;
24
25 i = 0;
26 while ((gpio_read(ECHO) == 0) && (i < MAX_WAIT)) {
27 mcu_delay(1);
28 i++;
29 }
30
31 unsigned long t0 = time_us();
32 if (gpio_read(ECHO) == 0 || i == MAX_WAIT) {
33 return RET_ERROR;
34 }
35
36 i = 0;
37 while ((gpio_read(ECHO) == 1) && (i < MAX_WAIT)) {
38 mcu_delay(1);
39 i++;
40 }
41
42 unsigned long t1 = time_us();
43 if (gpio_read(ECHO) == 1 || i == MAX_WAIT) {
44 return RET_ERROR;
45 }
46
47 unsigned long distance = (t1 - t0) / 58;
48 if (MIN_DISTANCE < distance && distance < MAX_DISTANCE) {
49 return distance;
50 } else {
51 return RET_ERROR;
52 }
53 }
54
55 #define MAX_BUF 255
56 unsigned char buf[MAX_BUF];
57
58 void mcu_main() {
59 // Setup Trig as OUTPUT
60 gpio_setup(TRIG, 1);
61 // Initially set Trig to LOW
62 gpio_write(TRIG, 0);
63 // Setup Echo as INPUT
64 gpio_setup(ECHO, 0);
65
66 while (1) {
67 unsigned int len;
68 len = host_receive(buf, MAX_BUF);
69
70 if ((len >= 12) && (strncmp(buf, "get_distance", 12) == 0)) {
71 unsigned int distance;
72 distance = get_distance();
73 len = mcu_snprintf(buf, MAX_BUF, "%d\n", distance);
74 host_send(buf, len);
75 }
76 }
77 }
<strong>添加我们的脚本以自动启动</strong>
如要启动我们的脚本,请先创建一个 shell 脚本:
File /home/root/startup.sh:
startup.sh (注:所有文件/脚本在本文末尾均存为 .zip 文件)
01 #!/bin/bash
02
03 cd /home/root
04
05 # configure PIN3 as GPIO OUPUT (TRIG signal)
06 ./init_DIG.sh -o 3 -d output
07
08 # configure PIN4 as GPIO INPUT (ECHO signal)
09 ./init_DIG.sh -o 4 -d input
10
11 python show_distance.py
将脚本标记为可执行文件:
# chmod a+x /home/root/startup.sh
# chmod a+x /home/root/init_DIG.sh
Yocto Project Linux 使用 systemd,因此我们需要创建 “service” 文件,添加脚本以自动启动。
创建 file/lib/systemd/system/startup-script.service:
startup-script.service (注:所有文件/脚本在本文末尾均存为 .zip 文件)
1 [Unit]
2 Description=Startup User Script
3 After=syslog.target
4
5 [Service]
6 ExecStart=/home/root/startup.sh
7
8 [Install]
9 WantedBy=multi-user.target
添加服务以自动启动:
# systemctl enable startup-script
重启后,符号显示器将会显示所测量的距离:
<center><img src="http://intel.eetrend.com/files/2016-03/wen_zhang_/100001245-1125-measur…; alt=""></center>
<strong>源代码</strong>
<strong>使用的资源</strong>
英特尔® Edison 开发板软件下载 https://software.intel.com/zh-cn/iot/hardware/edison/downloads
面向英特尔 Edison 的 SparkFun 数据块 — Arduino https://www.sparkfun.com/products/13036
使用 MCU SDK 和 API: 代码示例 https://software.intel.com/en-us/node/557354#Waking_up_the_host_CPU_usi…
组装带有 Arduino 扩展开发板的英特尔® Edison 开发板 https://software.intel.com/zh-cn/assembling-intel-edison-board-with-ard…
刷新英特尔® Edison http://www.intel.com/content/www/us/en/support/boards-and-kits/00000599…
使用 USB 以太网连接您的英特尔® Edison 开发板 https://software.intel.com/zh-cn/connecting-to-intel-edison-board-using…
安装 MCU SDK https://software.intel.com/en-us/node/545143
MRAA 库 https://github.com/intel-iot-devkit/mraa
面向 Arduino 的英特尔 Edison 套件硬件指南 http://www.intel.com/content/www/us/en/support/boards-and-kits/00000558…
面向 MCU SDK 的示例脚本 https://software.intel.com/en-us/node/557356
UPM 库 https://github.com/intel-iot-devkit/upm
UPM: Jhd1313m1 模块 http://iotdk.intel.com/docs/master/upm/classupm_1_1_jhd1313m1.html
使用 MCU 使 LED 指示灯闪烁 https://software.intel.com/en-us/node/545145
文章来源:<a href="https://software.intel.com/zh-cn/articles/using-an-mcu-on-the-intel-edi…;英特尔开发人员专区