2017/3/31

raspberry pi 一代真的是..

應該是廢了,一直debug wifi 一陣子就斷線。
結果是usb 問題,一陣子就斷線重新偵測...
換了bananapi 就OK,半小時了都還沒斷

usb ethernet

結果還是用了 usb-ethernet.

和在server 上一樣..
  • 先給 eth1 (usb-eth) 給定 static address 172.16.200.1
  • 設定 ip_forward=1
  • 設定 /etc/dnsmasq.conf : interface=eth1, dhcp-range=172.16.200.2,172.16.200.5,255,255,255,0,12h
  • 設定 iptables NAT eth0-eth1

然後接上 pi 之後,在pi 也如法做一次,但是這次就用 wlan0, hostapd 了。


這裡 https://github.com/ev3dev/ev3dev/wiki/Setting-Up-Linux-USB-Ethernet-Networking 竟然剛好是 usb ethernet share main nic 的設定。

要看dnsmasq 放出去的 ip list:
http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2010q3/004384.html
/var/lib/misc/dnsmasq.leases

另外,如果要指定某個MAC(11:22:33:44:55:66) 使用固定的 ip address(172.16.200.7), 可以在 /etc/dnsmasq.conf 中..
dhcp-host=11:22:33:44:55:66,172.16.200.7

2017/3/30

變更 kernel driver init 順序...

真的假的?
http://stackoverflow.com/questions/11642330/what-is-the-linux-built-in-driver-load-order

Built-in drivers wont be loaded, hence built-in. Their initialization functions are called and the drivers are activated when kernel sets up itself. These init functions are called in init/main.c::do_initcalls(). All init calls are classified in levels, which are defined in initcall_levels and include/linux/init.h

These levels are actuall symbols defined in linker script (arch/*/kernel/vmlinux.lds.*). At kernel compile time, the linker collects all function marked module_init() or other *_initcall(), classify in levels, put all functions in the same level together in the same place, and create like an array of function pointers.

What do_initcall_level() does in the run-time is to call each function pointed by the pointers in the array. There is no calling policy, except levels, in do_initcall_level, but the order in the array is decided in the link time.

So, now you can see that the driver's initiation order is fixed at the link time, but what can you do?

  • put your init function in the higher level, or
  • put your device driver at the higher position in Makefile
The first one is clear if you've read the above. ie) use early_initcall() instead if it is appropriate.

The second one needs a bit more explanation. The reason why the order in a Makefile matter is how the current kernel build system works and how the linkers works. To make a long story short, the build system takes all object files in obj-y and link them together. It is highly environment dependent but there is high probability that the linker place first object file in the obj-y in lower address, thus, called earlier.

If you just want your driver to be called earlier than other drivers in the same directory, this is simplest way to do it.

所以說,你要是寫了兩個 kernel driver,A driver 用到 B driver。
但是 kernel init driver 的順序,卻是A先,所以 A probe 的時候找不到 B...
這時候就修改 那層driver 的 Makefile,把obj-y += A.o 往後面放...

稍微紀錄,, build recovery

build-recoveryimage-target

.PHONY: recoveryimage-nodeps
recoveryimage-nodeps:
        @echo "make $@: ignoring dependencies"
        $(call build-recoveryimage-target, $(INSTALLED_RECOVERYIMAGE_TARGET))

和..
$(INSTALLED_RECOVERYIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) \
                $(INSTALLED_RAMDISK_TARGET) \
                $(INSTALLED_BOOTIMAGE_TARGET) \
                $(INTERNAL_RECOVERYIMAGE_FILES) \
                $(recovery_initrc) $(recovery_sepolicy) $(recovery_kernel) \
                $(INSTALLED_2NDBOOTLOADER_TARGET) \
                $(recovery_build_prop) $(recovery_resource_deps) \
                $(recovery_fstab) \
                $(RECOVERY_INSTALL_OTA_KEYS)
                $(call build-recoveryimage-target, $@)

2017/3/28

raspberry pi, setup wifi ap service

怎麼都是 raspberry pi 的說明...

大概記一下..



hostapd, dnsmasq
改 /etc/network/interfaces: wlan0 static
-- 這樣 wlan0 可以啟動。
建 /etc/hostapd/hostapd.conf : interface, ssid, wpa..
修改 /etc/default/hostapd : 指定 hostapd.conf 位置。
-- 這樣 ap 起動。

這一段.. 啟動 dnsmasq (lightweight, 包含 dns 和 dhcp)
修改 /etc/dnsmasq.conf : interface, dhcp-range.. 記得要把 eth0 排除 (except-interface)
-- 啟動
NAT
修改 /etc/sysctl.conf : ip_forward
用 sysctl -p 啟動。
iptables fileter and routing rules : 一堆...
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT


http://elinux.org/RPI-Wireless-Hotspot

另一個用 udhcpd
修改 /etc/udhcpd.conf :一樣,ip range, dns address..
其他 /etc/network/interfaces 改 static ip, hostapd.conf, ip_forward 和 iptables 都一樣。


就用 172.16.200.1 好了。
是 wlan2


紀錄一下在 bananapi 上的設定: /etc/network/interfaces:
source-directory /etc/network/interfaces.d

auto lo
iface lo inet loopback

auto eth0

iface eth0 inet dhcp

allow-hotplug wlan1
iface wlan1 inet static
    address 172.16.110.1
    netmask 255.255.255.0

/etc/hostapd/hostapd.conf
interface=wlan1
driver=nl80211
ssid=MYSSIDNAME
hw_mode=g
channel=6
ieee80211n=1
macaddr_acl=0
auth_algs=3
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=MYPASSWORD
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP

ht_capab=[HT40-][SHORT-GI-20][SHORT-GI-40]

logger_syslog=-1
logger_syslog_level=0

/etc/dnsmasq.conf
interface=wlan1
dhcp-range=172.16.110.2,172.16.110.8,255.255.255.0,12h
dhcp-host=XX:XX:XX:XX:XX:XX,172.16.110.7

bookmark 一下,有 ac 的 ap setting (不是 pi 的)。
wifi hostapd configuration for 80211ac networks

2017/3/27

ralink 5370

聽說..這個的linux support比較好,
其實是 可以support host 跟monitor mode..

用 iw list 看一下,支援好多 mode...
 Supported interface modes:
   * IBSS
   * managed
   * AP
   * AP/VLAN
   * WDS
   * monitor
   * mesh point
bcm43xx 只有support:
 Supported interface modes:
   * IBSS
   * managed
然後 rtl8188eu 則因為沒有 implement nl80211 界面,所以iw command 列不出來....


奇怪,突然無法啟動了。dmesg 說 load rt3870.bin failed
所以 aptitude install firmware-ralink 之後就 OK 了。

2017/3/21

nodejs on raspberry pi jessie

就用這個試試:https://github.com/audstanley/NodeJs-Raspberry-Pi

DietPi

http://dietpi.com/
原來 raspbian 除了沒有 X 的 lite 外,還有一個更小的...dietpi

還有支援很多板子...

記一下:
  • root :root
  • password : dietpi
結果..
try v145, 開機開到..Started Journal Service.. 之後就 hang 住了...

2017/3/15

Android Bluetooth SPP example

SPP 直接拿 RFCOMM,所以每個有 bluetooth 的裝置都有。
Android 的 example (直接在 SDK 下) BluetoothChat
一個程式,做 Server 和 Client..
兩隻手機戶連。

雖然在 2.X 版的 android 就包含這個 example 了,但是隨後的android 版本,這個 project source 還是有修改。
以6.0 為例。project 的 build tool 改成 gradle,command script 也修改,要用 gradle,沒有 Android.mk 了。

google 把 example 放到 github。
並且 AndroidStudio 一開始的 import 就多了一個 entry : import Android example。
會自動從 github import project。
這格版本比較新。
不用處理 SDK, gradle version 相依問題。

2017/3/13

rtc S35390A

http://jyhshin3.blogspot.tw/2010/03/s35390a-driver-for-8051.html
有說明。這個rtc 只用 4 個 bit 做 chip address, 剩下3個拿來當 command code.
所以當一般 i2c 裝置來看的化,他佔了 8 個位址。

kernel source code 也是這樣寫:
        s35390a->client[0] = client;
        i2c_set_clientdata(client, s35390a);

        /* This chip uses multiple addresses, use dummy devices for them */
        for (i = 1; i < 8; ++i) {
                s35390a->client[i] = i2c_new_dummy(client->adapter,
                                        client->addr + i);
                if (!s35390a->client[i]) {
                        dev_err(&client->dev, "Address %02x unavailable\n",
                                                client->addr + i);
                        err = -EBUSY;
                        goto exit_dummy;
                }


這樣看,他的 address 應該填 0x30 ..

在 defconfig 加上:
CONFIG_RTC_DRV_S35390A=y

在 board config 的 i2c bus device list 上加上:
       {       .type           = "s35390a",
               .addr           = 0x30,
               .flags          = 0,
       }


用 i2cdetect -y 1 (因為在 i2c-1 上)
可以看到
30: UU UU UU UU UU UU UU UU 38 39 3a 3b 3c 3d 3e 3f
符合source code..


struct i2c_msg {
        __u16 addr;     /* slave address                        */
        __u16 flags;
#define I2C_M_TEN               0x0010  /* this is a ten bit chip address */
#define I2C_M_RD                0x0001  /* read data, from slave to master */
#define I2C_M_NOSTART           0x4000  /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_REV_DIR_ADDR      0x2000  /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_IGNORE_NAK        0x1000  /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NO_RD_ACK         0x0800  /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_RECV_LEN          0x0400  /* length will be first received byte */
#define I2C_M_NEED_DELAY        0x0020  // add by kfx
#define I2C_M_REG8_DIRECT       0x0040  // add by kfx
        __u16 len;              /* msg length                           */
        __u8 *buf;              /* pointer to msg data                  */
        __u32 scl_rate;  // add by kfx
        int udelay;             //add by kfx
        __u16 read_type;
}

因為出現 i2c_transfer 的 warning, clk to low (0), 所以減查一下。發現只有 initialize i2c_msg 的前 4 個欄位。
所以在 初始值加一個欄位後 OK



check Android interface

在 Setting App 中... 最後 call AlarmManagerService 的 SetTimeMillis.
這個是 call /dev/alarm 的 ioctl ANDROID_ALARM_SET_RTC

找到 GPS, settime 也是call 這個 ioctl
所以 kernel rtc module 應該只要 implement set_time read_time 就可以,,.(?)
統整一下
i2c:

board config 的 i2c bus client data , id name 要填的是 client device driver 中 id table 填寫的 name, 不是 driver 的name。
填對了,client device driver 的 probe function 才會被呼叫。

i2cdetect -y devie 中 device 寫 0,1,2.. 就可以,他會一一去 read id address
列表中,沒反應的就會寫出 i2c address id
有反應的好像就是 --,有註冊的就是 UU

rtc:

最少要 implement read_time, set_time
register 後,會以 rtc0,1,2 的方式自動...

android 的 time set 和 gps 最後都會用 ANDROID_ALARM_SET_RTC 的 /dev/alarm ioctl 呼叫。
這個constant 定自在 bionic, 是 android 獨有的。