README.md

# 树莓派0

这是树莓派0/0w的Nerves基本配置。

![树莓派3B图](assets/images/raspberry-pi-model-zero.png)

## 使用

最常见的使用Nerves的方法是使用`mix
nerves.new` 创建一个项目,导出`MIX_TARGET=rpi0`。
更多信息请参阅[入门指南](https://hexdocs.pm/nerves/getting-started.html#creating-a-new-nerves-app)。

如果设备需要对系统进行自定义修改,
请复制此存储库并按[创建自定义系统](https://hexdocs.pm/nerves/systems.html#customizing-your-own-nerves-system)中所描述的进行更新

如果你对Nerves不熟悉,请浏览
[nerves_init_gadget](https://github.com/nerves-project/nerves_init_gadget)
来创建第一个项目。它将帮助您开始一些基础工作, 如建立网络、初始化可写应用程序数据分区以及启用基于ssh的固件更新。
使用有线以太网接口“Eth0”和DHCP是最容易的。

## 控制台与kernel消息配置

此映像的目标是使用OTG端口访问控制台。如果您正在调试引导过程,您将希望在GPIO连接器或HDMI输出上使用Raspberry PI的UART针脚。这是通过更新“cmdline.txt”文件启用的。如果您不想重建这个系统,可以用自定义的'fwup.conf'文件覆盖它。将以下内容添加到“cmdline.txt”中:

```text
console=ttyAMA0,115200 console=tty1 ...
```

如果您希望IEX显示UART管脚(`ttyama0`)或HDMI(`tty1`),那么也可以修改`rootfs_overlay/etc/erlinit.config`。

## 支持的OTG USB模式

基础图像激活`dwc2`,允许pi 0作为显示设备(又称gadget模式)。当通过OTG端口插入主机时,pi 0将显示为复合以太网和串行设备。虚拟串行端口提供对IEX提示符的访问,以太网设备可用于固件更新、erlang分发以及通过IP运行的任何其他操作。


## 支持的WiFi设备

基础镜像包括树莓PI 0w的WiFi模块(`brcmfmac` 驱动程序)。由于USB端口处于小工具模式,此系统不支持USB WiFi适配器。

## 音频

树莓PI有很多音频输出选项。该系统支持HDMI和立体声音频插孔输出,The Linux ALSA 驱动程序用于音频
输出。

试一试,运行:

```elixir
:os.cmd('espeak -ven+f5 -k5 -w /tmp/out.wav Hello')
:os.cmd('aplay -q /tmp/out.wav')
```

一般的树莓PI的音频文件适用于Nerves。
例如,强制将音频输出到HDMI端口,运行:

```elixir
:os.cmd('amixer cset numid=3 2')
```

将最后一个`amixer`参数更改为`1` 输出到立体声。


## 配置设备

该系统支持将配置信息存储在文件系统之外的key-value存储区中。配置是可选的步骤,如果缺少,则使用合理的默认值。

配置信息可以使用Nerves.Runtime KV存储的
[`Nerves.Runtime.KV.get/1`](https://hexdocs.pm/nerves_runtime/Nerves.Runtime.KV.html#get/1)函数。

本系统使用的关键字为:

关键字                    | 例如     | 描述
:--------------------- | :---------------- | :----------
`nerves_serial_number` | `"12345678"`      | 默认情况下,此字符串用于创建单一主机名和Erlang节点的名称。如果未设置,它默认为树莓PI的设备ID的一部分。

正常的程序是在制造前或部署前设置这些键,然后将它们单独保存。

例如,要在运行的设备上提供序列号,请运行以下内容并重新启动:

```elixir
iex> cmd("fw_setenv nerves_serial_number 12345678")
```

该系统支持离线设置序列号。为此需在烧录固件时设置
`NERVES_SERIAL_NUMBER`环境变量。如果使用`fwup`编写MicroSD卡,则命令行为:

```sh
sudo NERVES_SERIAL_NUMBER=12345678 fwup path_to_firmware.fw
```

序列号被存储在MICROSD卡上,所以如果MICROSD卡被替换,序列号将需要被重新编写。这些数字存储在U-boot环境块中。
 这是一个与应用程序分区分离的特殊区域,因此重新格式化应用程序分区不会丢失序列号或存储在此块中的任何其他数据。

可以通过设置环境变量`NERVES_PROVISIONING=/path/to/provisioning.conf`来覆盖默认的provisioning.conf文件位置用来提供其他键值对。
默认的provisioning.conf用来设置`nerves_serial_number`,如果重写此文件的位置,则需要您将自己负责设置。

## Linux内核与RPI固件/用户空间

在这里使用的`nerves_system_br` 版本和Linux内核版本之间有微妙的耦合。
 `nerves_system_br` 提供了安装的 `rpi-userland`和`rpi-firmware`版本。
 我更喜欢将它们与Linux内核相匹配,以避免任何问题发生。
不幸的是,这些都没有被树莓PI基金会标记,所以要么尝试匹配Raspbian中的内容,要么采用具有相似提交时间的版本库。

## 安装

如果您是Nerves新手,请查看
[nerves_init_gadget](https://github.com/fhunleth/nerves_init_gadget) 以便为Raspberry Pi Zero或Zero W创建一个启动项目。它将帮助您开始学习一些基本知识,如建立虚拟以太网接口、初始化应用程序分区以及启用基于ssh的固件更新

## Linux内核配置

为Nerves编译的Linux内核默认是树莓Pi Linux内核的精简版本。
这样做是为了去除不必要的功能,选用一些Nerves特性,并节省空间。
若要使用这里的内核配置,请执行以下操作(这有点乏味):

1. 从`arch/arm/configs/bcmrpi_defconfig`开始。这是在官方Raspberry Pi镜像中使用的内核配置。
1. 关闭除`ext4`, `squashfs`, `tmpfs`, `proc`,`sysfs`, 和 `vfat`之外的所有文件系统。 只需要ZLIB支持。
1. `vfat` 默认为 `utf8`. 启用`ascii`, `utf-8`, `ISO 8859-1`, 代码页 437, 和代码页 850的本机语言支持。
1. 禁用 Broadcom FullMAC WLAN 以外的所有网络驱动程序和无线局域网驱动程序。
1. 禁用 PPP 和 SLIP。
1. 禁用驱动程序菜单中的WiFi驱动程序。
1. 在多媒体支持菜单中禁用 TV, AM/FM, 媒体USB适配器, DVB前端和远程控制器支持。
1. 转到`Device Drivers->Sound card support`。禁用ALSA中的`USB sound devices`, 禁用 `Open Sound System`.
1. 转到`Device Drivers->Graphics support`. 禁用 `DisplayLink`
1. 禁用`HID support` (注意:重新访问蓝牙)
1. 禁用输入设备支持中的所有功能 (无法插入设备)
1. 在`Device Drivers > USB support` 菜单中,启用小工具模式并禁用所有主机模    式。如果先前步骤中的所有USB驱动程序都被禁用,则可以完全禁用USB主机模式。请参阅`DesignWare USB2 Core Support->DWC Mode Selection` 并选择 `CDC Composite Device (Ethernet and ACM)`. 如果你想要双模式 USB host/gadget    支持,你需要重新启用一些东西。 双模式支持在过去一直存在未解决的问题。它们可能是固定的,但一定要测试。他们在非Mac平台上需要注意。

1. 在 `Kernel Features`中, 选择 `Preemptible Kernel (Low-Latency Desktop)`,
   禁用压缩页的内存分配器。
1. 在 `Userspace binary formats`中, 禁用对MISC二进制文件的支持。
1. 在 `Networking support`中, 禁用业余无线电支持、CAN总线子系统、IrDA子系统、蓝牙、WiMAX、Plan 9和NFC。
(这可能太苛刻了,如果使用这些中的任何一个,请提出问题,这是创建自定义系统的唯一原因)。
1. 在 `Networking options`, 禁用IPSec,SCTP协议802.1D以太网,异步传输模式,桥接,L2TP, VLAN, AppleTalk, 6LoWPAN 802.15.4,DNS,旋转变压器, B.A.T.M.A.N, 虚拟交换机, MPLS, 以及网络测试中的包生成器。
1. 在 `Networking support->Wireless`中, 启用 "use statically compiled regulatory
   rules database"。内置`cfg80211` 和 `mac80211`。关闭`mac80211`网状网络和LED触发器。
   关闭 `cfg80211` 无线扩展兼容性。
1. 在 `Kernel hacking`中, 禁用 KGDB, 和 Magic SysRq key.
1. 在设备驱动程序中,禁用MTD支持。在块设备中,禁用除了回环和RAM块设备以外的所有设备。禁用SCSI设备支持。禁用RAID和LVM。
1. 在 `Enable the block layer`中, 取消选择一切,但PC BIOS分区类型(即,没有MAC分区支持等)。
1. 在 `Enable loadable module support`中, 选择 "Trim unused exported kernel symbols"。
注意:如果你在一个树外内核模块构建中遇到问题,试着删除这个!!
1. 在 `General Setup`中, 关闭 `initramfs/initfd` 支持, 关闭Kernel .config
   支持, 关闭OProfile.
1. 在 `Device Drivers -> I2C -> Hardware Bus Support`中,  将模块编译到内核中,并禁用除了`BCM2708 BSC`支持之外的所有功能。
1. 在 `Device Drivers -> SPI`中, 编译BCM2835 SPI 控制器和用户模式SPI 设备驱动支持。
1. 在 `Device Drivers -> Dallas's 1-wire support`中,  除了GPIO 1-主线和温度计外,禁用其他。(注:为什么温度计编译? 这似乎是个历史问题。)
1. 禁用 `Hardware Monitoring support`, `Sonics Silicon Backplane support`
1. 在 `Device Drivers -> Character devices -> Serial drivers`中,  禁用8250和SC16IS7xx支持。禁用原始驱动程序。
1. 在 `Networking support->Network options`中,  禁用 `IP: kernel level autoconfiguration`
1. 在 `Networking support->Network options->TCP: advanced congestion control`中,
   禁用除`CUBIC TCP`以外的所有内容。
1. 禁用 `Real Time Clock`.
1. 禁用`Cryptographic API` 和 `Library routines`中的所有内容。有时你需要多次尝试。
1. 禁用EEPROM 93CX6支持、PPS支持、所有GPIO扩展器、语音核心、媒体分级驱动程序、意法半导体STMPE、全部"Wolfson"。
1. 禁用大多数ALSA的SoC音频支持和编解码器。注意:我们可能应该支持一些,但是我不知道哪些是最有用的,而且列表中还有很多设备驱动程序。
1. 禁用IIO和UIO。
1. 禁用NXP PCA9685 PWM驱动器