2012年10月22日 星期一

[OpenWrt] preinit

一般 Linux 執行的第一個指令會是 /sbin/init、/etc/init、/bin/init、/bin/sh 其中之一 ,而 OpenWrt 將第一個執行的指令改為 /etc/preinit。

/etc/preinit 會呼叫 /lib/preinit/ 下的 script 來準備下列五組程式組,記在環境變數裡,並執行前面兩組:
  1. preinit_essential:會先執行,大致上是在掛載 /proc, /sys, /tmp, /dev 等,跟相關 daemon,以及初始化 console。
  2. preinit_main:大致包括載入 reset 按鍵驅動,設定網路界面,檢查是否執行 failsafe 程式組,初始化 hotplug,檢查是否執行 initramfs 程式組,執行 preinit_mount_root 程式組,回復系統設定,最後執行 /sbin/init。
  3. failsafe:提供 telnet 登入
  4. initramfs:似乎是空的
  5. preinit_mount_root:掛載根目錄

2012年10月10日 星期三

[設備] TP-LINK TL-WR703N

號稱市面上最小的含有 USB Host 的 Wi-Fi AP,也相當省電,低於 1W[參考來源]

主要處理器是 Atheros AR9331,內含:
  • AR7240 CPU @400MHz
  • Wi-Fi 802.11b/g/n
  • Fast Ethernet (有 5 port,但 WR703N 只用一個)
  • USB 2.0
外加 4MB Flash 及 32MB RAM

AR9331 也用在 TL-MR3020 (多開關及一些燈號)、TL-WR741ND (使用 5 port Ethernet)

由於 OpenWrt 有支援,常拿來改成其它應用。

拆解:[參考]。應該拿小一字起子,往有卡榫的地方插下去。我插在卡榫旁邊不太好拆,需要一些暴力,造成一些損傷。

接 UART 出來
  • 拆開後,正面下方的 TP_IN 及 TP_OUT 分別是 UART 的 Rx 及 Tx,如果接 FT232R 或其它轉 USB 的晶片或連接線,只需要再找一個 GND 接點。有人把 Ethernet 或 USB 的鐵殼當 GND,其實不是。除了背面的 TPGND 外,可以找的很多地方去接 GND。
  • baud rate 是 115200。
備份 u-boot 及 art:
  • u-boot 是 bootloader,損壞的話,將無法開機,也無法做任何更新動作,只能解焊 SPI Flash 透過燒錄器寫入好的 u-boot,才能讓 TL-WR703N 重新運作。有了 u-boot 之後,就可以更新其它任何部份。
  • art 是放無線校準後的資料,損壞的話,可以開機,但會影響到無線功能無法使用。這裡提到,如果沒經過校準,Wi-Fi 訊號可能會較差;也就是複製別台同樣型號及處理器的 art,未必適用。
  • 參考這裡,在 UART console 下用 Linux 的 cp 指令讀出 u-boot 及 art 分割,透過網頁存到 PC。應該也可以使用指令「dd if=/dev/mtd0 of=/tmp/boot.backup」跟「dd if=/dev/$(grep '"art"' /proc/mtd |cut -c 1-4) of=/tmp/art.backup」讀出。
加大 SPI Flash (例如改用 8MB SPI Flash)
  • firmware 修改:
    1. OpenWrt 的 tools/firmware-utils/src/mktplinkfw.c
      •  TL-WR703Nv1 的 fw_max_len 改成 0x7c0000
    2.  target/linux/ar71xx/files/arch/mips/ar71xx/mach-tl-wr703n.c
      • rootfs 的 .size 改成 0x6d0000
      • art 的 .offset 改成 0x7f0000
      • firmware 的 .size 改成 0x7d0000
    3. 編譯,結果在 bin/ar71xx/openwrt-ar71xx-tl-wr703n-v1-squashfs-*.bin
  • 最終 8MB SPI Flash 的內容應該是:
    • u-boot 複製自原本的 flash,放到 8MB flash
    • art 複製自原本的 flash,放到到最後分割,也就是位址 0x7f0000 開始的地方
    • firmware 需要改成支援 8MB Flash 後重新編譯產生,放到位址 0x20000 開始的地方
  • 解焊舊 SPI Flash,焊上新 8MB SPI Flash。
  • 參考
參考資料:

2012年10月8日 星期一

2012年10月6日 星期六

OpenWrt LED

無線路由器有許多 LED 顯示狀態。在 OpenWrt 下,如何控制 LED 呢?

除了電源狀態 (PWR) 是有電就亮,及一些 Ethernet 狀態 (WAN 和 LAN 1 2 3 4) 是 Ethernet Controller 直接控制外,其它 LED 是接到 SoC 的 GPIO,Linux Kernel 有個 platform 子系統,並有一些針對 GPIO 的現成驅動程式,例如驅動程式 leds-gpio 用來控制 LED。只要把 GPIO 的位置,所使用的驅動程式及功能在編譯前設定好,編譯後的 Linux Kernel 就能支援這些 GPIO。
  • 準備資料結構 struct gpio_led,內含每個 LED 名稱、GPIO 接腳、是否 low 動作等。例如:
    static struct gpio_led tl_wr1043nd_leds_gpio[] __initdata = {
        {
            .name        = "tl-wr1043nd:green:wlan",
            .gpio        = TL_WR1043ND_GPIO_LED_WLAN,
            .active_low    = 1,
        }
    };
    不清楚 LED 名稱為何要取 tl-wr1043nd:green:wlan 這麼一長串
  • 透過 platform_device_alloc() 取得使用 "leds-gpio" 的資料結構 struct platform_device。(相反是 platform_device_put())
  • 建構資料結構 struct gpio_led_platform_data,包括 LED 數目,及 leds 欄位指到 struct gpio_led
  • 透過 platform_device_add_data() 加進 struct gpio_led_platform_data
  • 透過 platform_device_add() 登記到 Linux Kernel
上述例子是在 Linux 的 arch/mips/ar71xx/mach-tl-wr1043nd.c 執行 arch/mips/ar71xx/dev-leds-gpio.c 裡的 ar71xx_add_device_leds_gpio() 完成的。

編譯後的 Linux 就會有 /sys/class/leds/tl_wr1043nd:green:wlan/  目錄。使用方式,例如
點亮 LED:
echo 1 > /sys/class/leds/tl_wr1043nd:green:wlan/brightness
熄滅 LED
echo 0 > /sys/class/leds/tl_wr1043nd:green:wlan/brightness
應該還有其它用法,待了解。

2012年9月21日 星期五

FXS 轉 UART

連接話機的界面是 FXS (Foreign eXchange Station),連接局端的界面是 (FXO, Foreign eXchange Office),FXS 或 FXO 轉換成其它界面叫 ATA (Analog Telephone Adaptor)。網路上可以找到兩個將 FXS 轉成 UART 的專題,都是 David Rowe 的傑作:一開始的「 $10 ATA」跟構想延伸的「Mesh Potato 的 FXS 界面」,想在無線路由器加 FXS 界面,而 UART 是無線路由器都有的界面,只藏在裡面的電路板上,baud rate 115 kbit/s 就夠 64 kbit/s 的語音使用。

「$10 ATA」後來也受到 Mesh Potato 影響,但最後資訊是去年三月,之後可能沒有進展,或者作者未公佈,主要缺如何一起在 UART 傳振鈴及 hook 資訊,跟整合測試。其架構如下:
     +---------------+   +--------------------+
     |     Hybrid    |<->|ADC/PWM             |
話機-| DC-DC/ringing |<->|PWM/ADC  ATmega328P |--UART
     | hook detector |-->|PWM                 |
     +---------------+   +--------------------+
ATmega328P 是 AVR 八位元微處理器,也用於 Arduino,可以處理類比訊號,用其 ADC 及 PWM 來轉換類比訊號。作者一系列文章:
Mesh Potato 已經是一個產品了,是一個含有 FXS 界面的戶外型 802.11bg mesh router,相當特別。架構如下:
     +--------+   +--------------------+  +------------+
     |        |<--|SPI                 |<-|GPIOs       |
話機-| Si3210 |   |       CPLD         |  |     AR2317 |
     |        |<->|TDM                 |->|UART Rx     |
     +--------+   +--------------------+  |            |
                  | ATmega8L(16B FIFO) |<-|UART Tx     |
                  +--------------------+  +------------+
AR2317 是 Atheros 的無線 MIPS 4KEc SoC,用於 AIR-300 等無線路由器。Si3210 是 FXS 界面晶片,包括 hybrid、DC-DC converter、振鈴、hook 偵測等,語音走 TDM,控制走 SPI。CPLD 主要是要轉換 UART 跟 TDM,但可能是內部 buffer 不夠,所以加 ATmega8L。

參考

  • Silvertel Ag2130 PSTN 界面模組。(RT03106)
  • USB FXS

FT232R

FT232R 是一個 USB 轉 UART 的晶片,整合 clock 及 EEPROM 等,讓線路非常簡單。有些 Arduino 含有 FT232R 來提供 USB 界面,例如 DuemilanoveDiecimila,但新的 Leonardo 使用 ATmega32u4 處理器已經內建 USB 了。FT232R 除了 UART 功能外,亦可作為 Clock 產生器,透過 bit bang 模式提供 GPIO 或 SPI 功能,或者作為 FTDIChip-ID™ security dongle 功能。
  • 相關文件:DatasheetBit Bang Application NoteFTDIChip-ID™ Application Note
  • 內建 128 bytes EEPROM 作為設定用,其中 Manufacturer, ManufacturerId, Description, SerialNumber 字串最長 96 bytes,沒用完的可作為 user area 或 FTDIChip-ID 使用。
  • 可產生 6/12/24/48 MHz clock
  • Big Band I/O
    • Asynchronous:UART 8 IO 作為 8-bit data,CBUS 提供 RD# 跟 WR# 訊號
    • Synchronous:同上
    • CBUS Mode:CBUS0~CBUS3 4-bit GPIO
  • 內建 3.3V 電源轉換,最大提供 50mA。
  • 驅動程式
    • Virtaul Com Port (VCP):變成一般序列埠使用
      • Linux: ftdi_sio → usbserial
    • Direct (D2XX):設定 EEPROM 及 bit bang 需要
    • libFTDI for Linux
      • 裡面的 ftdi_eeprom_build() 或 ftdi_eeprom_decode() 可看出 EEPROM 內容每個位址的定義。

FT232RL IO 訊號
PinName預設功能Bit Bang
CBUS modeAsynchronous / Synchronous
1TXD 輸出D0
5RXD 輸入D1
3RTS# 輸出 (Arduino Reset)D2
11CTS# 輸入D3
2DTR# 輸出 (Arduino Reset)D4
9DSR# 輸入D5
10DCD# 輸入D6
6RI# 輸入D7
23CBUS0TXLED# 輸出4-bit GPIO其中兩個作為 RD# 及 WR#
22CBUS1RXLED# 輸出
13CBUS2TXDEN 輸出,RS-485 用。
14CBUS3PWREN# 輸出,需外加 10kΩ pull high,USB 設定完 low,USB suspend 時 high。
12CBUS4SLEEP# 輸出,USB suspend 時 low。
CBUSx 都可以設定成任何 CBUS 功能,除了表列五種外,尚有 TX&RXLED#、6/12/24/48 MHz clock 輸出。

內部 EEPROM,整理自 datasheet 及 libFTDI。
parameteraddressvalue說明
High Current I/Os0.20
10x40IN endpoint size
Vendor ID3~20403hFTDI default VID
Product ID5~46001hFTDI default PID
Device Type7~60x06000x0600=FT232R
Battery Powered8.40
Remote Wake Up8.51RI# low → wake up USB Host Controller in 20 ms
Bus Powered 8.61
Load VCP Driver8.71Make the host to load VCP driver。此位置是猜測的。
Max Bus Power Current990mA以 2 mA 為單位
IN endpoint is isochronous0x0a.00
OUT endpoint is isochronous0x0a.10
Enable suspend I/O power down0x0a.20
Use serial number string0x0a.30
Change USB Version0x0a.40
Invert TXD0x0b0
Invert RXD0
Invert RTS#0
Invert CTS#0
Invert DTR#0
Invert DSR#0
Invert DCD#0
Invert RI#0
USB Version0x0d~0x0c0x0200USB 2.0 Full Speed
Manufacturer Offset0x0e.6~00x18指向 10, 0x03, "FTDI"
Manufacturer Enabled0xe.71
Manufacturer Size0x0f10byte 數含結尾 0,因每個字佔 2 bytes,所以需乘二
Product Description Offset0x10.6~00x24指向 32, 0x03, "FT232R USB UART"
Product Description Enabled0x10.71
Product Description Size0x1132
Serial Number Offset0x12.6~00x46指向 18, 0x03, "A6001dHI",A unique serial number
Serial Number Enabled0x12.71
Serial Number Size0x1318
CBUS00x14.3~030=TXDEN, 1=PWREN#, 2=RXLED#, 3=TXLED#, 4=TXRXLED#, 5=SLEEP#, 6=CLK48, 7=CLK24, 8=CLK12, 9=CLK6, 10=Bitbang IO mode, 11=Bitbang WR#, 12=Bitbang RD#
CBUS10x14.7~42
CBUS20x15.3~00
CBUS30x15.7~41
CBUS40x16.3~05
Dynamic Content0x18~0x7f見說明預設應該是放 Manufacturer, Production Description, 及 Serial 字串。字串含 0,每字佔兩個 byte。格式依序是長度,0x03,字串本身。
10, 0x03, "FTDI"
32, 0x03, "FT232R USB UART"
18, 0x03, "A6001dHI"
ChipID0x86~0x89見說明

USB 的請求控制指令:
  • reset (0x00)
  • set baud rate (0x01)
  • set data (0x02):設定 RS-232 參數
  • set flow control (0x03)
  • modem control (0x04):設定 DTR, RTS 等。
  • poll modem status (0x05)
  • set event char (0x06)
  • set error char (0x07)
  • set latency timer (0x09)
  • get latency timer (0x0a)
  • set bit mode (0x0b)
  • read pins (0x0c)
  • read eeprom (0x90)
  • write eeprom (0x91)

實際應用

2012年9月14日 星期五

SIP header Via

所有 SIP 訊息 都要有 Via,縮寫 v。一開始的 UAC 和後續途經的每個 proxy 都會疊加一個 Via 放傳送的位址,依序作為回應的路徑。 格式 sent-protocol sent-by [ ;branch= branch ][ ; 參數 ...] s...