Category Archives: Embedded

Create Bash-script service for Debian

ในบางครั้ง เราต้องการให้โปรแกรมที่เราเขียนขึ้นรันเมื่อเปิดเครื่องคอมพิวเตอร์ขึ้นมา และใน Debian นั้นสามารถทำได้หลายวิธี ไม่ว่าจะเป็นการสั่งให้เรียกโปรแกรมจากไฟล์ crontab หรือ rc.local ซึ่งในวันนี้จะเสนอวิธีที่นำโปรแกรมมาสร้างเป็น Bash-script แล้วนำไปผูกกับ service ของระบบปฎิบัติการ Debian

การสร้าง Bash-script แล้วจึงนำไปถูกกับ Service มีข้อดีคือ เราสามารถสั่งเปิดปิดโปรแกรมของเรา รวมถึง restart ได้ผ่านทางระบบ service ของ Debian ได้นั่นเอง ซึ่งนี่คือตัวอย่างของวิธีการดังกล่าว PiCam-Setup เป็นการสร้าง Service ในการเปิดกล้องให้กับ Raspberry Pi โดยใช้ไลบรารี่ mpeg-streamer

มาเริ่มกันเลยดีกว่า อย่างแรกที่ต้องมีคือโปรแกรมที่อยากให้ทำงานก่อนในที่ใช้โปรแกรม my_program.py จากนั้นเขียนไฟล์ Bash-script ดังนี้

#!/bin/bash
# /etc/init.d/MyService.sh

function startService()
{
    ./my_program.py &
}

case "$1" in
    start)
        echo "Starting my_program.py"
        startService
        ;;
    stop)
        echo "Stopping my_program.py"
        killall my_program.py
        ;;
    status)
        echo "Not supported yet"
        ;;
    restart)
        echo "Restarting my_program.py"
        killall my_program.py
        start
        sleep 2
        ;;
    *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
        ;;
esac
exit 0

จากนั้น เราต้องก็อปปี้สคริปข้างบนไปไว้ /etc/init.d/ จากนั้นก้ update-rc.d ตามคำสั่งดังนี้

# cp MyService.sh /etc/init.d/
# chmod +x /etc/init.d/MyService.sh
# update-rc.d MyService.sh defaults

เพียงเท่านี้เราก้จะได้เซอร์วิสที่เป็นของเราเองแล้วครับ

Compile kernel 3.x for mini2440

จากคราวที่แล้วที่ได้นำเสนอการ compile U-Boot ไป ซึ่งเป็นแค่ boot loader เท่านั้น ยังไม่สามารถใช้งาน linux บน mini2440 ได้ เราจำเป็นจะต้องมี kernel ซึ่งเป็นระบบปฎิบัติการในการใช้งานต่อไป ซึ่งเราสามารถทำการ compile kernel ได้ตาม link นี้ และต่อจากนั้นเราจำเป็นจะต้องมี root file system ซึ่งจะมี configuration สำหรับการ boot อยู่ โดยเราสามารถสร้างโดยใช้ Debootstrap ซึ่งสามารถทำได้ตาม link นี้ แต่ release เป็น version เก่า (lenny) ซึ่งผมแนะนำให้เปลี่ยนเป็น wheezy เพื่อความทันสมัย

เมื่อเราเปลี่ยน root file system ให้ทันสมัยแล้ว การ compile kernel ที่นำเสนอไปก่อนหน้า จะไม่สามารถใช้ได้ โดยเมื่อนำไปใช้จะเกิดปัญหาดังนี้

udevd[xxx]: unable to receive ctrl connection: Function not implemented

และเมื่อค้นลึกลงไป ปรากฎว่า version ของ kernel เก่าไปนิดเดียวเอง ของตามที่นำเสนอเป็น 2.6.32 แต่ฟังก์ชันที่ kernel ใหม่เรียกหาอยู่ใน version 2.6.36 ช่างน่าเสียดาย ตอนแรกก้คิดว่าจริงๆ ขยับไป 2.6.36 ก้ได้ แต่เพื่อไม่ให้เกิดปัญหาคล้ายเดิมอีกในอนาคต เราควรจะย้ายไป kernel ใหม่เลย ในที่นี้เลือก 3.10.6 เพราะมีคนบอกว่าใช้ได้

การ compile จำเป็นต้องลง cross-compile ก่อน จากนั้นดาวน์โหลด kernel 3.10.6 จากนั้นแตกไฟล์ และใช้คำสั่งดังนี้

$ mkdir ../kernel-bin
$ CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm make O=../kernel-bin/ mini2440_defconfig

จากนั้น ให้ดาวน์โหลด file นี้ ไปเขียนทับไฟล์ .config ในโฟล์เดอร์ kernel-bin จากนั้นทำการ make ตามคำสั่งด้านล่าง ซึ่ง -j8 คืออนุญาตให้ make แบบขนานได้พร้อมกัน 8 thread

$ CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm make O=../kernel-bin/ -j8

จากนั้นนำไปสร้าง uImage ตามวิธีการ compile kernel ที่นำเสนอไปตอนต้นของโพส ซึ่งสำหรับคนที่ต้องการประหยัดเวลาในส่วนนี้สามารถ นำ image file ซึ่งประกอบด้วย kernel และ root file system โดยขอเพียงมี SDcard ที่ขนาดตั้งแต่ 4Gb ขึ้นไป จากนั้นใช้คำสั่งดังนี้ ซึ่งเปลี่ยน mmcblk0 ตามชื่อพาร์ติชั่นของ SDcard ของคุณเอง

$ tar -zxvf mini2440_sdcard.img.tar.gz
$ sudo dd bs=4M if=mini2440_sdcard.img of=/dev/mmcblk0

ซึ่งสามารถ ขยายพาร์ติชั่นตามที่อยากได้โดยการใช้โปรแกรม gparted เพียงเท่านี้เราก้จะได้ SDcard สำหรับรัน linux บน FriendlyARM mini2440 ได้แล้ว เห็นมั้ยครับมันลำบากนะครับกว่าจะมาเป็นคอมพิวเตอร์ที่ใช้ง่ายๆในมือคุณ

mini2440 partition

Mini2440 SDcard Partition

Compile U-Boot for mini2440

เดี๋ยวนี้ถ้าพูดถึง Embedded board คงไม่มีใครไม่รู้จัก Raspberry Pi ทั้งใช้ง่ายและสะดวกสบายมาก แต่บางทีชีวิต Programmer ก้อยากมีช่วงลำบากบ้าง วันนี้จึงนำเสนอ Board ที่เก่าหน่อย แล้วก้ทุกอย่างต้อง compile เองเกือบทั้งหมด นั่นคือ FriendlyARM mini2440 ซึ่งหลายๆคนบอกว่า ไม่ Friendly เลย เพื่อไม่ให้เป็นการเสียเวลาเรามาเริ่มกันเลย สำหรับการ compile ครั้งนี้จะทำบน ubuntu นะครับ

Cross-Compile

อย่างแรกที่ต้องมีในการ compile U-Boot คือ cross-compile แค่เริ่มก้เห็นความยากแล้วใช่มั้ยครับ cross-compile คือ การ compile code สำหรับอุปกรณ์อื่นบนเครื่องเราเอง เช่น ใช้เครื่องคอมพิวเตอร์เรา compile code สำหรับ arm แล้วทำไมไม่ compile บน arm เลยหล่ะ ก้อาจจะเพราะว่า arm ช้าจนเกินไป ซึ่งใช้คำสั่งในการติดตั้งดังนี้

$ sudo apt-get install gcc-arm-linux-gnueabi

ลองทดลองได้โดยใช้คำสั่งดังนี้

$ arm-linux-gnueabi-gcc
arm-linux-gnueabi-gcc: fatal error: no input files
compilation terminated.

ซึ่งขึ้นแบบนี้ไม่ต้องกังวลนะครับ หมายถึงใช้ได้

Compile U-Boot

ต่อมาเราจะทำการ compile U-Boot โดยเริ่มต้นจากการ clone repository ของ U-Boot มาก่อน (ซึ่งก้คือ code นั่นเอง) จากนั้นต้องทำการเซ็ค CROSS_COMPILE สุดท้ายก้ทำการ compile ได้โดยใช้คำสั่งดังนี้

$ mkdir ~/uboot && cd ~/uboot
$ git clone git://repo.or.cz/u-boot-openmoko/mini2440.git
$ export CROSS_COMPILE=arm-linux-gnueabi-
$ cd mini2440 && make mini2440_config
$ make

ถ้าสำเร็จ ก้สามารถนำไฟล์ u-boot.bin ไปลงบอร์ด mini2440 ได้ตามวิธีใน link นี้ แต่ของที่ผมทำมันไม่สำเร็จนะครับ โดยขึ้น error ดังนี้

{standard input}: Assembler messages:
{standard input}:22: Error: lo register required -- `ldr ip,[r8,#32]'
{standard input}:23: Error: lo register required -- `ldr pc,[ip,#0]'
...

ซึ่งจากการค้นหาที่มาของภัยพิบัติดังกล่าว พบว่าเราใช้ optimize มากเกินไป จึงต้องแก้ cpu/arm920t/config.mk โดยเพิ่ม -marm ไปดังนี้

PLATFORM_RELFLAGS += -fno-strict-aliasing  -fno-common -ffixed-r8 \
        -msoft-float

PLATFORM_CPPFLAGS += -march=armv4t -marm
# ===========================================================

จากนั้นทำการ make ใหม่ครับ เห็นมั้ยครับว่าจุดเริ่มต้นของความสบายมักจะเกิดจากความลำบากนะครับ ถ้าไม่อยากลำบาก compile เองผมมีอันที่ compile ไว้ให้แล้วครับ ตาม link นี้เลย