ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上

2010年12月30日 星期四

mkfs.ext4 for ARM (Android)

因為 eSD, eMMC mount 在版上,所以不能用讀卡機接到 PC 作 format。
所以要再 target board 上作 mkfs.ext4。
而且因為 bionic 的關係,要 static link lib.

partition 還好,busybox 就有支援, ext4 就沒有 (到1.18 還沒有),
所以只好 build 一版 for arm 的 mkfs (mke2fs).

這一篇:mtab 有多重要 有完整的說明。
另外 這一篇:制作嵌入式文件系统工具 mkfs.ext2 mkfs.ext3 mkfs.ext4 也有說明

Download http://sourceforge.net/projects/e2fsprogs/

解開後,run config:
LDFLAGS=-static ./configure --host=arm-none-linux-gnueabi 然後 make 就可以了,會在 misc 下找到 mke2fs.

copy 到 target 上,用
#mke2fs -t ext4 /dev/block/mmcblk2p4 就 .... 會像 elleryq 說的一樣,因為沒有 /etc/mtab ,所以沒有辦法做出 journal.

跟elleryq說的一樣,建一個空的 /etc/mtab 就可以了。


或是用 busybox 的 mkfs.ext3 format 完在用
# tune2fs -O extents,uninit_bg,dir_index /dev/sdxn #e2fsck /dev/sdxn
ref
  1. https://ext4.wiki.kernel.org/index.php/Ext4_Howto#Converting_an_ext3_filesystem_to_ext4
  2. http://wiki.debian.org.hk/w/Format_disk_as_Ext2,_Ext3_or_Ext4

2010年12月29日 星期三

ref: http://www.debian.org/doc/manuals/apt-howto/ch-sourcehandling.en.html $apt-get source ibus-chewing charles-chang@ubuntu:~/Downloads$ apt-get source ibus-chewing Reading package lists... Done Building dependency tree Reading state information... Done NOTICE: 'ibus-chewing' packaging is maintained in the 'Bzr' version control system at: lp:~pkg-ime/ibus/debian-ibus-chewing Please use: bzr get lp:~pkg-ime/ibus/debian-ibus-chewing to retrieve the latest (possibly unreleased) updates to the package. Need to get 85.5kB of source archives. Get:1 http://us.archive.ubuntu.com/ubuntu/ maverick/main ibus-chewing 1.3.6.20100730-1 (dsc) [1,480B] Get:2 http://us.archive.ubuntu.com/ubuntu/ maverick/main ibus-chewing 1.3.6.20100730-1 (tar) [80.7kB] Get:3 http://us.archive.ubuntu.com/ubuntu/ maverick/main ibus-chewing 1.3.6.20100730-1 (diff) [3,316B] Fetched 85.5kB in 3s (25.1kB/s) sh: dpkg-source: not found Unpack command 'dpkg-source -x ibus-chewing_1.3.6.20100730-1.dsc' failed. Check if the 'dpkg-dev' package is installed. E: Child process failed then install dpkg-dev then install build-dep for ibus-chewing

2010年12月28日 星期二

ibus_main( )

2010年12月27日 星期一

紀錄一下 uboot 讀到的 ocr csd register:
  • mmc ocr: 80FF8080
  • csd : D00F0032 F5A03A6 FFFFFCFF 92404000
CSD 的 byte order是相反的:
  • D00F0032 : 96-127
  • 0F5A03A6 : 64-95
  • FFFFFCFF: 32-63
  • 92404000 : 0-31
跟micro sd 讀到的一樣。 很麻煩,還是用 linux 的 code: #define UNSTUFF_BITS(resp,start,size) \ ({ \ const int __size = size; \ const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \ const int __off = 3 - ((start) / 32); \ const int __shft = (start) & 31; \ u32 __res; \ \ __res = resp[__off] >> __shft; \ if (__size + __shft > 32) \ __res |= resp[__off-1] << ((32 - __shft) % 32); \ __res & __mask; \ }) 這樣就可以用比較漂亮的方式: csd_struct = UNSTUFF_BITS(resp, 126, 2); m = UNSTUFF_BITS(resp, 115, 4); e = UNSTUFF_BITS(resp, 112, 3); csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100; m = UNSTUFF_BITS(resp, 99, 4); e = UNSTUFF_BITS(resp, 96, 3); csd->max_dtr = tran_exp[e] * tran_mant[m]; csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); e = UNSTUFF_BITS(resp, 47, 3); m = UNSTUFF_BITS(resp, 62, 12); csd->capacity = (1 + m) << (e + 2); csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); csd->read_partial = UNSTUFF_BITS(resp, 79, 1); csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); csd->write_partial = UNSTUFF_BITS(resp, 21, 1); host->read_bl_len = (1<<9); host->write_bl_len = (1<<9); host->capacity = csd->capacity<<(csd->read_blkbits - 9); CSD 的內榮要看 JEDEC 84-A43 : (http://www.solutioninside.com/~jackiekan/lib/exe/fetch.php?id=dsd2008%3Aindex&cache=cache&media=dsd2008:jedsd84-a43.pdf) command class 在 linux header 有定義: /* * Card Command Classes (CCC) */ #define CCC_BASIC (1<<0) /* (0) Basic protocol functions */ /* (CMD0,1,2,3,4,7,9,10,12,13,15) */ /* (and for SPI, CMD58,59) */ #define CCC_STREAM_READ (1<<1) /* (1) Stream read commands */ /* (CMD11) */ #define CCC_BLOCK_READ (1<<2) /* (2) Block read commands */ /* (CMD16,17,18) */ #define CCC_STREAM_WRITE (1<<3) /* (3) Stream write commands */ /* (CMD20) */ #define CCC_BLOCK_WRITE (1<<4) /* (4) Block write commands */ /* (CMD16,24,25,26,27) */ #define CCC_ERASE (1<<5) /* (5) Ability to erase blocks */ /* (CMD32,33,34,35,36,37,38,39) */ #define CCC_WRITE_PROT (1<<6) /* (6) Able to write protect blocks */ /* (CMD28,29,30) */ #define CCC_LOCK_CARD (1<<7) /* (7) Able to lock down card */ /* (CMD16,CMD42) */ #define CCC_APP_SPEC (1<<8) /* (8) Application specific */ /* (CMD55,56,57,ACMD*) */ #define CCC_IO_MODE (1<<9) /* (9) I/O mode */ /* (CMD5,39,40,52,53) */ #define CCC_SWITCH (1<<10) /* (10) High speed switch */ /* (CMD6,34,35,36,37,50) */ /* (11) Reserved */ /* (CMD?) */ EXT_CSD 的資料更多。 在 linux kernel 的 source code : include/linux/mmc/mmc.h 有一些定義: 用到的 field 也有定義: #define EXT_CSD_BOOT_BUS_WIDTH 177 /* R/W */ #define EXT_CSD_BOOT_CONFIG 179 /* R/W */ #define EXT_CSD_BUS_WIDTH 183 /* R/W */ #define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ #define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */ #define EXT_CSD_BUS_WIDTH_4_DDR 5 /* Card is in 4 bit ddr mode */ #define EXT_CSD_BUS_WIDTH_8_DDR 6 /* Card is in 8 bit ddr mode */ #define EXT_CSD_HS_TIMING 185 /* R/W */ #define EXT_CSD_CARD_TYPE 196 /* RO */ #define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */ #define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */ #define EXT_CSD_CARD_TYPE_DDR_52 (2<<1) /* Card can run at DDR 52MHz */ #define EXT_CSD_REV 192 /* RO */ #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ #define EXT_CSD_BOOT_SIZE_MULT 226 /* RO, 1 bytes */ #define EXT_CSD_BOOT_INFO 228 /* RO, 1 bytes */

Change vimdiff color

hi DiffAdd term=reverse cterm=bold ctermbg=green ctermfg=white hi DiffChange term=reverse cterm=bold ctermbg=cyan ctermfg=black hi DiffText term=reverse cterm=bold ctermbg=gray ctermfg=black hi DiffDelete term=reverse cterm=bold ctermbg=red ctermfg=black 因為diff convert 的某 background C comment 的顏色一樣,所以會看不到 code, 所以改 .vimrc。 用上面的。

uboot - mmc - reading notes

common/cmd_mmc.c : do_mmcops()

drivers/mmc/mmc.c : mmc_init( )

go_idle( ) -- cmd 0
if_cmd( ) -- SD
sd_op_cond( ) --
mmc_op_cond( ) --

go_idle( )
cmd : OCR_HCS | mmc->voltages
- get  version, ocr, high_capacity from response.

mmc_startup

cmd : MMC_CMD_ALL_SEND_CID
- get CID
cmd : SD_CMD_SEND_RELATIVE_ADDR
cmdarg : mmc->rca >>16
- set relative address
cmd : MMC_SEND_CSD
- get CSD
cmd : MMC_CMD_SELECT_CARD
- set into transfer mode

mmc_change_freq( ) -- set freq  -- a lot of command
mmc_switch( ) -- set bus width (MMC_CMD_SWITCH)
mmc_set_clock( ) --


start.S start_armboot mmc_initialize --board_mmc_init ----esdhc_gpio_init ------fsl_esdhc_initialize (all the sdhc) : set host controller capability --------mmc_register

install a Master Boot Record

在 mbr 套件。 有 install-mbr 用 #install-mbr /dev/sda 可以用來在 usb driver 建立開機磁區。
[3535199.173907] usb 1-8: USB disconnect, address 10 [4412460.642042] EXT4-fs error (device loop0): htree_dirblock_to_tree: bad entry in directory #2: directory entry across blocks - block=16offset=0(0), inode=3822418, rec_len=146784, name_len=82 [4412460.644535] EXT4-fs error (device loop0): htree_dirblock_to_tree: bad entry in directory #2: directory entry across blocks - block=16offset=0(0), inode=3822418, rec_len=146784, name_len=82 [4646877.140014] usb 4-2: new full speed USB device using ohci_hcd and address 2 [4646877.352101] usb 4-2: New USB device found, idVendor=067b, idProduct=2303 [4646877.352107] usb 4-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [4646877.352112] usb 4-2: Product: USB-Serial Controller [4646877.352116] usb 4-2: Manufacturer: Prolific Technology Inc. [4646877.352244] usb 4-2: configuration #1 chosen from 1 choice [4646877.933260] usbcore: registered new interface driver usbserial [4646877.933856] USB Serial support registered for generic [4646877.934457] usbcore: registered new interface driver usbserial_generic [4646877.934462] usbserial: USB Serial Driver core [4646877.959565] USB Serial support registered for pl2303 [4646877.960436] pl2303 4-2:1.0: pl2303 converter detected [4646877.992316] usb 4-2: pl2303 converter now attached to ttyUSB0 [4646877.992339] usbcore: registered new interface driver pl2303 [4646877.992343] pl2303: Prolific PL2303 USB to serial adaptor driver

2010年12月24日 星期五

Build native c program in Windows with Eclipse

這一篇 (http://hi.baidu.com/oopsware/blog/item/5a86550152edf7d1267fb56e.html) 有說明在 windows 下,用 cygwin 環境 build android native c executable program.

同樣的方法大概可以用在 windows eclipse 吧。

其中 compiler 用 codesourcer的, library, header 從 linux building server 上 copy 過來。

文章說,header, library 的位置和 build option 可以參考:
 myandroid/build/core/combo/ TARGET_linux_arm.mk

其中 crtbegin_XX.o 在
/myandroid/out/target/product/imx51_bbg/obj/lib
libc.a 在
myandroid/out/target/product/imx51_bbg/obj/STATIC_LIBRARIES/libc_intermediates
..

2010年12月21日 星期二

linux - mmc host

struct mmc_host { struct device *parent; struct device class_dev; int index; const struct mmc_host_ops *ops; unsigned int f_min; unsigned int f_max; u32 ocr_avail; unsigned long caps; /* Host capabilities */ /* host specific block data */ unsigned int max_seg_size; /* see blk_queue_max_segment_size */ unsigned short max_hw_segs; /* see blk_queue_max_hw_segments */ unsigned short max_phys_segs; /* see blk_queue_max_phys_segments */ unsigned short unused; unsigned int max_req_size; /* maximum number of bytes in one req */ unsigned int max_blk_size; /* maximum size of one mmc block */ unsigned int max_blk_count; /* maximum number of blocks in one req */ /* private data */ spinlock_t lock; /* lock for claim and bus ops */ struct mmc_ios ios; /* current io bus settings */ u32 ocr; /* the current OCR setting */ /* group bitfields together to minimize padding */ unsigned int use_spi_crc:1; unsigned int claimed:1; /* host exclusively claimed */ unsigned int bus_dead:1; /* bus has been released */ #ifdef CONFIG_MMC_DEBUG unsigned int removed:1; /* host is being removed */ #endif struct mmc_card *card; /* device attached to this host */ wait_queue_head_t wq; struct delayed_work detect; const struct mmc_bus_ops *bus_ops; /* current bus driver */ unsigned int bus_refs; /* reference counter */ unsigned int sdio_irqs; struct task_struct *sdio_irq_thread; atomic_t sdio_irq_thread_abort; #ifdef CONFIG_LEDS_TRIGGERS struct led_trigger *led; /* activity led */ #endif struct dentry *debugfs_root; unsigned long private[0] ____cacheline_aligned; } print debug message 可以用 mmc_hostname(struct mmc_host *host) 印出 %s
ref
  1. http://www.esawdust.com/blog/serial/files/tag-sd.html
  2. http://elm-chan.org/docs/mmc/mmc_e.html
  3. http://www.imhan.com/tag/MMC/
  4. http://www.phpfans.net/article/htmls/201006/Mjg3NzM4.html
  5. http://blog.csdn.net/evilcode/archive/2010/12/16/6079772.aspx
  6. http://zh.wikipedia.org/zh-tw/Secure_Digital
  7. http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf
  8. http://www.hardwarebook.info/SDIO

2010年12月20日 星期一

GPIO Wakeup Detection Register (CWDR) 竟然在 Clock Control Module 章節
新平台,系統的 problem solving time 增加考慮 了解系統 所需的時間,還有 學習 debug 技術的時間。

some notes about wubi

參考 wubi installation guide (https://wiki.ubuntu.com/WubiGuide)
  • wubi 的移除就像是一般 windows ap 移除一樣,在控制台有安裝移除程式。
  • wubi好像不能安裝多個 linux。
  • wubi 是建在 windows filesystem 下,所以 該partition 的 fragmentation會影響效能。推薦用 jkdefrag (http://www.kessels.com/JkDefrag/)
  • 要增加 wubi installed disk 的大小,建議是用 lubi (http://lubi.sourceforge.net/lvpm.html) -- 但是看起來好像是 create 一個 virtual HD,然後用 lubi transfer 過去。-- 建立 virtual driver 是用 qemu 的 tool (在 windows 下)
  • wubi 另外提供一個 ubuntu script,可以同時作到 create virtual box, move home folder to it 兩個動作。 --- 這是 wubu guide 建議用來增加 system space 的方法。

2010年12月17日 星期五

connect adb with android

用 android sdk 的 tools/android 安裝完 真正的 sdk 後。
在 android sdk 目錄會多一個 platform-tool 目錄。裡面就有 adb.

根據 google 的說法, adb 在 linux 不必 driver (用的好像是 mass storage driver)。
但是要手動增加一個 usb event rule : http://developer.android.com/guide/developing/device.html#setting-up 先接上 android 裝置,用 lsusb 看一下 pid。然後寫 (我用的是 10.10)
charles-chang@ubuntu:/etc/udev/rules.d$ cat 51-android.rules SUBSYSTEM=="usb", SYSFS{idVendor}="0bb4", MODE="0666"
接上去後,用 adb device 就會列出 id,然後用 adb shell 就可以連線。

發現這是權限的問題,adb 是使用 scsi,所以 android device 會形成 /dev/sd? 這可以用 dmesg 看出來是哪一個。
第一次使用 adb 時,會啟動一個 daemon,用 ps -aux 可以看到
adb fork-server server
這個 daemon 的 pid 就是你自己 (user)。這個 daemon 需要有對 /dev 下,android device read/write 的權限。
所以,整個作法就是:
插入 android device, dmesg 看一下是 哪一個 device (/dev/sd?),ls -l 看一下 device 的 group 是誰 (floppy),修改 /etc/group,把自己 (user) 加到 floppy group 中。
(重新 login ?)
重新啟動 adb fork-server server: 先 kill 再 invoke:
adb kill-server adb devices
OK
不必加 rules.d

會特別看這篇是因為,我不寫 51-android.rules時,adb device, shell都會 report "permission denied",
即使用 sudo run 也一樣。

* 奇怪的是....Nelson Auron 也都是用 Linux,但是他門就沒有出現這個問題。
而且一但 rules 寫好,成功開啟adb 一次後,刪掉 rules 差拔裝置也OK.\

linux 跟 windows 的 adb push 有一點不一樣。
linux 的 adb push 會保留 file attribute (rwx), windows 不會。
--- 其實這是因為 windows 沒有 rws attribute 的關係。

2010年12月16日 星期四

install android sdk in linux

Downoad 完 android-sdk-r_08-linux_86.tar.gz
解開。

看 SDK readme.txt ===>
run
tool/android
這要 jre 執行,所以要先有 jdk. (sun-java6)

tool/android 會出現 download 真正 sdk 的 UI,設好 connection (proxy) 後,選 "available" 會出現一堆選項。
勾選要的後 就會 download and install

.. 這樣都不用靠 eclipse 來 install 了。




其實這樣很麻煩。
像公司有一堆人要,每個要download 一次,應該要有可以 copy 的方法。

worklog - uboot copy uboot from mmc0 to mmc2

>fatls mmc 0:1 / 把 mmc 0 , partition 1 的 root (/) 內容 list 出來。 lost.dir/ .android_secure/ 159684 u-boot.bin Copy 到 ram 裡: >fatload mmc 0:1 0x90800000 u-boot.bin reading u-boot.bin 159684 bytes read 再 write 到 mmc 2 的 uboot section (start from 1k). > mmc write 2 0x90800000 2 140 MMC write: dev # 2, block # 2, count 320 ... 320 blocks written: OK

jni -- auron's presentation

jni 用 javah 從 java class file 產生 c header (function prototype).
所以 jni 的 function 限制只有 class 可以用。
所以不是類似 linux 一般的 .so 誰都可以用。
實際上要作到 "誰都可以用" 還是在 java class level -- import.

2010年12月15日 星期三

git -- revert some files back to previous rev

git checkout revhash file checkout就版本的file。
然後
git status就會顯示那個file 是modified, 但是 git diff 卻不會顯示出來。
然後用
git reset HEAD file 再 git diff 後,就會顯示出來。



如果是整個 project 都回到以前的某個rev,可以用
git checkout revsha
但是這個狀態,用 git branch 來看,會發現不再認一個 branch ,顯示 (no branch)。
這樣的狀態叫 detach HEAD.
因為不再任一個branch 中,所以commit 的東西將來 checkout 到其他 branch 後,就不見了 (沒辦法merge)。

就和 checkout 時的說明一樣
Note: moving to "v2.6.17" which isn't a local branch If you want to create a new branch from this checkout, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b HEAD is now at 427abfa... Linux v2.6.17 在 detach HEAD 狀態,要把保留的話,要再branch 出去一次。

Terminator -- 多視窗 terminal.

今天看到的:http://kewang.pixnet.net/blog/post/24498084 Terminator 就是可以做出切割視窗的 terminal. 基本command 用 mouse右鍵就可以切割,用Ctrl-Tab 就可以切換。 另外還可以用 Ctrl- 縮小字型。
覺得好用是: ssh 到 building machine 後,開啟上下兩個 window, 上面大一點,vi source,下面的 window 用來 make..

iMX51 : gpio selection

freescale 的 iMX51.
Linux source archive : http://linux-fsl-imx51.sourcearchive.com/
可其中 PAD Multiplex 的設定,可以看到..
/* select I2C1_SCK as daisy chain input */ mxc_request_iomux(MX37_PIN_I2C1_CLK, IOMUX_CONFIG_ALT0); mxc_iomux_set_input(MUX_IN_I2C1_SCL, INPUT_CTL_PATH1); 雖然一個 pin 可以有很多 function 可以選擇,但是選某幾種 function 時,會需要同時設定另一個 register - iomux_set_input 。
這個好像就是 iMX51 GPIO 特有的 daisy chain 架構。
所以在設 PAD Multiplex function 時,要看完 datasheet 有關 該 pin 所有 function 的說明,最後會提到選哪幾個 function 時,要額外設 IOMUXC register.

2010年12月14日 星期二

  • putty -- for serial com
  • ssh-server
  • vim
  • subversion
  • git-core

2010年12月13日 星期一

input - input_event, input_report_xx

根據 input event 的 type, 又包裝成: key, rel, abs, ff_status, switch, sync, mt_sync。 實際上,都只是 包裝 input_event: include/input.h: static inline void input_report_key(struct input_dev *dev, unsigned int code, int value) { input_event(dev, EV_KEY, code, !!value); } static inline void input_report_rel(struct input_dev *dev, unsigned int code, int value) { input_event(dev, EV_REL, code, value); } static inline void input_report_abs(struct input_dev *dev, unsigned int code, int value) { input_event(dev, EV_ABS, code, value); } static inline void input_report_ff_status(struct input_dev *dev, unsigned int code, int value) { input_event(dev, EV_FF_STATUS, code, value); }
input_device 要register 之前,先要把自己的 input capability 設定好,再用 input_register_devie( ) 來註冊。

input capability 包括: input 的 種類 (mouse move, key event ..)。
key 的種類 (keycode. button code..)

有關
keycode 與實體 key 的 mapping ,和 hardware 相關,所以有些 作法會定義在 board driver.

所有的 KEY_XX constant 都定義在 include/linux/input.h
/*
 * Event types
 */

#define EV_SYN                  0x00
#define EV_KEY                  0x01
#define EV_REL                  0x02
#define EV_ABS                  0x03
#define EV_MSC                  0x04
#define EV_SW                   0x05
#define EV_LED                  0x11
#define EV_SND                  0x12
#define EV_REP                  0x14
#define EV_FF                   0x15
#define EV_PWR                  0x16
#define EV_FF_STATUS            0x17
#define EV_MAX                  0x1f
#define EV_CNT                  (EV_MAX+1)


Android 基本的:
  • KEY_MENU : 139
  • KEY_BACK : 158
  • KEY_ENTER : 28
  • 繼續做完 communication with MCU
  • software key input

2010年12月10日 星期五

more on serial programming - termios and read/write raw data

上次 tty (UART) 的測試,結果我丟一個 0x0d, 0x0a ,對方卻收到 0x0d,0x0d,0x0a。 因為tty 會特別處理 控制字元,用 termios structure 可以知道: tty = open("/dev/ttymxc2",O_RDWR | O_NOCTTY | O_NONBLOCK); tcgetattr(tty,&tio); printf("c_oflag:"); if(tio.c_oflag & OPOST){ printf("OPOST "); if( tio.c_oflag & ONLCR) printf("-ONLCR"); if( tio.c_oflag & OCRNL) printf("-OCRNL"); if( tio.c_oflag & ONOCR) printf("-ONOCR"); if( tio.c_oflag & ONLRET) printf("-ONLRET"); printf("\n"); } printf("c_iflag:"); if(tio.c_iflag & IGNBRK) printf("-IGNBRK"); if(tio.c_iflag & BRKINT) printf("-BRKINT"); if(tio.c_iflag & IGNPAR) printf("-IGNPAR"); if(tio.c_iflag & PARMRK) printf("-PARMRK"); if(tio.c_iflag & INPCK) printf("-INPCK"); if(tio.c_iflag & ISTRIP) printf("-ISTRIP"); if(tio.c_iflag & INLCR) printf("-INLCR"); if(tio.c_iflag & IGNCR) printf("-IGNCR"); if(tio.c_iflag & ICRNL) printf("-ICRNL"); if(tio.c_iflag & IUCLC) printf("-IUCLC"); if(tio.c_iflag & IXON) printf("-IXON"); if(tio.c_iflag & IXANY) printf("-IXANY"); if(tio.c_iflag & IXOFF) printf("-IXOFF"); if(tio.c_iflag & IMAXBEL) printf("-IMAXBEL"); printf("\n"); run 的結果是: c_oflag:OPOST -ONLCR c_iflag:-ICRNL-IXON 參考這一篇,有解釋每個 bit field 的意義。 ONLCR - 會把 0x0a 變成 0x0d,0x0a. 所以我要把 OPST 這個 bit clear 掉...
要 read raw data, 參考 這一篇 (Serial Proramming Guide in POSIX System)。 termios 的 lflag 是: options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); 如果是要 output raw data,就只要: options.c_oflag &= ~OPOST; ... 那篇文章最後就有 raw data input/output 的 code: int fd; struct termios options; /* open the port */ fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY); fcntl(fd, F_SETFL, 0); /* get the current options */ tcgetattr(fd, &options); /* set raw input, 1 second timeout */ options.c_cflag |= (CLOCAL | CREAD); options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); options.c_oflag &= ~OPOST; options.c_cc[VMIN] = 0; options.c_cc[VTIME] = 10; /* set the options */ tcsetattr(fd, TCSANOW, &options);
read tty 的動作 (block, no block , wait time, how many bytes.. etc) 是由 c_cc[VMIN], c_cc[VTIME] 的值決定的。 有關 c_cc[] 中 VMIN, VTIME 的功能: (ref : Nonecanonical Input)
  • VMIN : 至少收到多少 bytes 後 return
  • VTIME : 達成 收到 VMIN bytes 的條件後,多少時間 timout 後 return.
所以..
  • c_cc[VMIN], c_cc[VTIME] 的值都是 0 : 有沒有資料都會立刻 return,不過有資料的時候,會把資料都讀出來再return.
  • c_cc[VMIN]=0, c_cc[VTIME] 不是 0 : 等 c_cc[VTIME] 都沒有資料就 return.,如果有收到 data 就立刻 return
  • c_cc[VMIN] 不是 0, c_cc[VTIME] = 0 : 一定要等到收到 c_cc[VMIN] 個資料後才 return.
  • c_cc[VMIN], c_cc[VTIME] 都不是 0 : ..

後來又發現,對方送 0x0d, 0x0a,我收到 0x0a, 0x0a。 確認一下, c_iflag 要 mask 掉 + options.c_iflag &= ~(INLCR | IGNCR | ICRNL); 才行

2010年12月9日 星期四

install flash plugin failed in 10.10

10.10 amd64 在 install flash plugin 時,會出現要去 canonical download gz 檔的時候,沒有辦法 download. 這是因為她沒有看 系統的 proxy 設定。 在 launpad 也有列出這一項..Flash Plugin / Update Manager / PROXY not being honored 解決的方法就是 .... 到沒有 proxy 的地方去裝 XD
..等 install retry 20 次 fail 後,關掉 firefox,在 console 把http_proxy 環境變數設好,然後: sudo bash -c 'eval $(apt-config shell http_proxy Acquire::http::Proxy) dpkg-reconfigure flashplugin-installer' 就會正常經由 proxy download 了。
測試一下10.10 的 ibus 酷音修好了沒。 好像OK了。 但是 什麼 的麼 還是要打二聲 "什麼" 還有 shiff切換中英也沒有 看 這一篇,看來這個shift key 的功能應該不會改了>_< 但是我用caps lock 來切,沒辦法打大寫英文呀!! 喔,切到英文 then press shift to key in UPPER CASE..

git : fast-forward 的意思..

Navie.com 看到的這張圖.

從 devlope branch 出來,commit 三次後 merge 回去...
develope ---O---O----------M----
                \         /
branch            X---X---X
代表 --no-ff 的意思..

在 merge 的時候 (branch merge 進 develope),
如果 develope 沒有任何修改,這被認為是一次 "fast-forward",

所以merge進 develope 時,branch 的三次 commit 記錄 (X--X--X) 會被加進 develope 的 commit log 中,
但是這次 merge 的動作不會被記錄 (也就是上圖的 'M') 不會被記錄:
develope ---O---O---X---X---X----

如果在 merge 時加上 "--no-ff" 在 merge 的時候就會把這個 merge 的動作也記錄下來 (M):
develope ---O---O---X---X---X---M---

2010年12月8日 星期三

serial programming

這一篇
設定 /dev/ttymxc2 (UART3) 為 38400,然後每隔 1 sec 送一個固定的 packet 出去.. #include <stdio.h> #include <termios.h> #include <fcntl.h> void setparameter(void) { int tty; struct termios tio; tty = open("/dev/ttymxc2",O_RDWR | O_NOCTTY | O_NONBLOCK); tcgetattr(tty,&tio); tio.c_cflag = B38400 | CS8 | CLOCAL | CREAD; tcflush(tty,TCIFLUSH); tcsetattr(tty,TCSANOW,&tio); close(tty); } int main(int argc,char *argv[]) { FILE *fd; int i; printf("ttymxc2 bomb\n"); setparameter(); int data[]={0x24,0x06,0x03,0x00,0x0d,0x0a}; fd = fopen("/dev/ttymxc2","w"); // fd = stdin; if(!fd){ printf("open /dev/ttymxc2 failed!!\n"); return 1; } data[3]=data[0]^data[1]^data[2]; data[3] &= 0xFF; while(1){ for(i=0;i<6;i++) fputc(data[i],fd); sleep(1); fprintf(stdout,"%02X %02X %02X %02X %02X %02X\n",data[0],data[1],data[2],data[3],data[4],data[5]); } fclose(fd); return 0; }
然後只要在 init.rc 加上 +# MCU sending service ttymxc2bomb /system/bin/ttymxc2bomb console 就會自動跑起來。
加上 "console" ,就會 把 stdout 放到 console,所以可以看到 message。

--- 麻煩是用 service 啟動的 東西,,,kill 掉後又會自己起來 >_<
--- 好像加一行 oneshot 就可以

2010年12月7日 星期二

qemu, static and sdl

? 原來 QEMU 用 static build 的話,不能 enable-sdl. $./configure --disable-xen --disable-kvm --target-list="i386-softmmu" --enable-sdl 這樣就可以 disable kvm , build 一個可以在 vmware 的 linux 裡 run 的 qemu 了. 為了 build 快一點,所以 用 --target-list 指定,只 build i386-softmmu 就好 build 好會在 i386-softmmu/qemu
有關 git 的說明:
  • create branch
  • merge branch
  • git difftool
  • vimdiff
remote 預計的操作:
  • 如果是 follow git Distribution 的方法,每個人可以開放自己的 working folder ,並且要能夠以 ssh 連接,這樣 host server 就可以 pull 個別 pc 的 code 回來 merge
  • host server merge 完所有的 code
  • 個人 再 pull host server 的 code 回來 merge

built-in.o

好像是有 Makefile 的 folder,依照Makefile 和 Kconfig .config 的內容,會將有用到的 *.o link 成 built-in.o 然後最後 再把所有的 built-in.o link 成 vmlinux built-in.o 的 Make rule 在 scripts/Makefile.build ifdef builtin-target quiet_cmd_link_o_target = LD $@ # If the list of objects to link is empty, just create an empty built-in.o cmd_link_o_target = $(if $(strip $(obj-y)),\ $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^) \ $(cmd_secanalysis),\ rm -f $@; $(AR) rcs $@) $(builtin-target): $(obj-y) FORCE $(call if_changed,link_o_target) targets += $(builtin-target) endif # builtin-target

2010年12月6日 星期一

notes on reading git community book

翻譯一下 git community book
Internals and Plumbing

所有的 objects (是說有被記錄的file 嗎?) 都是以 gzip 壓縮的方式存放,以 他的 sha value 為檔名(?)

git 有兩種保存 object 的方法:
  • Loose Objects : 就整個 rev 的所有 file 的壓縮,會以 sha value 為檔名。為求快速,前兩個 char 會被當做 folder name
  • Packed Objects : 有點像 diff,如果某個 rev 只是另一個 rev 加一個小小的修改,整個ˊ重存一次太浪費空間,所以就會以 diff 跟 base link 的方式存
* packed object 要手動用 git gc 來作,否則都是用 Loose objects 的方式存。

所有的東西都放在 .git/objects 裡。


查看 Objects 的方法...
git 把每一個 file, commit, tree, tag 都當做是一個物件(object) 放在這個folder 裡。
所以.
$find . .git/objects 列出來的每個 object ,都可以用
$git cat-file -t shavalue 來看他是屬於哪一個type.

git 把你目前工作的 base 記錄在 .git/HEAD,可以cat 出來看:
ref: refs/heads/trysquash -- 我現在是checkout trysquash 這個 branch 在工作。

正因為 git 所有的東西(rev, commit, file, tag) 都是以 sha filename 放在 object,
所以剛剛那個 HEAD 的內容,只是指向 objects 中的一個 file。
$cat refs/heads/trysquash 2da4ad933b2079851c37e7334637d745bdfb9c94 看看是什麼type:
$git cat-file -t 2da4 commit 再看一下 commit 的內容 $git cat-file commut 2da4 tree e233040dafb15380a01e73d420143a10d66019f4 parent ce00a162dd739865c16c3fab542fb4c9fa504ac2 author Charles Chang 1291615019 +0800 committer Charles Chang 1291615019 +0800 in trysquash 看一下這次 comit 有哪些東西 $fit ls-tree 2da4 100644 blob d79ded6406430e1ab113a70476fa560d938c9292 f1 只有 f1 這個 file.
也可看這個 file 的內容
$git cat-file blob d79d add new line

Reference

branch, remote-tracking branch (是什麼?) 還有tag 實際上都是 reference 到某一個 commit。
這些 reference 別人的記錄,都是記錄在 git/refs 下,並且每個type 都有一個 folder
$ls .git heads remotes tags
  • git merge -- without commit
  • debug suspend hang on evb -- why my patch cause exception ons suspending
  • small HEX-BIN convert UART program for testing with MCU -- a backup for N.
  • debug the pwr-pin voltage -- work with hardware eng

  • try full linux version -- maybe used in mass-production, fdisk, mkfs,dd

2010年12月3日 星期五

WFI : Wait for Interrupt

ARMv7 增加一個instruction : WFI, opcode 是
.long 0xe320f003 @ Opcode for WFI 因為這個新 instruction 在現在的 GCC 裡面還沒 support,所以可以在很多地方看到這一行 code.(? 是嗎)

WFI 的動作 ref ARM Technical Manual : Wait for Interrupt.
Support WFI 的 chip 有:Which Architecture Support WFI

在 Linux kernel 裡,用這個 instruction 作 suspend. (其實也可以作idle 吧?)

2010年12月2日 星期四

Android -- Suspend (and wakeup ?)

Android 設定 power state 的 function 好像是在: hardware/libhardware_legacy/power/power.c 裡面的 int set_screen_state(int on) { QEMU_FALLBACK(set_screen_state(on)); LOGI("*** set_screen_state %d", on); initialize_fds(); //LOGI("go_to_sleep eventTime=%lld now=%lld g_error=%s\n", eventTime, // systemTime(), strerror(g_error)); if (g_error) return g_error; char buf[32]; int len; if(on) len = sprintf(buf, on_state); else len = sprintf(buf, off_state); len = write(g_fds[REQUEST_STATE], buf, len); if(len < 0) { LOGE("Failed setting last user activity: g_error=%d\n", g_error); } return 0; } 其中的 g_fds[REQUEST_STATE] 就是: enum { ACQUIRE_PARTIAL_WAKE_LOCK = 0, RELEASE_WAKE_LOCK, REQUEST_STATE, OUR_FD_COUNT }; 對應 const char * const NEW_PATHS[] = { "/sys/power/wake_lock", "/sys/power/wake_unlock", "/sys/power/state" }; 也就是 /sys/power/state 寫入 static const char *off_state = "mem"; static const char *on_state = "on";
suspend 就寫 "mem".



使用這個 function 的 source 在 ./frameworks/base/core/jni/android_os_Power.cpp: static int setScreenState(JNIEnv *env, jobject clazz, jboolean on) { return set_screen_state(on); } 這是一個 JNI function,包裝的 class 是: ./frameworks/base/core/java/android/os/Power.java
使用的 class 是 ./frameworks/base/services/java/com/android/server/PowerManagerService.java



kernel 層對應 /sys/power/state 的 device 是 kernel/power/main.c

對 /sys/power/state的 read/write 對應有點.. #define power_attr(_name) \ static struct kobj_attribute _name##_attr = { \ .attr = { \ .name = __stringify(_name), \ .mode = 0644, \ }, \ .show = _name##_show, \ .store = _name##_store, \ } 在 main.c 中: power_attr(state); 所以要找 state_store:
state_store( ) 會把 write 到 /sys/power/state 和 support 的 power state 比較,下面是suspend 的 state : (suspend.c) const char *const pm_states[PM_SUSPEND_MAX] = { #ifdef CONFIG_EARLYSUSPEND [PM_SUSPEND_ON] = "on", #endif [PM_SUSPEND_STANDBY] = "standby", [PM_SUSPEND_MEM] = "mem", }; 然後call enter_state(state) -- state 就是 pm_states[] 對應的index。

這個在 suspend.c: int enter_state(suspend_state_t state) { int error; if (!valid_state(state)) return -ENODEV; if (!mutex_trylock(&pm_mutex)) return -EBUSY; printk(KERN_INFO "PM: Syncing filesystems ... "); sys_sync(); printk("done.\n"); pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]); error = suspend_prepare(); if (error) goto Unlock; if (suspend_test(TEST_FREEZER)) goto Finish; pr_debug("PM: Entering %s sleep\n", pm_states[state]); error = suspend_devices_and_enter(state); Finish: pr_debug("PM: Finishing wakeup.\n"); suspend_finish(); Unlock: mutex_unlock(&pm_mutex); return error; } 可以看到 .. suspend_device_and_enter(state);
然後是,. suspend_finish( );

上面的 debug message 是.. PM:Finishing wakeup.
所以 在 suspend_device_and_enter( ) 後,cpu 應該就進入 suspend state。
一直到有 wakeup event 後,才會wakeup 起來,繼續執行.. suspend_finish().



但是 user program 寫入 /sys/power/state 和 kernel/power/main.c 的執行沒有同步 (?)。
所以 user program 不知道在什麼時候停住。 (?)



suspend_enter( ) 實際作 cpu suspend 的動作是靠
static struct platform_suspend_ops *suspend_ops; 的 ops interface 來完成的。

這個變數是呼叫
void suspend_set_ops(struct platform_suspend_ops *ops) { mutex_lock(&pm_mutex); suspend_ops = ops; mutex_unlock(&pm_mutex); } 完成的,每個 platform 都會實作呼叫這個 function 的 code.
所以在 arch/ 下面的code 可以找到很多..
例如 arch/arm/mach-xxx/pm.c

platform 為了作 suspend,通常會 copy 最後一段的 code 到 internal ram 中,再跳過去執行,然後把 DRAM 設為 self-fresh mode,然後停止 clock.


ref: http://hi.baidu.com/linuxembedded/blog/item/4eeb143837879bd2d46225ca.html

2010年12月1日 星期三

Android - key input , touch input

framework/base/lib/ui/EventHub.cpp: static const char *device_path = "/dev/input"; 然後 .. scan_device(device_path) scan_device 找所有 /dev/input 下面的 node int EventHub::scan_dir(const char *dirname) { char devname[PATH_MAX]; char *filename; DIR *dir; struct dirent *de; dir = opendir(dirname); if(dir == NULL) return -1; strcpy(devname, dirname); filename = devname + strlen(devname); *filename++ = '/'; while((de = readdir(dir))) { if(de->d_name[0] == '.' && (de->d_name[1] == '\0' || (de->d_name[1] == '.' && de->d_name[2] == '\0'))) continue; strcpy(filename, de->d_name); open_device(devname); } closedir(dir); return 0; } 呼叫 open_device,把 node 加到 mFD[] 中。
在 kernel 的部份, /dev/input 是由 /driver/input/input.c 註冊的: static int __init input_init(void) { int err; input_init_abs_bypass(); err = class_register(&input_class); if (err) { printk(KERN_ERR "input: unable to register input_dev class\n"); return err; } err = input_proc_init(); if (err) goto fail1; err = register_chrdev(INPUT_MAJOR, "input", &input_fops); if (err) { printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR); goto fail2; } return 0; fail2: input_proc_exit(); fail1: class_unregister(&input_class); return err; }
最上層 EventHub.cpp 中,poll input device 的 function : bool EventHub::getEvent 用 bionic -- libc 的 poll function .. release_wake_lock(WAKE_LOCK_ID); pollres = poll(mFDs, mFDCount, -1); acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); if (pollres <= 0) { if (errno != EINTR) { LOGW("select failed (errno=%d)\n", errno); usleep(100000); } continue; } //printf("poll %d, returned %d\n", mFDCount, pollres); // mFDs[0] is used for inotify, so process regular events starting at mFDs[1] for(i = 1; i < mFDCount; i++) { ...... 一次poll所有的 input device,timeout 是 -1 ,所以是 block。 也就是說,要任一個 device 有資料才 return. 然後...判斷 有 update 的 device,read data: if(mFDs[i].revents & POLLIN) { res = read(mFDs[i].fd, &iev, sizeof(iev)); iev 內容就是 keyscan code.


touch 的 interface 也在這裡。

more on git remote repository

作 repo 的 local mirror 的時候有點奇怪。
要修改 .repo/manifest.xml

但是用 repo --mirror init/sync 的 repo 目錄,沒有辦法直接修改 (就跟用 git clone --bare 的目錄內容沒有辦法值些修改 source / 找不到 source)。

所以就要 先在其他地方 repo init ,這樣就 'checkout' 出 .repo 。
然後手動修改 .repo/manifest.xml
然後再 repo sync



git 要在 remote repository 上 create branch 要用
git push <server-name> <local-branch-name>:<remote-branch-name> 方法是把一個 local 的 branch/commit push 進 remote repository。
所以,這個命令要在某一個 workable 的 git project 下作。

標籤

網誌存檔