---
# System prepended metadata

title: AM335x/Beaglebone Black IOT BSP How-to
tags: [Beaglebone Black, TI AM335x, DevelopingNotes]

---

# AM335x/Beaglebone Black IOT BSP How-to
持續更新
[TOC]
## 前言
這個主要是紀錄TI AM335x/Beaglebone black作為信號收集器的開發過程以及可能遇到的問題
## AM335X boot option(Beaglebone Black)
boot option在正常開機來說是
eMMC(MMC1) -> SD Card(MMC0) -> USB0(RNDIS) -> UART0
當按著S2開機時，會是
SD Card(MMC0) -> USB0(RNDIS) -> UART0 -> eMMC



## BSP Requirement
一個BSP Image內容主要分為bootloader, kernel, rootfs, 以及rootfs上面的system services, user profiles, network configuration等

基本上，原始的AM335x開發板會有SD卡槽和eMMC flash，同時也支援從TFTP下載的方式去將系統寫進eMMC。

信號收集器一般而言不會有SD卡的卡槽，因此只能透過TFTP boot把系統的image寫進去eMMC。

TI提供的寫入image工具有以下兩種
- for Window: [CCS Uniflash5.0](https://processors.wiki.ti.com/index.php/Category:CCS_UniFlash)、[CCS Uniflash 3.4.1](http://software-dl.ti.com/dsps/forms/self_cert_export.html?prod_no=uniflash_3.4.1.00012_win32.zip&ref_url=http://software-dl.ti.com/ccs/esd/uniflash/)
- for Linux: TFTP boot /CCS Uniflash

![AM335x flash to eMMC duagram](https://i.imgur.com/B7aoHr7.png)
從上圖來說，主要有兩種image需要製作
1. flasher program/Image: 這個的功用主要是經由USB/Ethernet把Flasher image載入AM335X的RAM/DDR，並且開機，開機完後便會開始把Flasher Image所包含的Images寫入eMMC中
2. System Image:真正在eMMC運作的系統映像檔，會藉由flasher.sh來寫入

基本上，在flash mode的時候，AM335X是會被當成一張Linux RNDIS網卡來看。
### flasher program/image
內容主要有以下組成
- MLO(SPL)
- u-boot.img
- Linux Kernel Image
- customized flasher file system(ramfs)
- customized debrick script(flasher<span>.sh)
### System Image
內容有以下組成
- MLO
- u-boot.img
- Linux kernel
- rootfs
### Setting steps of Ubuntu as a tftp server
- Host OS: Ubuntu 12.04
之所以選擇12.04，是由於其Network interface naming rule還是以eth0/eth1/usb0等等去命名，而不是動態依據device所連接的interface去命名
- 前置步驟:安裝以下package
sudo apt-get install isc-dhcp-server tftpd-hpa xinetd
- Edit BOOTP/DHCP Server(/etc/dhcp/dhcpd.conf)
這個設定主要是給BOOTP Client從192.168.2.2~192.168.2.100的IP位址範圍，TFTP server通常會是192.168.2.1
```script=
# /etc/dhcp/dhcpd.conf
## bootp subnet declaration
subnet 192.168.2.0 netmask 255.255.255.0 { 
range dynamic-bootp 192.168.2.2 192.168.2.100; 
if substring (option vendor-class-identifier, 0, 10) = "AM335x ROM" 
{ filename "u-boot-spl-restore.bin"; } 
elsif substring (option vendor-class-identifier, 0, 10) = "DM814x ROM" 
{ filename "u-boot-spl-restore.bin"; } 
elsif substring (option vendor-class-identifier, 0, 17) = "AM335x U-Boot SPL" 
{ filename "u-boot-restore.img"; } 
else { filename "zImage"; } 
range 192.168.2.101 192.168.2.199; }
```
- Setup TFPT server(edit /etc/xinetd.d/tftp)
寫入底下設定內容後，裡面server_args主要是定義tftpboot的folder在哪邊，其實可以自己去定義
```script=
service tftp
{
protocol = udp 
port = 69 
socket_type = dgram 
wait = yes 
user = root 
server = /usr/sbin/in.tftpd 
server_args = -s /tftpboot 
disable = no 
}
```
- 設定tftpboot folder
```script=
sudo mkdir /tftpboot
sudo chmod -R 777 /tftpboot
sudo chown -R nobody /tftpboot
```
- 設定/etc/default/isc-dhcp-server
```script=
#INTERFACESv4="HOST_NET_INTERFACE INTERFACE_OF_AM335X_Device"
INTERFACESv4="eth0 usb0"
```
- 重新啟動服務
> systemctl restart isc-dhcp-server
> systemctl restart tftpd-hpa
- 其他設定1
```script=
# /etc/NetworkManager/dispatcher.d/99am335x-dhcp-server
#!/bin/sh
IF=$1
STATUS=$2

if [ "$IF" = "usb0" ]&&[ "$STATUS" = "up" ] ; then
        service isc-dhcp-server restart
fi
```
- 其他設定2
新增以下內容
```script=
# /etc/network/interfaces
allow-hotplug usb0
iface usb0 inet static
address 192.168.2.1
network 192.168.2.0
netmask 255.255.255.0
broadcast 192.168.2.255 
up /etc/network/if-up.d/usb-interfaces
```
- 其他設定3
```script=
#/etc/network/if-up.d/usb-interfaces
#!/bin/sh 
if [ "$IFACE" = usb0 ]; then 
service isc-dhcp-server restart 
fi 
```
- 其他設定4
```script=
#/etc/NetworkManager/NetworkManager.conf
[main]
plugins=ifupdown,keyfile
dns=dnsmasq

no-auto-default=9A:1F:85:1C:3D:0E,

[ifupdown]
managed=true
```
### u-boot(bootloader)
u-boot需要加入TFTP boot的機制
而需要去擴增**BOOT_TARGET_DEVICES**的Macro
可以參考[這邊](https://www.twblogs.net/a/5cacfc90bd9eee2e850fb03d)了解其機制。
針對C的巨集(Macro)，需要了解的是#的用法，當巨集定義為
```C=
#define Peval(cmd) printf(#cmd ":%g\n", cmd);
Peval(list[0])
//Peval(list[0])會展開為
//printf("list[0]"":%g\n", list[0]);
//前置處理器會把字串自然合併
//printf("list[0]:%g\n", list[0]);
```
這時#cmd會被視為文字輸出。
如果要連結兩個字串外的東西，則可以使用##
```C=
#define TEST(name) name ## _list
TEST(good)
//會被解成 good_list
```

### Linux Kernel
### Rootfs

#### 注意事項
init.d script echo message: 由於echo是印到stdout，所以先要在rootfs的dev下面

mknod -m 600 console c 5 1
mknod -m 666 null c 1 3

之後boot up才會把script的message印出來

### System Services
### User Profiles
### Network Configuration

## Task to Complete
### Basic System Build

### System Service Build

### TFTP Boot
TFTP用在embedded target board上面算是很常見的手段
- Target Board Driver as network device

- Flash to eMMC

## Linux Network Statck
之所以會有這一段，是因為產品會使用PRU來作為Ethernet接口的輸入，而需要把中間的Network stack給補足

###### tags:`TI AM335x` `Beaglebone Black` `DevelopingNotes`