1. server 端的管理
2. 整合driver至平台
3. 整合framework,撰寫ap與library
2010年3月31日 星期三
台中鐵馬路線規劃
1. 參考網頁: http://www.mobile01.com/topicdetail.php?f=320&t=461940&p=2
2. 太平市自行車道: http://www.mobile01.com/topicdetail.php?f=377&t=997674
3. 中正露營區: http://www.mobile01.com/topicdetail.php?f=377&t=824959&r=2&last=10350887
4. 須取回之零件:
輪胎*2
踏板 *2
龍頭 *1
手把 *2
碼表發射器 *1
鍊條 *1
飛輪 *1
大盤護蓋*1
後變速器*1
磁鐵 *2
立管*1
2. 太平市自行車道: http://www.mobile01.com/topicdetail.php?f=377&t=997674
3. 中正露營區: http://www.mobile01.com/topicdetail.php?f=377&t=824959&r=2&last=10350887
4. 須取回之零件:
輪胎*2
踏板 *2
龍頭 *1
手把 *2
碼表發射器 *1
鍊條 *1
飛輪 *1
大盤護蓋*1
後變速器*1
磁鐵 *2
立管*1
2010年3月30日 星期二
2010年3月27日 星期六
jk24210開發版實作練習
1. 記得先關閉防火牆,設定static ip,以系統管理員模式開啟tftp軟體。
2. JK2410開發版BSP有特定的API可以使用 Ex: set_external_irq( )
3. 重要檔案 : kernel-jk2410/include/asm-arm/arch-s3c2410/irqs.h => 定義外部中斷 (IRQ_EINT4 => S0, IRQ_EINT11 => S6)
4. request_irq為kernel提供的標準API。
5. 測試GPIO前的準備: 先 echo or cat 裝置檔,過程中會去open 裝置檔,之後便可以收到外部中斷(open system call 中必須要implement irq的功能)。
6. make rootfs 兩個Makefile需要修改(/jk2410-make-rootfs , /jk2410-make-rootfs/rootfs/)。
7. 一般習慣一次將多個byte寫入kernel , 而非一次一個byte,減少system time(cpu 中斷 -> system call ->return to user process ) 的花費。
8. 試著設計一些題目(修改外部中斷, 排程機制的on board練習)
9. 練習題: 由ap寫data進driver,buffer滿了之後會讓process 去sleep, 按下S6按鍵之後會印出訊息或撥放音樂。
10. 測試一下當只改變狀態並呼叫schedule()而不將current process 放入wait_queue的系統行為。
11. 開發版的audio system 架構 (由下到上): OSS -> liibmad -> application , AP透過外部程式存取device file (/dev/dsp) 來使用OSS driver 。
12. 進行kernel編譯時 (*) 代表build-in 至 kernel 中, 在開機中會自動產生裝置檔。
13. arnix 提供之layer architechre (由上往下): test.c -> madplay -> libmad -> /dev/dsp -> kernel audio driver (OSS)
14. audio driver 練習題 1:
(a) 實做blocking read 當 ap 執行 read 後 forground process put to sleep
(b) 當按下S6按鈕之後,啟動interrupt handler 將process wake up
(c) 往下執行到外部程式即可撥放音樂
(d) 使用mmap將data register mapping to user space 直接控制LED燈
參考說明: http://www.jollen.org/wiki/MP3_Player
15. 開發版 ip 設定參考: http://hi.baidu.com/lozn/blog/item/411f5caf1a053ffafbed504d.html
16. libmad如何porting到開發版? p.s. 查閱jollen wiki
17. 思考為何在播放音樂時,按下S6還是會執行interrupt handler ? 由於此時應用程式還在執行中尚未結束,此時出現外部中斷系統還是會叫起cdata-gpio的中斷,而該操作並沒有意義,因為forground process 並未sleep 且已被madplay 取代掉了。(以上為猜測)
18. 題目2 LED顯示(1~9) 2進制燈號,http://www.jollen.org/wiki/JK2410_LED
19. 寫ap 為結構化程式設計,可以用流程圖分析function call flow,與driver 必須留意OS狀態不同,寫driver = (ap + OS kernel module)。
20. cdata-gpio.c 當中,若write超過64個字元時,會先啟動timer_function(5秒後執行),將current process put to sleep ,此時可接收外部中斷(目前沒有實作有意義的操作),直到timer_function啟動 -> fail2 -> return to forground (猜測) -> 結束。
21 S3c2410 硬體說明: http://blog.ednchina.com/thinkker/29056/category.aspx
22. LED實驗中,在bootloader中下mw.l 0x56000014 0xbff 1 發現LED1不會亮! (參考25.)
mw.l 0x56000010 0x00154000 1 => LED 會全亮。 l : 4個 byte w: 2個 byte b: 1個byte
23. OS中不允許driver直接存取實體位址 => 使用 led = ioremap(0x56000014,4) 透過led變數 indirect 去存取實體位址。
24. cdata2 write to LED 中的程式可以寫在 init_module()中。
25. LED 功能確實啟動的兩個步驟: (1) 先設定好GPBCON register (0x56000010)指定LED1~LED4與CPU之間的PIN腳為輸出Mode (2) 設定GPBDAT register (0x56000014)指定欲亮的LED,GPBDAT為DATA Register。
26. LED練習題: 寫入4個數字,並假設Buffer 此時已滿,使用kernel timer 每1秒鐘顯示1個數字出來,並將10進制換成2進制輸出於LED上,在timer function 中也會將process wake up。
27. 進階練習: 當按下按鈕一次,LED顯示按了幾次對應的數字。 p.s. 寫ap可以讀取GPIO,紀錄按鍵被按下的次數。
28. 如何將自己的driver整合到kernel當中: http://www.jollen.org/wiki/JK2410_merge_a_new_driver_into_kernel
29. 測試 writel(0x87f,led) 是否也可以使LED全亮?可以!
30. 出現 bug: kernel timer added twice at c000bfffb4 記得檢查是否漏掉初始化kernel timer的步驟!
31. (銜接26.)撰寫 write_led() : 提供依輸入數字並將數字顯示到LED的功能。
led_timer(): 每秒鐘輸出一個數字,在idx為0之後結束計數功能。
32. RAM與I/O MEM差別在於RAM可以存放DATA!
33. 一般ARM/RISC 處理器的記憶體位址配置: 0X30000000~0X34000000 FOR RAM
0X34000000以上 FOR I/O MEM
34. 名詞定義: X86 -> VideoRam RISC -> Framebuffer 兩者所指的是同一個LCD Panel 。
35. 可以藉由設計bootloader 或 driver 來定義好 配置給 framebuffer 的記憶體空間(for JK2410開發版 在RAM區間中,33F00000~34000000 300KB的範圍)。
36. 將圖片檔案放入Framebuffer則能在panel上看到圖片被顯示出來。
37. mw.l 33f00000 0x00ff0000 0x12c00畫紅色於整片panel,0x12c00代表點數,1 pixel為 4個 byte 所以用 mw.l,在driver開發中還是要記得不要直接存取實體記憶體位址。
38. for JK2410開發版panel 320*240*4kB(per pixel) ~= 300KB
39. 一般拿到開發版寫driver的工程師須了解以下資訊:
(1) 中斷處理
(2) I/O MEM (frame buffer)
(3) RAM
40. 試著用小畫家,做一張320*240的圖,開機時用tftp 放到 frame buffer 中(有風險性)。
41. 開啟frame buffer driver 後編譯出現error ,vgacon:290 'PCIMEM_BASE' undeclared (first use in this function) => 已解決安裝 patch即可!
42. 為何kernel 中的frame buffer driver即使不打開也可以work ? 因為在bootloader中已經設定過LCD controller 。
43. 設定bootargs 中mem=60M 使得kernel 不會在開機時再去使用到framebuuffer 的空間了!(初始設定下 frame buffer 的空間會在60~64M之間) ,之後若需要存取frame buffer 的空間則須參考存取I/O Memory的方法來做。
44. Linux system 在開機階段會將 root filesystem壓縮檔放入設定好的memory addr (0x30f00000)當中,解壓縮之後檔案會往後長(addr 0x33f0000)。
45. 編譯file system時,若發生error時,記得先將資料備份好,將jk2410-make-rootfs資料夾整個刪除,若rootfs無法刪除,則重開機後再刪掉即可!
46. request_irq() 應該寫在cdata_open(),還是cdata_init_module()中? 參考網址 : http://www.jollen.org/wiki/Hardware_shared_interrupt_and_software_shared_interrupt
47. (承接43.) 練習題: 在kernel space 利用 ioremap() ,存取frame buffer 在panel 上畫圖,不過正式的driver並不會這樣實作,畫圖的功能一定是由ap發起。
48. 實作mmap system call 讓ap可以存取frame buffer,先前於IPC應用上也有使用到mmap()的功能。
49. 在kernel中fb指標會指向0x30f00000,在user space mapping virtual address 有2個階段: (1) phy addr -> kernel virtual adde (2) kernel virtual addr -> user virtual addr。
50. android 系統也是使用direct framebuffer ,可以在ap層直接存取frame buffer。
51. /dev/fb/0 為kernel 內建的frame buffer driver 內部已實作mmap功能可以直接使用!
52. 不要使用程式語言特性去實作,而要利用OS提供的function去實作功能。
53. 4/2 發現showmmap 測試程式無法開啟 /dev/fb/0!
54. 更新jk2410測試程式: http://code.google.com/p/jk2410-codesuite/source/checkout
55. cdata-0.4的範例,testm.c中的操作會造成 kernel panic 的現象發生!
56. 希望driver在kernel/系統開機的狀況下自動進行註冊,只需在driver/char/中修改Makefile即可。
57. 任何application 存取I/O時,都需要使用mmap這個system call,這個nterface必須由driver寫作者自行實作。
58. 利用svn工具 下載lcd_demo程式,測試lcd driver的功能。
59. 測試程式(在init_module時註冊interrupt handler)會出現kernel panic狀況! http://www.jollen.org/wiki/JK2410_shared_interrupt
60. embedded system (非X86系統)中由於GPIO PIN腳多,故較不實作share IRQ。
61. 期末測驗: (1) cdata_led.c <= buffer 滿了之後會將輸入的數字output出去。 (2) mknod 與 install driver 可以寫入 init.rc中在開機後就自動做好(參考wiki 做法)。
62. 講義(二)p.160 由user space 執行mmap 將 user space 的記憶體空間與kernel space 的page table 做mapping ,結果將user space 的記憶體空間對應至I/O MEM。
63. reserved pages 為MMU無法管理到的記憶體區間。
64. GPIO測試方法: case1:先open裝置檔,再做fork()讓兩個process都會去讀取該裝置檔,觀察driver是否有異常 case2: 針對同一裝置檔執行2次open。
65. User-space driver and process race condiction: http://www.jollen.org/wiki/User-space_driver_and_process_race_condition
2. JK2410開發版BSP有特定的API可以使用 Ex: set_external_irq( )
3. 重要檔案 : kernel-jk2410/include/asm-arm/arch-s3c2410/irqs.h => 定義外部中斷 (IRQ_EINT4 => S0, IRQ_EINT11 => S6)
4. request_irq為kernel提供的標準API。
5. 測試GPIO前的準備: 先 echo or cat 裝置檔,過程中會去open 裝置檔,之後便可以收到外部中斷(open system call 中必須要implement irq的功能)。
6. make rootfs 兩個Makefile需要修改(/jk2410-make-rootfs , /jk2410-make-rootfs/rootfs/)。
7. 一般習慣一次將多個byte寫入kernel , 而非一次一個byte,減少system time(cpu 中斷 -> system call ->return to user process ) 的花費。
8. 試著設計一些題目(修改外部中斷, 排程機制的on board練習)
9. 練習題: 由ap寫data進driver,buffer滿了之後會讓process 去sleep, 按下S6按鍵之後會印出訊息或撥放音樂。
10. 測試一下當只改變狀態並呼叫schedule()而不將current process 放入wait_queue的系統行為。
11. 開發版的audio system 架構 (由下到上): OSS -> liibmad -> application , AP透過外部程式存取device file (/dev/dsp) 來使用OSS driver 。
12. 進行kernel編譯時 (*) 代表build-in 至 kernel 中, 在開機中會自動產生裝置檔。
13. arnix 提供之layer architechre (由上往下): test.c -> madplay -> libmad -> /dev/dsp -> kernel audio driver (OSS)
14. audio driver 練習題 1:
(a) 實做blocking read 當 ap 執行 read 後 forground process put to sleep
(b) 當按下S6按鈕之後,啟動interrupt handler 將process wake up
(c) 往下執行到外部程式即可撥放音樂
(d) 使用mmap將data register mapping to user space 直接控制LED燈
參考說明: http://www.jollen.org/wiki/MP3_Player
15. 開發版 ip 設定參考: http://hi.baidu.com/lozn/blog/item/411f5caf1a053ffafbed504d.html
16. libmad如何porting到開發版? p.s. 查閱jollen wiki
17. 思考為何在播放音樂時,按下S6還是會執行interrupt handler ? 由於此時應用程式還在執行中尚未結束,此時出現外部中斷系統還是會叫起cdata-gpio的中斷,而該操作並沒有意義,因為forground process 並未sleep 且已被madplay 取代掉了。(以上為猜測)
18. 題目2 LED顯示(1~9) 2進制燈號,http://www.jollen.org/wiki/JK2410_LED
19. 寫ap 為結構化程式設計,可以用流程圖分析function call flow,與driver 必須留意OS狀態不同,寫driver = (ap + OS kernel module)。
20. cdata-gpio.c 當中,若write超過64個字元時,會先啟動timer_function(5秒後執行),將current process put to sleep ,此時可接收外部中斷(目前沒有實作有意義的操作),直到timer_function啟動 -> fail2 -> return to forground (猜測) -> 結束。
21 S3c2410 硬體說明: http://blog.ednchina.com/thinkker/29056/category.aspx
22. LED實驗中,在bootloader中下mw.l 0x56000014 0xbff 1 發現LED1不會亮! (參考25.)
mw.l 0x56000010 0x00154000 1 => LED 會全亮。 l : 4個 byte w: 2個 byte b: 1個byte
23. OS中不允許driver直接存取實體位址 => 使用 led = ioremap(0x56000014,4) 透過led變數 indirect 去存取實體位址。
24. cdata2 write to LED 中的程式可以寫在 init_module()中。
25. LED 功能確實啟動的兩個步驟: (1) 先設定好GPBCON register (0x56000010)指定LED1~LED4與CPU之間的PIN腳為輸出Mode (2) 設定GPBDAT register (0x56000014)指定欲亮的LED,GPBDAT為DATA Register。
26. LED練習題: 寫入4個數字,並假設Buffer 此時已滿,使用kernel timer 每1秒鐘顯示1個數字出來,並將10進制換成2進制輸出於LED上,在timer function 中也會將process wake up。
27. 進階練習: 當按下按鈕一次,LED顯示按了幾次對應的數字。 p.s. 寫ap可以讀取GPIO,紀錄按鍵被按下的次數。
28. 如何將自己的driver整合到kernel當中: http://www.jollen.org/wiki/JK2410_merge_a_new_driver_into_kernel
29. 測試 writel(0x87f,led) 是否也可以使LED全亮?可以!
30. 出現 bug: kernel timer added twice at c000bfffb4 記得檢查是否漏掉初始化kernel timer的步驟!
31. (銜接26.)撰寫 write_led() : 提供依輸入數字並將數字顯示到LED的功能。
led_timer(): 每秒鐘輸出一個數字,在idx為0之後結束計數功能。
32. RAM與I/O MEM差別在於RAM可以存放DATA!
33. 一般ARM/RISC 處理器的記憶體位址配置: 0X30000000~0X34000000 FOR RAM
0X34000000以上 FOR I/O MEM
34. 名詞定義: X86 -> VideoRam RISC -> Framebuffer 兩者所指的是同一個LCD Panel 。
35. 可以藉由設計bootloader 或 driver 來定義好 配置給 framebuffer 的記憶體空間(for JK2410開發版 在RAM區間中,33F00000~34000000 300KB的範圍)。
36. 將圖片檔案放入Framebuffer則能在panel上看到圖片被顯示出來。
37. mw.l 33f00000 0x00ff0000 0x12c00畫紅色於整片panel,0x12c00代表點數,1 pixel為 4個 byte 所以用 mw.l,在driver開發中還是要記得不要直接存取實體記憶體位址。
38. for JK2410開發版panel 320*240*4kB(per pixel) ~= 300KB
39. 一般拿到開發版寫driver的工程師須了解以下資訊:
(1) 中斷處理
(2) I/O MEM (frame buffer)
(3) RAM
40. 試著用小畫家,做一張320*240的圖,開機時用tftp 放到 frame buffer 中(有風險性)。
41. 開啟frame buffer driver 後編譯出現error ,vgacon:290 'PCIMEM_BASE' undeclared (first use in this function) => 已解決安裝 patch即可!
42. 為何kernel 中的frame buffer driver即使不打開也可以work ? 因為在bootloader中已經設定過LCD controller 。
43. 設定bootargs 中mem=60M 使得kernel 不會在開機時再去使用到framebuuffer 的空間了!(初始設定下 frame buffer 的空間會在60~64M之間) ,之後若需要存取frame buffer 的空間則須參考存取I/O Memory的方法來做。
44. Linux system 在開機階段會將 root filesystem壓縮檔放入設定好的memory addr (0x30f00000)當中,解壓縮之後檔案會往後長(addr 0x33f0000)。
45. 編譯file system時,若發生error時,記得先將資料備份好,將jk2410-make-rootfs資料夾整個刪除,若rootfs無法刪除,則重開機後再刪掉即可!
46. request_irq() 應該寫在cdata_open(),還是cdata_init_module()中? 參考網址 : http://www.jollen.org/wiki/Hardware_shared_interrupt_and_software_shared_interrupt
47. (承接43.) 練習題: 在kernel space 利用 ioremap() ,存取frame buffer 在panel 上畫圖,不過正式的driver並不會這樣實作,畫圖的功能一定是由ap發起。
48. 實作mmap system call 讓ap可以存取frame buffer,先前於IPC應用上也有使用到mmap()的功能。
49. 在kernel中fb指標會指向0x30f00000,在user space mapping virtual address 有2個階段: (1) phy addr -> kernel virtual adde (2) kernel virtual addr -> user virtual addr。
50. android 系統也是使用direct framebuffer ,可以在ap層直接存取frame buffer。
51. /dev/fb/0 為kernel 內建的frame buffer driver 內部已實作mmap功能可以直接使用!
52. 不要使用程式語言特性去實作,而要利用OS提供的function去實作功能。
53. 4/2 發現showmmap 測試程式無法開啟 /dev/fb/0!
54. 更新jk2410測試程式: http://code.google.com/p/jk2410-codesuite/source/checkout
55. cdata-0.4的範例,testm.c中的操作會造成 kernel panic 的現象發生!
56. 希望driver在kernel/系統開機的狀況下自動進行註冊,只需在driver/char/中修改Makefile即可。
57. 任何application 存取I/O時,都需要使用mmap這個system call,這個nterface必須由driver寫作者自行實作。
58. 利用svn工具 下載lcd_demo程式,測試lcd driver的功能。
59. 測試程式(在init_module時註冊interrupt handler)會出現kernel panic狀況! http://www.jollen.org/wiki/JK2410_shared_interrupt
60. embedded system (非X86系統)中由於GPIO PIN腳多,故較不實作share IRQ。
61. 期末測驗: (1) cdata_led.c <= buffer 滿了之後會將輸入的數字output出去。 (2) mknod 與 install driver 可以寫入 init.rc中在開機後就自動做好(參考wiki 做法)。
62. 講義(二)p.160 由user space 執行mmap 將 user space 的記憶體空間與kernel space 的page table 做mapping ,結果將user space 的記憶體空間對應至I/O MEM。
63. reserved pages 為MMU無法管理到的記憶體區間。
64. GPIO測試方法: case1:先open裝置檔,再做fork()讓兩個process都會去讀取該裝置檔,觀察driver是否有異常 case2: 針對同一裝置檔執行2次open。
65. User-space driver and process race condiction: http://www.jollen.org/wiki/User-space_driver_and_process_race_condition
review 從變動中創造財富
1. 擦鞋童理論: http://tw.myblog.yahoo.com/jw!MsrgfAWBHwTCw9iDYKv_qA0X/article?mid=2809
2. 融資餘額代表什麼意義? 是進場信號,或者退場?
3. 日本股神士川銀藏透過物價變動前巧妙收購大量物資,迅速獲取高額利潤的做法,關鍵在於看出需求面的出現,因此在市場需求增加前,保握了絕佳的進場時間。
4. 3低2高 => 低基期 , 低股價 , 以低本益比; 高成本, 高殖利率。
5. 挑選長期穩定基金的指標: (1)4433法則 (2)晨星5顆星 (3)理柏Leader指標 。
2. 融資餘額代表什麼意義? 是進場信號,或者退場?
3. 日本股神士川銀藏透過物價變動前巧妙收購大量物資,迅速獲取高額利潤的做法,關鍵在於看出需求面的出現,因此在市場需求增加前,保握了絕佳的進場時間。
4. 3低2高 => 低基期 , 低股價 , 以低本益比; 高成本, 高殖利率。
5. 挑選長期穩定基金的指標: (1)4433法則 (2)晨星5顆星 (3)理柏Leader指標 。
2010年3月25日 星期四
Linux Kernel Module
1. kernel symbol table: for linux kernel 2.6 is under /proc/kallsyms ,呈現globe variable 與 globe function 與位址的對應表格。
2. insmod 與 modprobe指令均可安裝kernel module但insmod 必須自行安裝其他有相依性的模組(EX : video4linux 為Linux kernel 支援影像裝置的API,架構分為上下兩層,上層為video4linux本身(videodev module),下層為bttv模組 ,模組間具有關聯性)。
2. insmod 與 modprobe指令均可安裝kernel module但insmod 必須自行安裝其他有相依性的模組(EX : video4linux 為Linux kernel 支援影像裝置的API,架構分為上下兩層,上層為video4linux本身(videodev module),下層為bttv模組 ,模組間具有關聯性)。
2010年3月24日 星期三
Semaphone 觀念 & Pthread Programing
1.
if(semaphone){
critical section (放置需保護的資料)
}
2. thread可分為user thread(POSIX thread) 與 kernel thread兩種
3. 寫multi thread 的程式時,編譯記得加上 -lpthread
4. pthread_create(thread_id, thread_attr, thread_func, thread_argu) 其中:
thread_argu為傳遞給thread func 的參數
thread_id 為指向thread_id的指標
thread_func 為指向therad function 的指標 資料型別為 (void *)
thread_attr 指向thread attribute 的指標 NULL 則表示create出來的thread為joinable Thread
5. join Thread 機制可以確保thread 執行的工作要先完成,後續的process/thread才會往下執行。
6. join_thread2.c 編譯執行後會出現 segmentation fault !
7. join_thread3.c 中示範如何讓process與thread依照期望的順序執行完成,在thread中亦可妥善利用pthread_join() 做等待(特定thread工作結束)。
8. Pthread programing 練習: https://computing.llnl.gov/tutorials/pthreads/
9. GNI/Linux 實做的semaphones可以分為 :
thread semaphones
process semaphones
10. Semaphores 使用方式:
Semaphones S ; // 初始化變數S, 一般設定為'1'
P(S); //wait operation
EnterCriticalSection();
V(S); // post operation
11. Race Condition 發生在以下2種情況下
(1) 多個process同時concurrent執行且共用相同資源(EX:同一個結構變數)
(2) 在多工與分時系統下會產生,因程式碼執行順序而出現的競賽問題
12. (猜測)semaphones 可以分為:
kernel semaphones : 呼叫 sem_init()初始化
down_interruptable();
{
critical section
}
up();
user semaphones: 呼叫sema_init()初始化
sem_wait();
{
critical section
}
sem_post();
13. 不能在critical section 中直接呼叫 sleep(造成deadlock) , 試著思考為什麼? 因為Atomic特性,不能有停頓出現在critical section。
14. 利用程式碼特性善用區域變數,最後處理完的結果用semaphore保護起來放到,減少semaphore的使用次數
15. 思考 先 open() 再 fork() 跟先fork() 再 open() 的差別在哪? 先open 再 fork的話,parent 與 child process 會共用同一個struct file 的資源。
16. 實做sleep_on 的簡單步驟:
(1) init_waitqueue_entry()
(2) add_waitqueue
(3) current->state = TASK_INTERRUPTIBLE
(4) schedule() // 在critical section外呼叫
17. taskqueue 用於對function進行排程時使用,為進化版的kernel timer,linux kernel 2.6 進化為workqueue,具體做法: queue_task(&cdata->cdata_tq,&tq_timer)。
18. kernel thread 也可以被排程(需特別將kernel thread丟到queue中),形成具有time slice 的kernel space function
19. 在critical section 中,還是可以接收硬體的中斷(猜測),而sleep則不允許!
20. mutex,semapores , spin-lock的差別在哪? spin-lock為driver另一組semaphone函數(busy loop/waiting) ,用於中斷模式下使用, semaphores則是先讓user space process 去 sleep。
21. down, up 函數是使用wait queue做等待(用於等待時間長) <-> spin-lock 用 busy loop方式做等待(用於等待時間短)
22. 單處理器不會出現P進入critical section 而 Q在外面等待的情況,SMP則會出現!所以在單處器使用semaphores / spin-lock 比較沒有意義,但建議還是加上去。
23. linux 2.4 kernel 中有變化型的spin-lock可以在critical section 下關閉外部中斷。
24. hold semaphores
25. 留意 linux 2.4 kernel底下的driver , 其 spin-lock的實作是空的。
26. spin-lock在多處理器才有意義, 2.4 kernel不支援ARM的多核心處理器(猜測)。
27. 在單處理器的架構之下,並不會P停下來後Q並不會在semaphores外面等待,而是否會有同步問題則需看實做的架構而定(基本上還是會出現同步問題)。
28. semaphores 系列函數: down , up
spin-lock系列函數: spin_lock , spin_unlock
if(semaphone){
critical section (放置需保護的資料)
}
2. thread可分為user thread(POSIX thread) 與 kernel thread兩種
3. 寫multi thread 的程式時,編譯記得加上 -lpthread
4. pthread_create(thread_id, thread_attr, thread_func, thread_argu) 其中:
thread_argu為傳遞給thread func 的參數
thread_id 為指向thread_id的指標
thread_func 為指向therad function 的指標 資料型別為 (void *)
thread_attr 指向thread attribute 的指標 NULL 則表示create出來的thread為joinable Thread
5. join Thread 機制可以確保thread 執行的工作要先完成,後續的process/thread才會往下執行。
6. join_thread2.c 編譯執行後會出現 segmentation fault !
7. join_thread3.c 中示範如何讓process與thread依照期望的順序執行完成,在thread中亦可妥善利用pthread_join() 做等待(特定thread工作結束)。
8. Pthread programing 練習: https://computing.llnl.gov/tutorials/pthreads/
9. GNI/Linux 實做的semaphones可以分為 :
thread semaphones
process semaphones
10. Semaphores 使用方式:
Semaphones S ; // 初始化變數S, 一般設定為'1'
P(S); //wait operation
EnterCriticalSection();
V(S); // post operation
11. Race Condition 發生在以下2種情況下
(1) 多個process同時concurrent執行且共用相同資源(EX:同一個結構變數)
(2) 在多工與分時系統下會產生,因程式碼執行順序而出現的競賽問題
12. (猜測)semaphones 可以分為:
kernel semaphones : 呼叫 sem_init()初始化
down_interruptable();
{
critical section
}
up();
user semaphones: 呼叫sema_init()初始化
sem_wait();
{
critical section
}
sem_post();
13. 不能在critical section 中直接呼叫 sleep(造成deadlock) , 試著思考為什麼? 因為Atomic特性,不能有停頓出現在critical section。
14. 利用程式碼特性善用區域變數,最後處理完的結果用semaphore保護起來放到,減少semaphore的使用次數
15. 思考 先 open() 再 fork() 跟先fork() 再 open() 的差別在哪? 先open 再 fork的話,parent 與 child process 會共用同一個struct file 的資源。
16. 實做sleep_on 的簡單步驟:
(1) init_waitqueue_entry()
(2) add_waitqueue
(3) current->state = TASK_INTERRUPTIBLE
(4) schedule() // 在critical section外呼叫
17. taskqueue 用於對function進行排程時使用,為進化版的kernel timer,linux kernel 2.6 進化為workqueue,具體做法: queue_task(&cdata->cdata_tq,&tq_timer)。
18. kernel thread 也可以被排程(需特別將kernel thread丟到queue中),形成具有time slice 的kernel space function
19. 在critical section 中,還是可以接收硬體的中斷(猜測),而sleep則不允許!
20. mutex,semapores , spin-lock的差別在哪? spin-lock為driver另一組semaphone函數(busy loop/waiting) ,用於中斷模式下使用, semaphores則是先讓user space process 去 sleep。
21. down, up 函數是使用wait queue做等待(用於等待時間長) <-> spin-lock 用 busy loop方式做等待(用於等待時間短)
22. 單處理器不會出現P進入critical section 而 Q在外面等待的情況,SMP則會出現!所以在單處器使用semaphores / spin-lock 比較沒有意義,但建議還是加上去。
23. linux 2.4 kernel 中有變化型的spin-lock可以在critical section 下關閉外部中斷。
24. hold semaphores
25. 留意 linux 2.4 kernel底下的driver , 其 spin-lock的實作是空的。
26. spin-lock在多處理器才有意義, 2.4 kernel不支援ARM的多核心處理器(猜測)。
27. 在單處理器的架構之下,並不會P停下來後Q並不會在semaphores外面等待,而是否會有同步問題則需看實做的架構而定(基本上還是會出現同步問題)。
28. semaphores 系列函數: down , up
spin-lock系列函數: spin_lock , spin_unlock
2010年3月22日 星期一
driver function 排程 與 user application 排程 與 中斷處理
1. 在kernel space 下呼叫schedule()時,排程器會先去檢查current process是否時間已經用完,決定是否進行context switch 或讓current process把時間用完再執行 context switch.
2. kernel timer , tasklet , task queues.
3. waitqueue 對實做 blocking I/O 有用處,讓current process 可以被rescheduling。
4. interruptible_sleep_on(&cdata->write_q) => 將current process放入自己所宣告的waitqueue 中,並將process 的狀態改成waiting state , 且能隨時收到SIGNAL(可以使用 kill 命令)。
5. 當timer function 執行完成之後,程式會直接跳至timer function 執行前的地方繼續執行 (猜測)
6. schduling 概念介紹: http://www.jollen.org/blog/2008/12/kernel-scheduling-concept-1.html
7. 每一次open需包含一個wait queue 於私有資料結構(避免WAKE UP效率很差)。
8. Ex:cdata-0.2.1中 cdata_interrupt handler負責處理process 的wake up,當ap 執行open時,會去初始化timer_frunction(每5秒執行)與cdata_interrupt_handler(每毫秒執行),可以調整cdata_interrupt_handler的執行周期,觀察系統的行為差異。
9. driver 範例: http://lxr.linux.no/linux-old+v2.4.31/drivers/char/scan_keyb.c
10. kernel timer 用於不需排程機制的應用, EX: 機器人走路。
11. 練習七的架構可以應用於: 按下按鈕5秒鐘(kernel timer poling 50次檢察案件是否被按),開發版自動重開機。
12. timer function中不能實做排程!!! ,因為timer function是在中斷模式下執行,會造成當機,所以timer functon沒有重複進入的問題。
13. 中斷模式下執行的程式與呼叫System call的程式差異:
(1). 是在一般process的context(PCB <--紀錄process狀態)外執行 (2). 不能直接存取user space (因為copy_to_user 必須透過PCB才能存取),須先將Data放置於kernel中buffer ,process再透過read/write去存取。 (3). 不能做call schedule() => 不能使用wait queue,中斷模式下做concurrent access 必須用spin lock 不能用down/up。
14. request IRQ基本觀念: http://www.jollen.org/blog/2008/03/interrupt_handling_1.html
15. 驅動程式的中斷處理 #2 (包含Counting semaphore觀念介紹): http://www.jollen.org/blog/2008/03/interrupt_handling_semaphore.html
16. Buttom Half 的觀念: http://www.jollen.org/blog/2008/03/interrupt_handling_bottom_half.html
17. Blocking I/O 觀念總結: http://www.jollen.org/blog/2008/08/linux_device_driver_blocking_io.html
18. 中斷模式下kmalloc(64,GFP_ATOMIC)才被允許使用,有關中斷模式下的限制參考講義(二)P3~P11。
19. interrupt handler 實作須盡量減少所需之I/O時間(使用tasklet機制將一些operation做排程移到OS time下去執行),以免造成系統反應時間過長的問題出現,也避免掉中斷遺失的問題出現。
20. interrupt handler 可以分為top-half 與 bottom-half 兩種,差別在於bottom-half執行時所有中斷都是開啟的,且bottom-half是由top-half做排程,在OS 時間執行。
21. top-half 與 bottom-half中的程式由工程師自行取捨並無重要工作一定得分配給誰的問題。
22. 在top-half中會將硬體最新的狀態儲存於特定的buffer中,而bottom-half則由於過了一段時間後才執行,所存的硬體狀態資訊是舊的。
23. void my_tasklet_function(unsigned int)
DECLARE_TASKLET(my_tasklet,my_tasklet_function,(unsigned int)&my_data) <= 宣告Tasklet tasklet_schedule(&my_tasklet) <= 排程bottom-half ,可以重複schedule 24. 由bottom-half 負責將user-space process 叫醒 ,top-half 負責接收中斷與排程 bottom-half。 25. 若top-half同時排程兩個以上的bottom-half,邏輯上有機會concurrent 執行 <=使用spin-lock保護。 26. 講義(二) p.24 的鍵盤範例,可以同時記錄多個被按下的按鈕,學習該機制的設計方式,可以應用於中斷快速產生的狀況。 27. 效能調教時,會衡量interrupt handler 的處理效率,並計算花費的時間。 28. 組合鍵應用 ctrl + c,須使用kernel timer 紀錄下一個被按下的按鍵使否為 c。 29. 兩種framebuffer機制: (1) ap將圖片放入buffer中(已完成mapping ),再由driver透過memcopy_fromio(dest,source,num)將圖片寫入framebuffer <=目的為了進行影像處理 (2) ap直接存取framebuffer。
30. chache 中的資料並不會被swap out 且其中的資料不會消失,且kernel本身即是個大chache。
31. vmalloc()可以指定任意大小的記憶體空間,而kmalloc則只能指定到128kb <=無法存放一張圖片。
32. 記憶體位址的mapping table一般為MMU負責做分配,若無MMU則需實作軟體去做計算,但效能會變慢,透過直接修改kernel的方式可以直接跳過mapping動作,達到phsical address連續而快速的效果。
33. ioremap()與 vmalloc()均能劃分到任意大小的記憶體空間,且存取到的一定是建構於MMU系統的虛擬空間上。
34. 無MMU的系統由於需要軟體運算page table因此效能比較差。
35. virtual address 一定是連續的,由MMU系統負責處理。
36. 記憶體空間是由kernel由低位址開始使用
37. I/O MEM 由於是外部記憶體,因此相較於RAM為連續的位址分配 (還未確定)。
38. VMA 與 VFS 的關係:
39. vmalloc 的分配只有前4Mb的Page為連續,之後則不一定連續,cdata-lcd.c 中的do_lcd_mmap()做法是由於在I/O MEM的Page range所以才能連續做mapping,要注意這點。
40. vm_area_struct 結構為kernel準備好的結構。
41. 一個基本可開機的OS需要: (1) 排程/ Context switch (2) interrupt handler (3) virtual memory
2. kernel timer , tasklet , task queues.
3. waitqueue 對實做 blocking I/O 有用處,讓current process 可以被rescheduling。
4. interruptible_sleep_on(&cdata->write_q) => 將current process放入自己所宣告的waitqueue 中,並將process 的狀態改成waiting state , 且能隨時收到SIGNAL(可以使用 kill 命令)。
5. 當timer function 執行完成之後,程式會直接跳至timer function 執行前的地方繼續執行 (猜測)
6. schduling 概念介紹: http://www.jollen.org/blog/2008/12/kernel-scheduling-concept-1.html
7. 每一次open需包含一個wait queue 於私有資料結構(避免WAKE UP效率很差)。
8. Ex:cdata-0.2.1中 cdata_interrupt handler負責處理process 的wake up,當ap 執行open時,會去初始化timer_frunction(每5秒執行)與cdata_interrupt_handler(每毫秒執行),可以調整cdata_interrupt_handler的執行周期,觀察系統的行為差異。
9. driver 範例: http://lxr.linux.no/linux-old+v2.4.31/drivers/char/scan_keyb.c
10. kernel timer 用於不需排程機制的應用, EX: 機器人走路。
11. 練習七的架構可以應用於: 按下按鈕5秒鐘(kernel timer poling 50次檢察案件是否被按),開發版自動重開機。
12. timer function中不能實做排程!!! ,因為timer function是在中斷模式下執行,會造成當機,所以timer functon沒有重複進入的問題。
13. 中斷模式下執行的程式與呼叫System call的程式差異:
(1). 是在一般process的context(PCB <--紀錄process狀態)外執行 (2). 不能直接存取user space (因為copy_to_user 必須透過PCB才能存取),須先將Data放置於kernel中buffer ,process再透過read/write去存取。 (3). 不能做call schedule() => 不能使用wait queue,中斷模式下做concurrent access 必須用spin lock 不能用down/up。
14. request IRQ基本觀念: http://www.jollen.org/blog/2008/03/interrupt_handling_1.html
15. 驅動程式的中斷處理 #2 (包含Counting semaphore觀念介紹): http://www.jollen.org/blog/2008/03/interrupt_handling_semaphore.html
16. Buttom Half 的觀念: http://www.jollen.org/blog/2008/03/interrupt_handling_bottom_half.html
17. Blocking I/O 觀念總結: http://www.jollen.org/blog/2008/08/linux_device_driver_blocking_io.html
18. 中斷模式下kmalloc(64,GFP_ATOMIC)才被允許使用,有關中斷模式下的限制參考講義(二)P3~P11。
19. interrupt handler 實作須盡量減少所需之I/O時間(使用tasklet機制將一些operation做排程移到OS time下去執行),以免造成系統反應時間過長的問題出現,也避免掉中斷遺失的問題出現。
20. interrupt handler 可以分為top-half 與 bottom-half 兩種,差別在於bottom-half執行時所有中斷都是開啟的,且bottom-half是由top-half做排程,在OS 時間執行。
21. top-half 與 bottom-half中的程式由工程師自行取捨並無重要工作一定得分配給誰的問題。
22. 在top-half中會將硬體最新的狀態儲存於特定的buffer中,而bottom-half則由於過了一段時間後才執行,所存的硬體狀態資訊是舊的。
23. void my_tasklet_function(unsigned int)
DECLARE_TASKLET(my_tasklet,my_tasklet_function,(unsigned int)&my_data) <= 宣告Tasklet tasklet_schedule(&my_tasklet) <= 排程bottom-half ,可以重複schedule 24. 由bottom-half 負責將user-space process 叫醒 ,top-half 負責接收中斷與排程 bottom-half。 25. 若top-half同時排程兩個以上的bottom-half,邏輯上有機會concurrent 執行 <=使用spin-lock保護。 26. 講義(二) p.24 的鍵盤範例,可以同時記錄多個被按下的按鈕,學習該機制的設計方式,可以應用於中斷快速產生的狀況。 27. 效能調教時,會衡量interrupt handler 的處理效率,並計算花費的時間。 28. 組合鍵應用 ctrl + c,須使用kernel timer 紀錄下一個被按下的按鍵使否為 c。 29. 兩種framebuffer機制: (1) ap將圖片放入buffer中(已完成mapping ),再由driver透過memcopy_fromio(dest,source,num)將圖片寫入framebuffer <=目的為了進行影像處理 (2) ap直接存取framebuffer。
30. chache 中的資料並不會被swap out 且其中的資料不會消失,且kernel本身即是個大chache。
31. vmalloc()可以指定任意大小的記憶體空間,而kmalloc則只能指定到128kb <=無法存放一張圖片。
32. 記憶體位址的mapping table一般為MMU負責做分配,若無MMU則需實作軟體去做計算,但效能會變慢,透過直接修改kernel的方式可以直接跳過mapping動作,達到phsical address連續而快速的效果。
33. ioremap()與 vmalloc()均能劃分到任意大小的記憶體空間,且存取到的一定是建構於MMU系統的虛擬空間上。
34. 無MMU的系統由於需要軟體運算page table因此效能比較差。
35. virtual address 一定是連續的,由MMU系統負責處理。
36. 記憶體空間是由kernel由低位址開始使用
37. I/O MEM 由於是外部記憶體,因此相較於RAM為連續的位址分配 (還未確定)。
38. VMA 與 VFS 的關係:
39. vmalloc 的分配只有前4Mb的Page為連續,之後則不一定連續,cdata-lcd.c 中的do_lcd_mmap()做法是由於在I/O MEM的Page range所以才能連續做mapping,要注意這點。
40. vm_area_struct 結構為kernel準備好的結構。
41. 一個基本可開機的OS需要: (1) 排程/ Context switch (2) interrupt handler (3) virtual memory
閱讀 Linux kernel driver 程式碼
1. busmouse.c http://lxr.linux.no/linux-old+v2.4.31/drivers/char/busmouse.c
學習driver程式碼的架構 ,觀察其中的multi-thread的機制如何實做。
2. read & write system call
user space 的 process 分配到的記憶體有可能被swapping out,因此kernel space 的 含式在存取到userspace時必須要 能先做檢查動作,以免出現 Page Fault 問題。
3. OS 只會對user space process 進行排程,且kernel space 存取invalid page 並不像USER space process 一樣(swap in),而會出現kernel panic,須視執行當下的記憶體配置,所以在寫作kernel space code 時必須很小心記憶體的使用。
4. user space 與 kenel space 的記憶體空間配置是各自獨立的 (猜測)
5. 使用到kmalloc()與copy_from_user()/ copy_to_user()等存取到user space 的含數的驅動程式必須是reentrance(spinllock 與 semaphonme) 。
6. 函數重複進入 => 該函數還未return前,又被呼叫一次。
7. 區域變數在每次呼叫都會有一塊獨立的stack來存放,而全域變數是存放於?
8. 由於user space process 會去sleep故driver function 必須是可重複進入函數
9. 使用strace工具來觀察system call的調用過程。
10. 有關process的詳細介紹:http://www.jollen.org/blog/2007/01/process_creation_2.html
11. process 對應一個PCB 其中 有一個欄位Program Counter負責紀錄該Process 執行到哪一行
12. 假若硬體ready,並不會馬上讓資料寫入硬體,而是必須等待running中的程序把時間用完且使用該driver的應用層process被系統挑到才會寫入硬體,因此當系統中的程序越多相對系統的I/O 效能就越差。
13. sleep 的process 必須先改為ready 再由系統排程進入runnning
14. 介紹MultiTasking 概念:http://www.netrino.com/Embedded-Systems/How-To/RTOS-Preemption-Multitasking
15. 將Process 由 waiting state 到 running state 是由driver來負責,硬體ready之會產生中斷(有些硬體不會產生中斷),driver 中的interrupt handler 會將process state 改為ready state。
16. (char *)kmalloc(64, GFP_KERNEL); 左式程式碼中當系統一時要不到記憶體,會讓current process 去sleep,直到記憶體被swap in 後再將 waiting process 的狀態改成runnning state.
學習driver程式碼的架構 ,觀察其中的multi-thread的機制如何實做。
2. read & write system call
user space 的 process 分配到的記憶體有可能被swapping out,因此kernel space 的 含式在存取到userspace時必須要 能先做檢查動作,以免出現 Page Fault 問題。
3. OS 只會對user space process 進行排程,且kernel space 存取invalid page 並不像USER space process 一樣(swap in),而會出現kernel panic,須視執行當下的記憶體配置,所以在寫作kernel space code 時必須很小心記憶體的使用。
4. user space 與 kenel space 的記憶體空間配置是各自獨立的 (猜測)
5. 使用到kmalloc()與copy_from_user()/ copy_to_user()等存取到user space 的含數的驅動程式必須是reentrance(spinllock 與 semaphonme) 。
6. 函數重複進入 => 該函數還未return前,又被呼叫一次。
7. 區域變數在每次呼叫都會有一塊獨立的stack來存放,而全域變數是存放於?
8. 由於user space process 會去sleep故driver function 必須是可重複進入函數
9. 使用strace工具來觀察system call的調用過程。
10. 有關process的詳細介紹:http://www.jollen.org/blog/2007/01/process_creation_2.html
11. process 對應一個PCB 其中 有一個欄位Program Counter負責紀錄該Process 執行到哪一行
12. 假若硬體ready,並不會馬上讓資料寫入硬體,而是必須等待running中的程序把時間用完且使用該driver的應用層process被系統挑到才會寫入硬體,因此當系統中的程序越多相對系統的I/O 效能就越差。
13. sleep 的process 必須先改為ready 再由系統排程進入runnning
14. 介紹MultiTasking 概念:http://www.netrino.com/Embedded-Systems/How-To/RTOS-Preemption-Multitasking
15. 將Process 由 waiting state 到 running state 是由driver來負責,硬體ready之會產生中斷(有些硬體不會產生中斷),driver 中的interrupt handler 會將process state 改為ready state。
16. (char *)kmalloc(64, GFP_KERNEL); 左式程式碼中當系統一時要不到記憶體,會讓current process 去sleep,直到記憶體被swap in 後再將 waiting process 的狀態改成runnning state.
2010年3月18日 星期四
人生課題:團隊精神與自尊心的討論
今天與team member 提出討論的建議,一方面也是針對之前的誤會做溝通,一方面也希望能結束一些不當言論與行為一再發生,卻沒有人去試圖改變現狀的情形。
今天獲益良多,或許之後在職場生涯會比較懂得避免一些忌諱,感謝各位惠賜良言,雖然句句是苦在心裡,但收穫豐碩。
今天獲益良多,或許之後在職場生涯會比較懂得避免一些忌諱,感謝各位惠賜良言,雖然句句是苦在心裡,但收穫豐碩。
2010年3月17日 星期三
Linux System Programing

daemon.c無法確實編譯出執行檔
背景執行:
./pid &
execvp.c 範例:
int main(){
...
char *arg_list[] = {"ls","-l","/tmp",NULL};
execvp("ls",arg_list);
printf("the end of the program.\n");
}
紅字部分變數為重要參數,必須要正確填寫。
有關Daemon設計的觀念分享: http://home.educities.edu.tw/shirock/comp/Daemon_initiation.txt
./pid &
execvp.c 範例:
int main(){
...
char *arg_list[] = {"ls","-l","/tmp",NULL};
execvp("ls",arg_list);
printf("the end of the program.\n");
}
紅字部分變數為重要參數,必須要正確填寫。
有關Daemon設計的觀念分享: http://home.educities.edu.tw/shirock/comp/Daemon_initiation.txt
編譯android kernel
步驟:
git branch goldfish origin/android-goldfish-2.6.27
git checkout goldfish
make goldfish_defconfig ARCH=arm CROSS_COMPILE=arm-none-eabi-
make zImage ARCH=arm CROSS_COMPILE=arm-none-eabi-
注意細節:
su root
export PATH:%PATH:/root/CodeSourcery/Sourcery_G++_Lite/bin/
or modify ~/.bashrc
git branch goldfish origin/android-goldfish-2.6.27
git checkout goldfish
make goldfish_defconfig ARCH=arm CROSS_COMPILE=arm-none-eabi-
make zImage ARCH=arm CROSS_COMPILE=arm-none-eabi-
注意細節:
su root
export PATH:%PATH:/root/CodeSourcery/Sourcery_G++_Lite/bin/
or modify ~/.bashrc
Remote object 與 Proxy object 的差異
Proxy object :
public final class LedService extend ILedService.Stub{
............................
}
Remote object:
public final class LedService extends Binder{
..............
}
public final class LedService extend ILedService.Stub{
............................
}
Remote object:
public final class LedService extends Binder{
..............
}
2010年3月16日 星期二
Android 系統啟動流程
init -> runtime -> zygote -> system server (初始化30多個manager 與 audio suface flinger並由zygote fork) ->完成系統初始化
2010年3月15日 星期一
Android HAL Stub整合
一. 兩種整合HAL Stub的實作方式:
1.透過java service ->native service -> HAL ->HAL Stub
2.使用remote object直接與native service 溝通
其中第一種方式須使用IPC機制而第二種方式則是從java service 取得一個分身(remote object),直接與分身溝通
native service具有daemon與JNI (run time) 功能
二. mokoid project:
對應target 端 :
system/framework/mokoid.jar(API for LedManager)
=> /framework/base/core/mokoid/hardware/...
system/lib/hw/led.goldfish.so(LED HAL Stub)
=> /hardware/modules/...
system/lib/libmokoid_runtime.so(JNI handle Led Service) => /framework/base/service/jni/...

1.透過java service ->native service -> HAL ->HAL Stub
2.使用remote object直接與native service 溝通
其中第一種方式須使用IPC機制而第二種方式則是從java service 取得一個分身(remote object),直接與分身溝通
native service具有daemon與JNI (run time) 功能
二. mokoid project:
對應target 端 :
system/framework/mokoid.jar(API for LedManager)
=> /framework/base/core/mokoid/hardware/...
system/lib/hw/led.goldfish.so(LED HAL Stub)
=> /hardware/modules/...
system/lib/libmokoid_runtime.so(JNI handle Led Service) => /framework/base/service/jni/...

飛輪教室
踩踏的三種方式:
踝動式:(一推(1:00)、二壓(3:00)、三拖(5:00)、四提(7:00 or 8:00))
50%重心放踏板,30%在坐墊,20%在把手,並記得上半身要放鬆,踩踏時要用身體的重量去壓,踏板與芝麻球(大拇指第3關節處)。
變速時當下需放輕踩踏的力道,並且維持鍊條在中間的位置,ex:爬坡時,前大變小時,飛輪也要變小一齒,來維持前進動力。
注意兩腿的力量差,目前左腳用力過度,須加強右腳的力量。
騎成公路車時,須注意膝蓋與手肘往內縮,肩頰骨放開,骨棚固定不動。
踩踏時經過上死點時勿重踩,維持膝蓋的角度,遇到下死點想像將鞋底的泥巴刮乾淨,順時鐘往上拉直到上死點。
參考網頁: http://mypaper.pchome.com.tw/56490
踝動式:(一推(1:00)、二壓(3:00)、三拖(5:00)、四提(7:00 or 8:00))
50%重心放踏板,30%在坐墊,20%在把手,並記得上半身要放鬆,踩踏時要用身體的重量去壓,踏板與芝麻球(大拇指第3關節處)。
變速時當下需放輕踩踏的力道,並且維持鍊條在中間的位置,ex:爬坡時,前大變小時,飛輪也要變小一齒,來維持前進動力。
注意兩腿的力量差,目前左腳用力過度,須加強右腳的力量。
騎成公路車時,須注意膝蓋與手肘往內縮,肩頰骨放開,骨棚固定不動。
踩踏時經過上死點時勿重踩,維持膝蓋的角度,遇到下死點想像將鞋底的泥巴刮乾淨,順時鐘往上拉直到上死點。
參考網頁: http://mypaper.pchome.com.tw/56490
2010年3月14日 星期日
GCC 編譯與連結
產生動態連結執行檔: gcc getarg.c writeinfo.c main.c -o test
產生靜態連結執行檔:
step1: gcc -c -o getarg.o getarg.c
gcc -c -o writeinfo.o writeinfo.c
gcc -c -o main.o main.c
step2:
gcc getarg.o writeinfo.o main.o -static -o test_static.o
執行檔檔案大小: test => 10798kb
test_static => 590326kb
靜態連結型執行檔對於嵌入式系統來說是不適用的,因此在系統支援動態的前提下,多採用動態連結方式使程式達到最佳化與省空間的目的。
實做動態連結庫:
gcc -shared getarg.o writeinfo.o -o libtest_d.so
連結動態庫產生可執行程式:
gcc main.o -L. -libtest_d.so -o test_dlib
修改環境變數:
export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH <=目前仍無解 ./test_dlib
產生靜態連結執行檔:
step1: gcc -c -o getarg.o getarg.c
gcc -c -o writeinfo.o writeinfo.c
gcc -c -o main.o main.c
step2:
gcc getarg.o writeinfo.o main.o -static -o test_static.o
執行檔檔案大小: test => 10798kb
test_static => 590326kb
靜態連結型執行檔對於嵌入式系統來說是不適用的,因此在系統支援動態的前提下,多採用動態連結方式使程式達到最佳化與省空間的目的。
實做動態連結庫:
gcc -shared getarg.o writeinfo.o -o libtest_d.so
連結動態庫產生可執行程式:
gcc main.o -L. -libtest_d.so -o test_dlib
修改環境變數:
export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH <=目前仍無解 ./test_dlib
訂閱:
意見 (Atom)