2010年11月29日 星期一

有感

每當靜下心來好好的寫程式…就能感受到在邏輯的殿堂中自己意志力以及知識的力量,意志力經由手指的敲打化為真實的程式,就像是魔法師一般。看它順利的完成任務,心裏總是開心的滿足的。這單純的喜悅正是為什麼如此著迷於設計並實作軟體,即便是其它人不容易感受到內心的喜悅。
然而…如果想要改善台灣軟體環境的現況,我需要學會的…真的遠遠超過把軟體寫好的能力。夜深人靜時,總是不停的思索這個問題…好像看得到未來的方向,又好虛無飄渺。嗯,我必需學會另一種高度…

2010年6月9日 星期三

Eclair Libgralloc Deadlock Problem

As we are developing 0xdroid beagle-eclair branch, we occasionally encounter screen flipping issue. This issue rarely happens however it bothers the user experience very much when running some resource eating applications. Last week in the Computex Taipei 2010 show, we demoed 0xdroid beagle-eclair connecting wireless modules and played games. I noticed that this issue happens very often while playing a game called "Frozen Bubble". (It's a good game, we all love this game a lot, and spent a lot of time on it. ;-) ) It's kind of embarrassing when the screen keeps flipping on the show. Therefore I decided to dig out this issue.




Beside of 0xdroid on beagleboard and Devkit8000, I tested some other platforms and find out actually almost all of them having this problem. Therefore I suspected it's not a hardware related problem. Maybe a framework or HAL issue. We noticed that when the screen is flipping, the logcat message will complain as following

E/SurfaceFlinger(  768): eglSwapBuffers: EGL error 0x3002 (EGL_BAD_ACCESS)
E/gralloc (  768): handle 0x13f8c0 not locked
~E/gralloc (  768): handle 0x13f8c0 already locked for write
E/libagl  (  768): eglSwapBuffers() failed to lock buffer 0x1368e0 (640x480)
E/SurfaceFlinger(  768): eglSwapBuffers: EGL error 0x3002 (EGL_BAD_ACCESS)
E/gralloc (  768): handle 0x13f8c0 not locked
E/gralloc (  768): handle 0x13f8c0 already locked for write
E/libagl  (  768): eglSwapBuffers() failed to lock buffer 0x1368e0 (640x480)
E/SurfaceFlinger(  768): eglSwapBuffers: EGL error 0x3002 (EGL_BAD_ACCESS)
E/gralloc (  768): handle 0x13f8c0 not locked
E/gralloc (  768): handle 0x13f8c0 already locked for write
E/libagl  (  768): eglSwapBuffers() failed to lock buffer 0x1368e0 (640x480)
E/SurfaceFlinger(  768): eglSwapBuffers: EGL error 0x3002 (EGL_BAD_ACCESS)
E/gralloc (  768): handle 0x13f8c0 not locked

Therefore I checked the libgralloc and adding some debug message. The libgralloc plugin 0xdroid used is branched from original eclair source tree. I took few hours created the omap3/libgralloc at the first day when I got eclair source code months ago. Since it works well for the most of time, I didn't pay too much attention to it, until I found the deadlock issue goes crazy on frozen bubble.
After noticing the lock log and swap error, I took a close look of the gralloc_lock and gralloc_unlock in hardware/omap3/libgralloc/mapper.c

int gralloc_lock(gralloc_module_t const* module,
        buffer_handle_t handle, int usage,
        int l, int t, int w, int h,
        void** vaddr)
{
    if (private_handle_t::validate(handle) < 0)
        return -EINVAL;

    int err = 0;
    private_handle_t* hnd = (private_handle_t*)handle;
    int32_t current_value, new_value;
    int retry;

    do {
        current_value = hnd->lockState;
        new_value = current_value;

        if (current_value & private_handle_t::LOCK_STATE_WRITE) {
            // already locked for write 
            LOGE("handle %p already locked for write", handle);
            return -EBUSY;
        } else if (current_value & private_handle_t::LOCK_STATE_READ_MASK) {
            // already locked for read
            if (usage & (GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_HW_RENDER)) {
                LOGE("handle %p already locked for read", handle);
                return -EBUSY;
            } else {
                // this is not an error
                //LOGD("%p already locked for read... count = %d", 
                //        handle, (current_value & ~(1<<31)));
            }
        }

        // not currently locked
        if (usage & (GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_HW_RENDER)) {
            // locking for write
            new_value |= private_handle_t::LOCK_STATE_WRITE;
        }
        new_value++;

        retry = android_atomic_cmpxchg(current_value, new_value, 
    } while (retry);

    if (new_value & private_handle_t::LOCK_STATE_WRITE) {
        // locking for write, store the tid
        hnd->writeOwner = gettid();
    }

    if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
        if (!(current_value & private_handle_t::LOCK_STATE_MAPPED)) {
            // we need to map for real
            pthread_mutex_t* const lock = &sMapLock;
            pthread_mutex_lock(lock);
            if (!(hnd->lockState & private_handle_t::LOCK_STATE_MAPPED)) {
                err = gralloc_map(module, handle, vaddr);
                if (err == 0) {
                    android_atomic_or(private_handle_t::LOCK_STATE_MAPPED,
                            (volatile int32_t*)&(hnd->lockState));
                }
            }
            pthread_mutex_unlock(lock);
        }
        *vaddr = (void*)hnd->base;
    }

    return err;
}

int gralloc_unlock(gralloc_module_t const* module, 
        buffer_handle_t handle)
{
    if (private_handle_t::validate(handle) < 0)
        return -EINVAL;

    private_handle_t* hnd = (private_handle_t*)handle;
    int32_t current_value, new_value;

    do {
        current_value = hnd->lockState;
        new_value = current_value;

        if (current_value & private_handle_t::LOCK_STATE_WRITE) {
            // locked for write
            if (hnd->writeOwner == gettid()) {
                hnd->writeOwner = 0;
                new_value &= ~private_handle_t::LOCK_STATE_WRITE;
            }
        }

        if ((new_value & private_handle_t::LOCK_STATE_READ_MASK) == 0) {
            LOGE("handle %p not locked", handle);
            return -EINVAL;
        }

        new_value--;

    } while (android_atomic_cmpxchg(current_value, new_value, 
            (volatile int32_t*)&hnd->lockState));

    return 0;
}

The code looks reasonably for the first look. Lock and unlock pair looks good. However there is a very tricky part "android_atomic_cmpxchg may fail". Understanding this, it is not hard to see there is a potential bug in gralloc_unlock.  If android_atomic_cmpxchg fails, it will run the do while loop for more than once. However for the first run, the hnd->writeOwner will be changed to 0.  And then the new_value will not be changed anymore. This lock will goes crazy here after.

The patch solves this problem.

diff --git a/mapper.cpp b/mapper.cpp
index 16ebcc2..1f3e722 100644
--- a/mapper.cpp
+++ b/mapper.cpp
@@ -267,13 +267,13 @@ int gralloc_unlock(gralloc_module_t const* module,
         if (current_value & private_handle_t::LOCK_STATE_WRITE) {
             // locked for write
             if (hnd->writeOwner == gettid()) {
-                hnd->writeOwner = 0;
                 new_value &= ~private_handle_t::LOCK_STATE_WRITE;
             }
         }
 
         if ((new_value & private_handle_t::LOCK_STATE_READ_MASK) == 0) {
             LOGE("handle %p not locked", handle);
+            hnd->writeOwner = 0;
             return -EINVAL;
         }
 
@@ -282,5 +282,6 @@ int gralloc_unlock(gralloc_module_t const* module,
     } while (android_atomic_cmpxchg(current_value, new_value, 
             (volatile int32_t*)&hnd->lockState));
 
+    hnd->writeOwner = 0;
     return 0;
 }

It make sure the value hnd->writeOwner is the same as the first loop, if android_atomic_cmpxchg fails.

This issue comes from the original eclair source tree, and it is still there, and had been inherited to many different platforms.  If you encounter two frames crazily flipping and having the lock message, you may try to take a look of your libgralloc.  

2009年12月14日 星期一

[備忘] RGB565 To PNG/JPEG

竟然忘掉了… 寫在這備忘

ffmpeg -vcodec rawvideo -f rawvideo -pix_fmt rgb565 -s 1024x720 -i input.raw -f image2 -vcodec png output.png

2009年10月13日 星期二

Oprofile 0xdroid Android on Beagleboard

Android supports oprofile actually. And you can play happily with that with some oprofile knowledge on G1. However the external/oprofile in Android does not support ARM_V7 for now. To play with it patch the following type and trigger support of ARM_V7


diff --git a/libop/op_cpu_type.c b/libop/op_cpu_type.c
index b9d13de..737f63e 100644
--- a/libop/op_cpu_type.c
+++ b/libop/op_cpu_type.c
@@ -74,6 +74,7 @@ static struct cpu_descr const cpu_descrs[MAX_CPU_TYPE] = {
{ "ppc64 POWER5++", "ppc64/power5++", CPU_PPC64_POWER5pp, 6 },
{ "e300", "ppc/e300", CPU_PPC_E300, 4 },
{ "AVR32", "avr32", CPU_AVR32, 3 },
+ { "ARM V7 PMNC", "arm/armv7", CPU_ARM_V7, 5},
};

static size_t const nr_cpu_descrs = sizeof(cpu_descrs) / sizeof(struct cpu_descr);
diff --git a/libop/op_cpu_type.h b/libop/op_cpu_type.h
index be95ae2..f4db260 100644
--- a/libop/op_cpu_type.h
+++ b/libop/op_cpu_type.h
@@ -72,6 +72,7 @@ typedef enum {
CPU_PPC64_POWER5pp, /**< ppc64 Power5++ family */
CPU_PPC_E300, /**< e300 */
CPU_AVR32, /**< AVR32 */
+ CPU_ARM_V7, /**< ARM V7 */
MAX_CPU_TYPE
} op_cpu;

diff --git a/libop/op_events.c b/libop/op_events.c
index b4a10e7..7f0ed25 100644
--- a/libop/op_events.c
+++ b/libop/op_events.c
@@ -793,6 +793,7 @@ void op_default_event(op_cpu cpu_type, struct op_default_event_descr * descr)
case CPU_ARM_XSCALE2:
case CPU_ARM_MPCORE:
case CPU_ARM_V6:
+ case CPU_ARM_V7:
case CPU_AVR32:
descr->name = "CPU_CYCLES";
break;
diff --git a/opimport_pull b/opimport_pull
index 7dbac4a..bf1f19a 100755
--- a/opimport_pull
+++ b/opimport_pull
@@ -1,4 +1,4 @@
-#!/usr/bin/python2.4 -E
+#!/usr/bin/python -E

import os
import re


And adding event tables for ARMv7

commit f129bca975b1704c06e07df7710d29de13a1e922
Author: Tick Chen <tick@0xlab.org>
Date: Sat Sep 26 22:56:44 2009 +0800

[oprofile] adding metadata of armv7

diff --git a/linux-x86/oprofile/arm/armv7/events b/linux-x86/oprofile/arm/armv7/events
new file mode 100644
index 0000000..2550e41
--- /dev/null
+++ b/linux-x86/oprofile/arm/armv7/events
@@ -0,0 +1,53 @@
+# ARM V7 events
+# From Cortex A8 DDI (ARM DDI 0344B, revision r1p1)
+#
+event:0x00 counters:1,2,3,4 um:zero minimum:500 name:PMNC_SW_INCR : Software increment of PMNC registers
+event:0x01 counters:1,2,3,4 um:zero minimum:500 name:IFETCH_MISS : Instruction fetch misses from cache or normal cacheable memory
+event:0x02 counters:1,2,3,4 um:zero minimum:500 name:ITLB_MISS : Instruction fetch misses from TLB
+event:0x03 counters:1,2,3,4 um:zero minimum:500 name:DCACHE_REFILL : Data R/W operation that causes a refill from cache or normal cacheable memory
+event:0x04 counters:1,2,3,4 um:zero minimum:500 name:DCACHE_ACCESS : Data R/W from cache
+event:0x05 counters:1,2,3,4 um:zero minimum:500 name:DTLB_REFILL : Data R/W that causes a TLB refill
+event:0x06 counters:1,2,3,4 um:zero minimum:500 name:DREAD : Data read architecturally executed (note: architecturally executed = for instructions that are unconditional or that pass the condition code)
+event:0x07 counters:1,2,3,4 um:zero minimum:500 name:DWRITE : Data write architecturally executed
+event:0x08 counters:1,2,3,4 um:zero minimum:500 name:INSTR_EXECUTED : All executed instructions
+event:0x09 counters:1,2,3,4 um:zero minimum:500 name:EXC_TAKEN : Exception taken
+event:0x0A counters:1,2,3,4 um:zero minimum:500 name:EXC_EXECUTED : Exception return architecturally executed
+event:0x0B counters:1,2,3,4 um:zero minimum:500 name:CID_WRITE : Instruction that writes to the Context ID Register architecturally executed
+event:0x0C counters:1,2,3,4 um:zero minimum:500 name:PC_WRITE : SW change of PC, architecturally executed (not by exceptions)
+event:0x0D counters:1,2,3,4 um:zero minimum:500 name:PC_IMM_BRANCH : Immediate branch instruction executed (taken or not)
+event:0x0E counters:1,2,3,4 um:zero minimum:500 name:PC_PROC_RETURN : Procedure return architecturally executed (not by exceptions)
+event:0x0F counters:1,2,3,4 um:zero minimum:500 name:UNALIGNED_ACCESS : Unaligned access architecturally executed
+event:0x10 counters:1,2,3,4 um:zero minimum:500 name:PC_BRANCH_MIS_PRED : Branch mispredicted or not predicted. Counts pipeline flushes because of misprediction
+event:0x12 counters:1,2,3,4 um:zero minimum:500 name:PC_BRANCH_MIS_USED : Branch or change in program flow that could have been predicted
+event:0x40 counters:1,2,3,4 um:zero minimum:500 name:WRITE_BUFFER_FULL : Any write buffer full cycle
+event:0x41 counters:1,2,3,4 um:zero minimum:500 name:L2_STORE_MERGED : Any store that is merged in L2 cache
+event:0x42 counters:1,2,3,4 um:zero minimum:500 name:L2_STORE_BUFF : Any bufferable store from load/store to L2 cache
+event:0x43 counters:1,2,3,4 um:zero minimum:500 name:L2_ACCESS : Any access to L2 cache
+event:0x44 counters:1,2,3,4 um:zero minimum:500 name:L2_CACH_MISS : Any cacheable miss in L2 cache
+event:0x45 counters:1,2,3,4 um:zero minimum:500 name:AXI_READ_CYCLES : Number of cycles for an active AXI read
+event:0x46 counters:1,2,3,4 um:zero minimum:500 name:AXI_WRITE_CYCLES : Number of cycles for an active AXI write
+event:0x47 counters:1,2,3,4 um:zero minimum:500 name:MEMORY_REPLAY : Any replay event in the memory subsystem
+event:0x48 counters:1,2,3,4 um:zero minimum:500 name:UNALIGNED_ACCESS_REPLAY : Unaligned access that causes a replay
+event:0x49 counters:1,2,3,4 um:zero minimum:500 name:L1_DATA_MISS : L1 data cache miss as a result of the hashing algorithm
+event:0x4A counters:1,2,3,4 um:zero minimum:500 name:L1_INST_MISS : L1 instruction cache miss as a result of the hashing algorithm
+event:0x4B counters:1,2,3,4 um:zero minimum:500 name:L1_DATA_COLORING : L1 data access in which a page coloring alias occurs
+event:0x4C counters:1,2,3,4 um:zero minimum:500 name:L1_NEON_DATA : NEON data access that hits L1 cache
+event:0x4D counters:1,2,3,4 um:zero minimum:500 name:L1_NEON_CACH_DATA : NEON cacheable data access that hits L1 cache
+event:0x4E counters:1,2,3,4 um:zero minimum:500 name:L2_NEON : L2 access as a result of NEON memory access
+event:0x4F counters:1,2,3,4 um:zero minimum:500 name:L2_NEON_HIT : Any NEON hit in L2 cache
+event:0x50 counters:1,2,3,4 um:zero minimum:500 name:L1_INST : Any L1 instruction cache access, excluding CP15 cache accesses
+event:0x51 counters:1,2,3,4 um:zero minimum:500 name:PC_RETURN_MIS_PRED : Return stack misprediction at return stack pop (incorrect target address)
+event:0x52 counters:1,2,3,4 um:zero minimum:500 name:PC_BRANCH_FAILED : Branch prediction misprediction
+event:0x53 counters:1,2,3,4 um:zero minimum:500 name:PC_BRANCH_TAKEN : Any predicted branch that is taken
+event:0x54 counters:1,2,3,4 um:zero minimum:500 name:PC_BRANCH_EXECUTED : Any taken branch that is executed
+event:0x55 counters:1,2,3,4 um:zero minimum:500 name:OP_EXECUTED : Number of operations executed (in instruction or mutli-cycle instruction)
+event:0x56 counters:1,2,3,4 um:zero minimum:500 name:CYCLES_INST_STALL : Cycles where no instruction available
+event:0x57 counters:1,2,3,4 um:zero minimum:500 name:CYCLES_INST : Number of instructions issued in a cycle
+event:0x58 counters:1,2,3,4 um:zero minimum:500 name:CYCLES_NEON_DATA_STALL : Number of cycles the processor waits on MRC data from NEON
+event:0x59 counters:1,2,3,4 um:zero minimum:500 name:CYCLES_NEON_INST_STALL : Number of cycles the processor waits on NEON instruction queue or NEON load queue
+event:0x5A counters:1,2,3,4 um:zero minimum:500 name:NEON_CYCLES : Number of cycles NEON and integer processors are not idle
+event:0x70 counters:1,2,3,4 um:zero minimum:500 name:PMU0_EVENTS : Number of events from external input source PMUEXTIN[0]
+event:0x71 counters:1,2,3,4 um:zero minimum:500 name:PMU1_EVENTS : Number of events from external input source PMUEXTIN[1]
+event:0x72 counters:1,2,3,4 um:zero minimum:500 name:PMU_EVENTS : Number of events from both external input sources PMUEXTIN[0] and PMUEXTIN[1]
+event:0xFF counters:0 um:zero minimum:500 name:CPU_CYCLES : Number of CPU cycles
+
diff --git a/linux-x86/oprofile/arm/armv7/unit_masks b/linux-x86/oprofile/arm/armv7/unit_masks
new file mode 100644
index 0000000..02464a3
--- /dev/null
+++ b/linux-x86/oprofile/arm/armv7/unit_masks
@@ -0,0 +1,4 @@
+# ARM V7 PMNC possible unit masks
+#
+name:zero type:mandatory default:0x00
+ 0x00 No unit mask


This way we can play oprofile on beagleboard already. But you cannot analysis it yet.
Because of that prebuild opreport does not supports ARM_v7. Therefore I downloaded and compile the oprofile 0.9.5. Replace those in prebuild, then we can analysis the data happily.


All of these stuff had been done in 0xdroid, therefore you can play directly with 0xdroid.
The default kernel released in http://downloads.0xlab.org/ currently does not set oprofile flags up therefore you will need to set them up and recompile it.


+ CONFIG_OPROFILE_ARMV7=y
+ CONFIG_OPROFILE=y
+ CONFIG_PROFILING=y
+ CONFIG_HAVE_OPROFILE=y
+ CONFIG_TRACEPOINTS=y


You can throw the vmlinux into a usb storage or SD card with VFAT partition as the first partition.

After booting up 0xdroid beagle-cupcake or beagle-donut, you can run


opcontrol —setup —event=CPU_CYCLES:15000:::1:1 \
—vmlinux=/sdcard/vmlinux \
—kernel-range=0xc0008000,0xcfffffff
echo 16 > /dev/oprofile/backtrace_depth


That will setup the oprofiled to trigger sampling for every 15000 clock cycles. The smaller CPU_CYCLES the more heavy loading of profiling and getting more details. The larger CPU_CYCLES the less detail we get and lower profiling loading.
When I am profiling the overhead of camera preview I found one interesting phenomenon. When I use 150000 as sampling CPU_CYCLES, it's about sampling 30 times per second. I cannot get anything meaningful with the sampling rate. This confused me for a while before I realize it's just about the same frame rate with camera. I always sampled at the same point. Therefore even if we samples a lot, the grid of sampling period should be much smaller than what you want to profile. We always may be blind to some samples. We should be aware of that, and we may need to change various CPU_CYCLES profiling the same topic to get more confidence of the result.

When you are ready to profile just enter

opcontrol --start


And then do whatever you want to profile.
Stop oprofile with

opcontrol --stop


After stopping oprofile, you can use a mini usb cable to download all the samples to the host machine, and analysis them.


On device:
1. plug in usb line between laptop and beagleboard (OTG port)
2. netcfg usb0 up
3. ifconfig usb0 192.168.0.202
On you host:
1. sudo ifconfig usb0 192.168.0.200 # beware nm-applet may breaks it, you can set it up.
2. export ADBHOST=192.168.0.202
3. export PATH={Where you put 0xdroid}/out/host/linux-x86/bin:$PATH
4. pkill adb
5. adb devices # If you can see the device then you can do next step, or you may need to checkout what’s wrong.


Then:


cd {Where you put 0xdroid}
. build/envsetup.sh
setpaths
export OPROFILE_EVENTS_DIR=${PWD}/linux-x86/oprofile/
cd external/oprofile
./opimport_pull /tmp/0xdroid-oprofile


Copy your vmlinux to ${OUT}/symbols

Then you can analysis the whole symbols with

${OPROFILE_EVENTS_DIR}/bin/opreport --session-dir=/tmp/0xdroid-oprofile -p ${OUT}/symbols


After analyzing, we can use ooffice, graphvis, gnuplot, or whatever you like to rework the data. For example:







Happy profiling. :-)

2009年8月31日 星期一

murmur

沒什麼,太久沒寫文章,發個聲,証明自已還活著。

今年是一個充滿挑戰的一年,從籌備到成立 0xlab,接受各式各樣的挑戰,同時面對各方面的問題。和一群優秀的人一起工作,做一堆沒人做過的事,真是刺激極了。

這幾個月的目標是建立一個大家可以一同工作的平台,從設備到開發流程的建立。在大家的努力之下,慢慢的把一些東西建立了起來。對內做了相當多的實驗,對外則是提出了一個可以和大家一同工作的軟體平台。第一次的 code drop 之中,把 beagle-cupcake 調到可以玩,可以快速共同開發,容易整合。準備把心中的 item 慢慢一個一個完成。

把基礎打好了,真正的挑戰才要開始。給自已加油,也為大家加油。

這幾個月中之,發現到自已體力上的極限。刻意的放慢自已的腳步,我們是要做長做久的,不可以一下子就把自已燒掉。小心小心切記切記。對於自已一些 FOSS 的案子,真是對使用者感到抱歉,只要有時間和體力,我就會回來看的。 XD

在 lab 進入軌道後,接下來最重要的目標反而是調整好自已:管理好自已的情緒,讓自已更快樂、給自已更多時間,早點下班,多運動,讓自已更健康、訓練自已的表達能力,讓自已更能夠清楚的表達出想法。

希望能給大家和自已一個更好的 Tick. XD

2009年4月27日 星期一

0xlab is opening

0xlab looks very like 0x'1'ab and 0x1ab is 427. Therefore we choose this day to announce our lab. :)
http://0xlab.org

We are a group of software engineers who have strong passion in Free Open Source Software. We believe the power of knowledge and creativity, and we think we can do something very interesting and valuable.

2009年3月29日 星期日

Beagleboard demo

Demo for the last four days developement.






[beagleboard hacking note] HDMI monitor

I tried to use my LG TV as the monitor of beagleboard for three days, after some turning it works fine with Angstrom distribution. However, not in Android.
I tried to hacked around the driver/video/omap/lcd_omap3beagle.c but without successful. Just cannot see the Android screenshot. :(
After a long try, I almost sure every setting in my kernel is correct.And by checking the log, Android run very well. I thought it may be a problem from my TV, therefore I bring my beagle board to a 3C market and ask for testing a new HDMI monitor. It worked like a charm!! Oh my god, the LG TV waste a lot of my time. :( I bought that monitor without second though immediately.

Finally, I can play Android with my beagleboard. :-)
From beagleboard


But it seem need some other hack to simulate the touch panel events. I am considering write a fake device and sending touch panel event to kernel. (Is that a good idea? I doubt. Any Idea?)

A tiny program read signal from rs232, and translate message to positions and write to a device, and that device triggers input event report of touch panel. XD Hmm.... It's a pure dirty hack. Any suggestion? I don't want to buy another touch panel. I already bought too many stuff. Orz...

murmuring

2009年3月28日 星期六

[beagleboard hacking note] OE references

OE: openembedded a very powerful and complex build system.
beagleboard google code beagleboard info and download center.
Angstrom Distribution a good embedded distribution maintained by Koen, and that is what I am mainly used, and hacking on.

DSS reference a very good document to control the omap fbs


my local.conf of building beagleboard demo image

Filename: local.conf

MACHINE = "beagleboard"
DISTRO = "angstrom-2008.1"
BUILD_ARCH = "x86_64"
#INHERIT += "rm_work"
PARALLEL_MAKE = "-j 3"
BB_NUMBER_THREADS = "1"
TMPDIR = "/home/tick/OE/build/tmp"
BBFILES := "/home/tick/OE/openembedded/recipes/*/*.bb"


> bitbake beagleboard-demo-image
and have fun

[beagleboard hacking note] Bluetooth network

Because of using USB OTG mode, connecting beagleboard with keyboard and mouse. I cannot use usb0 as ethernet card. Therefore, I can use bluetooth dongle to simulate ethernet card.

1. modify the kernel configure, to allow usb bluetooth dongle works.
@@ -455,7 +455,7 @@ CONFIG_BT_HIDP=y
#
# Bluetooth device drivers
#
-# CONFIG_BT_HCIBTUSB is not set
+CONFIG_BT_HCIBTUSB=y
CONFIG_BT_HCIBTSDIO=y
# CONFIG_BT_HCIUART is not set
CONFIG_BT_HCIBCM203X=y

2. After boot, plug the dongle.
determin if bluetooth device detected or not.
> hcitool dev
scan surrounding bluetooth devices
> hcitool scan
If everything goes fine, we can try to connect bluetooth devices (e.g. mouse)

3. make your laptop a network access point (NAP) a very good document you should check
On your laptop with bluetooth RF on
a. turn off /etc/init.d/bluetooth
> /etc/init.d/bluetooth stop
b. modprobe bnep
c. pand -s -r NAP
On beagleboard:
a. finding the baddr of your laptop
> hcitool scan
b.connect to your laptop
>pand -c XX:XX:XX:XX:XX:XX:XX
c. Setup your beagleboard network
> ifconfig bnep0 192.168.0.202
> route add default gw 192.168.0.200
d. On your laptop set, let your laptop becomes an NAT gateway:
> ifconfig bnep0 192.168.0.200
> echo 1 > /proc/sys/net/ipv4/ip_forward
> iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j MASQUERADE
Enjoy the wireless network :-)

[beagleboard hacking note] USB OTG line

Beagleboard supports USB OTG mode, however beagleboard cannot run OTG mode with normal 5 pin mini USB lines.

It needs to short pin 4 and 5. and so that you can play with OTG mode. Therefore I bought a B type mini usb line and remove the cover and short pin 4 and 5, and I can play with OTG mode happily.

From beagleboard


From beagleboard

BTW, beagleboard can play as client with normal mini usb to USB A line as ethernet card. (USB0)

[beagleboard hacking note] Null modem

The first step of hacking beagleboard. You need to connect to beagleboard first.
.You will need a null modem line to connect beagleboard RS232 port and your PC.

My way is very straight forward: just buy a USB to RS232 line, three thin wires, one 2.5mm 5x2 pin slot, and a RS232 female head.

From beagleboard


Actually you only need to connect three wires, pin2 pin3 and pin5, and remember switch pin 2 and 3. Check here!

After made the line for beagleboard, you can use cu , minicom, or even screen to connect beagleboard. Baud rate is 115200n8.

From beagleboard


Therefore you can access the beagleboard u-boot and console.

2009年3月15日 星期日

Taipei App Engine Sprint 2009

感謝 Ping 的邀請,我們團隊的其中三人昨天去 Google 玩了一整天。
也做了一個小玩具 (我就知道大家會把它拿來找正妹)和大家分享。
享受了腦力激盪、高速開發及實踐想像力的快感。
當然,也吃了過量的 Hogan Doz,和鼎泰豐。
感謝 Google Taipei 舉辦這個好玩的活動。
對我們來說是一次非常好的經驗。

感謝大家的欣賞我們的作品和團員之間的無間合作,很高興得到了比賽的第一名。
特別感謝昨日加入我們的 Denial ,補足了我們在於 Web design 經驗上的不足。
畢竟,一群做 Linux Embedded System 的人突然跑來玩 Web,缺乏相當多的 domain knowledge。

昨天不只一次被問到:你們是如何做到一天之內衝出一個網站的? 你們是如何分工的?

其實這也道出了相當多人的相同問題。
這個問題回家想了很後,其實我的答案還是:團隊合作。

事實上大家都知道團隊合作的重要性,可是不知道如何做到。
其實,我個人認為這是沒有標準答案的。

試著把自已的想法寫下來,供自已分析和與大家分享。

人最重要:
當初決定留在台灣,就是抱著一個願望:在台灣,打造出一個有國際一流水準的軟體團隊。
我個人對於自已的 career path 的許多重大決定也是為了完成這個夢想。
很幸運的,在多年的尋覓之後,我們找到了一些有共同想法的伙伴,一群想追求一流而且真的很努力的 FOSS developer 找到了彼此,組成團隊。

事實上,我們之中的任何一個人,都是可以獨當一面的軟體工程師,技術能力也和歐美 hackers 同步。但我們也相當了解,在現在的軟體世界中,要和世界一流的團隊比,我們每個人的時間體力和專長真的不夠多。要真的做出什麼,我們必需互相信賴。
每一個人的專長都不相同,興趣領域也不同,不過都有所專精。
最重要的,信任和分享是我們相當大的特色。

John 特色擅長於洞悉情勢,有相當驚人的觀察力,對問題提出精確的看法
Tick 擅長結構性的思考,演算法選用,軟體系統架構分析和軟體風險估計及開發
Olv 對於新技術的理解能力一流,對於面對的技術可以快速的確實掌握
Erin 擅長提出破壞性思考,提供大家不同面向的思考和刺激
Jeremy 擅長把任務完成,面對問題可提出相當好的分析和實作
Julian 擅長於感性的思考,為技術帶來來自外太空的創意和美感

昨天是 Olv, Erin 和我三人受邀參加活動。面對這個題目,三人對於 App engine 各自 survey 結束後,我們開了一次的 brain storm meeting。我可以對不同題目所需要的技術可以快速的提供 scope 和風險分析,而 Erin 提出了相當多很有意思的想法和 Idea,Olv 很快速的理解問題的核心並提出更進一步的看法。當 Erin 說出 "依時間搜尋照片" 七個字時,我和 Olv 兩人都突然不說話了,思考著這個 idea 的可能性。害 Erin 以為這個 idea 不好。我和 Olv異口同聲的說出,“不,這個 idea 很棒。” 是的,這個題目的可能性很高,還不知有人做過,資料相依性應該很高,也是我們能力所及的。
再來就依著這個題目開始做了各種可能性的 brain storm。這是一個我們三個人一天可以做完的題目,我列出這個題目及各種可能性所需的所有技術項目,針對各個項目提出可選擇的技術和風險分析,Olv 針對著這題目提出許多更進一步的看法,和可能性。我們最大的風險是,我們沒有 html 和 javascript 的專長。
題目和項目決定後,我提出一個可以從很小很小的結構開始長大的軟體架構提出 API,把所有問題切成小塊小塊的,並立刻把 framework 實作出來。一個小時後, Olv 和 Erin 就可以進入開發,大約在兩個小時內,我們已經進入遞迴開發的階段,我維持軟體架構的彈性,Olv 神快的把每個小問題解掉,並找出我沒有想清楚的地方提出漂亮的修正。
很幸運的,昨天在活動中找到了一位 web 的開發者 Denial 加入我們的開發,對於 html 及javascript 的風險立刻變得相當的低。活動開始後,我們立刻把開發環境架好,開始把針對 web 這方面開始開發。並提出每個項目完成優先順續,和重要性,並把工作分配下去。在開發中,我們快速的交換各自分配到的 topic 所學到的 infomation。提出問題,和分享自已所了解的東西。其中“腦力激盪、分析、尋找答案、提出想法、實作”是不停的約以一個小時為週期巡迴發生。開始兩個多小時後我分配到的部份就做完了,過沒多久 Olv 的部份也實作完成,再來就開始把 nice to have 的部份一一補上,測試,美化以及互相 support。幫忙把沒做完的地方做出來。
因為得到了 Denial 的技術支援,和 Google Jeff 的 information sharing,我們做出來的比
本來估三人個可以做到的部份還要多。還把本來列為 nice to have 的地理資訊部份實作了出來。Olv 在完成工作後,也開始發揮幽默,把我們本來很工程師的形式的網頁改寫成山寨 Google theme。最後兩小時,大家全力衝刺收尾和 javascript 的部份。

這也是我們團隊成員第一次一起參加這種限時的軟體比賽,証明了我們的團隊能力,對於我們團隊有相當大鼓舞作用,也一再的讓我們深深的體會到,雖然每個人的能力都很不錯,如果能團隊運作起來威力是加乘的。

最後,感謝 Google 舉辦這個活動,和大家的欣賞。

2009年1月12日 星期一

Eagle outside my window!

When I was thinking about an algorithm of project at home. I heard some noise just outside the window. All my cats were rushing around like crazy. After some while, the noise does not stop, and I decide to take a look about that. I was stunned by what I saw. An eagle is just standing out side my window, eating a dove!! I live in Taipei, a mega-city without eagle for a long long time. When I was a boy, I live in the suburb of a small city, Chai-Yi, there were always eagle on the sky. I have not seen eagle in nature for a long time since I move to Taipei.
Suddenly, a eagle is standing out side my window. I am so surprised about this. Maybe the environment is getting better gradually.
It eyes are so beautiful, I have never observe an eagle so closely, less the 1 meteor. But while it's eating, it remind me it's a hunter. It can kill my cats easily with it's claw. This point made me a little bit nervous. Anyway beside of this, I am very happy to see an eagle out side the window.





















2009年1月2日 星期五

My color

Your rainbow is shaded blue.

 
 
 
 
 
 
 

What is says about you: You are a tranquil person. You appreciate friends who get along with one another. You share hobbies with friends and like trying to fit into their routines.

Find the colors of your rainbow at spacefem.com.


還蠻妙的~

2008年12月27日 星期六

墨子

近來看到了一些事。感謝友人介紹墨子給我。以古鑒今,讀得我汗流直下…不得不佩服古人的智慧,真的是真知灼見。歷史果然是以不同的面貌一再重演。今日看著一些人花了大把大把的銀子,得到的卻是一個謊言。雖然花了很多工夫來說服自己,這些是別人的錢,而且這也不在手臂範圍內,在自己的範圍內對得起自己,對得起投資人。投資人也不是笨蛋,如果事態這麼明顯了還看不出來,他們自己就要承受風險。看著台灣投資人的錢就這樣的被糟蹋,揮霍,心裏相當的難過。
一場大卡司的真實戲碼在眼前上映著,一面難過著一個看似美好的機會在眼前破滅, 也一面慶興著自己在年輕之時就可以上到這麼昂貴的一課,學到相當寶貴的經驗。更加了解在夢想這條路上有那些陷阱,和風險。在這場大卡司的戲碼中,看著一個有理想有才華的人被小人包圍,看著他的恐懼、看著他逃避、封閉自我、在精神上吸毒、不停的欺騙、最後沉淪,變得和他身旁的人沒兩樣。我們雖然被一些人欺騙、惡搞、看似受害者,雖然我們幫不上什麼忙,在這恐怖的經驗之中替他感到痛心,替投資時間、金錢於他的人感到可惜,也學得深刻的教訓,也許能保持自我且依然年輕的我們才是最大的受益者。

這讓我想起了第一份工作的公司所標榜的企業精神:"誠信正直"。真的說得很好。

夢想讓我們充滿熱情、創意讓我們與眾不同、技術讓我們拿到門票、運氣讓我們得以進入門檻,而要真正的成功:“誠信正直” 真的很重要。

這真的很難,也很重要。我想…成功的人那麼少,也許就是要真正落實實在太難了吧,不然也不用拿出來標榜。
修鍊、修鍊…

國高中時,完全不讀不下去的古文。沒想到在經歷了一些事之後,讀起來卻是異常的深刻…熟悉…
念書、念書…

墨子、卷一


親士
入國而不存其士,則亡國矣。見賢而不急,則緩其君矣。非賢無急,非士無與慮國,緩賢忘士而能以其國存者,未曾有也。

昔者文公出走而正天下,桓公去國而霸諸侯,越王句踐遇吳王之醜,而尚攝中國之賢君。三子之能達名成功於天下也,皆於其國抑而大醜也。太上無敗,其次敗而有以成,此之謂用民。

吾聞之曰:“非無安居也,我無安心也。非無足財也,我無足心也。”是故君子自難而易彼,眾人自易而難彼,君子進不敗其志,內究其情,雖雜庸民,終無怨心, 彼有自信者也。是故為其所難者,必得其所欲焉,未聞為其所欲,而免其所惡者也。是故偪臣傷君,諂下傷上。君必有弗弗之臣,上必有詻詻之下。分議者延延,而 支苟者詻詻,焉可以長生保國。

臣下重其爵位而不言,近臣則喑,遠臣則唫,怨結於民心,諂諛在側,善議障塞,則國危矣。桀紂不以其無天下之士邪?殺其身而喪天下。故曰:“歸國寶,不若獻賢而進士。

今有五錐,此其銛,銛者必先挫。有五刀,此其錯,錯者必先靡,是以甘井近竭,招木近伐,靈龜近灼,神蛇近暴。是故比干之殪,其抗也;孟賁之殺,其勇也;西施之沈,其美也;吳起之裂,其事也。故彼人者,寡不死其所長,故曰:“太盛難守也。”

故雖有賢君,不愛無功之臣;雖有慈父,不愛無益之子。是故不勝其任而處其位,非此位之人也;不勝其爵而處其祿,非此祿之主也。良弓難張,然可以及高入深; 良馬難乘,然可以任重致遠;良才難令,然可以致君見尊。是故江河不惡小谷之滿己也,故能大。聖人者,事無辭也,物無違也,故能為天下器。是故江河之水,非 一水之源也。千鎰之裘,非一狐之白也。夫惡有同方取不取同而已者乎?蓋非兼王之道也。是故天地不昭昭,大水不潦潦,大火不燎燎,王德不堯堯者,乃千人之長也。

其直如矢,其平如砥,不足以覆萬物,是故溪陝者速涸,逝淺者速竭,墝埆者其地不育。王者淳澤不出宮中,則不能流國矣。


修身
君子戰雖有陳,而勇為本焉。喪雖有禮,而哀為本焉。士雖有學,而行為本焉。是故置本不安者,無務豐末。近者不親,無務來遠。親戚不附,無務外交。事無終始,無務多業。舉物而闇,無務博聞。

是故先王之治天下也,必察邇來遠,君子察邇而邇脩者也。見不脩行,見毀,而反之身者也,此以怨省而行脩矣。譖慝之言,無入之耳,批扞之聲,無出之口,殺傷人之孩,無存之心,雖有詆訐之民,無所依矣。

是故君子力事日彊,願欲日逾,設壯日盛。君子之道也,貧則見廉,富則見義,生則見愛,死則見哀。四行者不可虛假,反之身者也。藏於心者,無以竭愛。動於心者,無以竭恭。出於口者,無以竭馴。暢之四支,接之肌膚,華髮隳顛,而猶弗舍者,其唯聖人乎!

志不彊者智不達,言不信者行不果。據財不能以分人者,不足與友。守道不篤,偏物不博,辯是非不察者,不足與游。本不固者末必幾,雄而不脩者,其後必惰,源濁者流不清,行不信者名必秏。 名不徒生而譽不自長,功成名遂,名譽不可虛假,反之身者也。務言而緩行,雖辯必不聽。多力而伐功,雖勞必不圖。慧者心辯而不繁說,多力而不伐功,此以名譽 揚天下。言無務多而務為智,無務為文而務為察。故彼智無察,在身而情,反其路者也。善無主於心者不留,行莫辯於身者不立。名不可簡而成也,譽不可巧而立 也,君子以身戴行者也。思利尋焉,忘名忽焉,可以為士於天下者,未嘗有也。


所染
子墨子言見染絲者而嘆曰:“染於蒼則蒼,染於黃則黃。所入者變,其色亦變。五入必而已,則為五色矣。故染不可不慎也。”

非獨染絲然也,國亦有染。舜染於許由、伯陽、禹染於皋陶、伯益,湯染於伊尹、仲虺,武王染於太公、周公。此四王者所染當,故王天下,立為天子,功名蔽天地。舉天下之仁義顯人,必稱此四王者。

夏桀染於干辛、推哆,殷紂染於崇侯、惡來,厲王染於厲公長父、榮夷終,幽王染於傅公夷、蔡公穀。此四王者所染不當,故國殘身死,為天下僇。舉天下不義辱人,必稱此四王者。

齊桓染於管仲、鮑叔,晉文染於舅犯、高偃,楚莊染於孫叔、沈尹,吳闔閭染於伍員、文義,越句踐染於范蠡大夫種。此五君者所染當,故霸諸侯,功名傅於後世。

范吉射染於長柳朔、王胜,中行寅染於籍秦、高彊,吳夫差染於王孫雒、太宰嚭,智伯搖染於智國、張武,中山尚染於魏義、偃長,宋康染於唐鞅、佃不禮。此六君者所染不當,故國家殘亡,身為刑戮,宗廟破滅,絕無後類,君臣離散,民人流亡。舉天下之貪暴苛擾者,必稱此六君也。

凡君之所以安者,何也?以其行理也,行理性於染當。故善為君者,勞於論人,而佚於治官。不能為君者,傷形費神,愁心勞意,然國逾危,身逾辱。此六君者,非不重其國,愛其身也,以不知要故也。不知要者,所染不當也。

非獨國有染也,士亦有染。其友皆好仁義,淳謹畏令,則家日益,身日安,名日榮,處官得其理矣,則段干木、禽子、傅說之徒是也。其友皆好矜奮,創作比周,則家日損,身日危,名日辱,處官失其理矣,則子西、易牙、豎刀之徒是也。《詩》曰:“必擇所堪。”必謹所堪者,此之謂也。


法儀
子墨子曰:“天下從事者,不可以無法儀,無法儀而其事能成者無有也。雖至士之為將相者,皆有法,雖至百工從事者,亦皆有法。百工為方以矩,為圓以規,衡以水,直以繩,正以縣。無巧工、不巧工,皆以此五者為法。巧者能中之,不巧者雖不能中,放依以從事,猶逾己。故百工從事,皆有法所度。”

今大者治天下,其次治大國,而無法所度,此不若百工辯也。然則奚以為治法而可?當皆法其父母,奚若?天下為 父母者眾,而仁者寡,若皆法其父母,此法不仁也。法不仁不可以為法,當皆法其學,奚若?天下之為學者眾,而仁者寡,若皆法其學,此法不仁也。法不仁不可以 為法,當皆法其君,奚若?天下之為君者眾,而仁者寡,若皆法其君,此法不仁也。法不仁不可以為法。故父母、學、君三者,莫可以為治法。

然則奚以為治法而可?故曰莫若法天。天之行廣而無私,其施厚而不德,其明久而不衰,故聖王法之。既以天為法,動作有為,必度於天,天之所欲則為之,天所不 欲則止。然而天何欲何惡者也?天必欲人之相愛相利,而不欲人之相惡相賊也。奚以知天之欲人之相愛相利,而不欲人之相惡相賊也?以其兼而愛之,兼而利之也。 奚以知天兼而愛之,兼而利之也?以其兼而有之,兼而食之也。

今天下無大小國,皆天之邑也。人無幼長貴賤,皆天之臣也。此以莫不犓羊牛、豢犬豬,絜為酒醴粢盛,以敬事天,此不為兼而有之,兼而食之邪?天苟兼而有食之,夫奚說以不欲人之相愛相利也?故曰:“愛人利人者,天必福之,惡人賊人者,天必禍之。”曰:“殺不辜者,得不祥焉。夫奚說人為其相殺而天與禍乎?是以知天欲人相愛相利,而不欲人相惡相賊也。”

昔之聖王禹、湯、文、武,兼愛天下之百姓,率以尊天事鬼,其利人多,故天福之,使立為天子,天下諸侯皆賓事之。暴王桀、紂、幽、厲,兼惡天下之百姓,率以詬天侮鬼。其賊人多,故天禍之,使遂失其國家,身死為僇於天下。後世子孫毀之,至今不息。故為不善以得禍者,桀、紂、幽、厲是也。愛人利人以得福者,禹、湯、文、武是也。愛人利人以得福者有矣,惡人賊人以得禍者亦有矣!


七患
子墨子曰:國有七患。七患者何?城郭溝池不可守而治宮室,一患也。邊國至境四鄰莫救,二患也。先盡民力無用之功,賞賜無能之人,民力盡於無用,財寶虛於待客,三患也。仕者持祿,游者愛佼,君脩法討臣,臣懾雨不敢拂,四患也。君自以為聖智而不問事,自以為安彊而無守備,四鄰謀之不知戒,五患也。所信不忠,所忠不信,六患也。畜種菽粟不足以食之,大臣不足以事之,賞賜不能喜,誅罰不能威,七患也。以七患居國,必無社稷;以七患守城,敵至國傾。七患之所當,國必有殃。

凡五穀者,民之所仰也,君之所以為養也。故民無仰則君無養,民無食則不可事。故食不可不務也,地不可不力也,用不可不節也。五穀盡收,則五味盡御於主,不 盡收則不盡御。一穀不收謂之饉,二穀不收謂之旱,三穀不收謂之凶,四穀不收謂之餽,五穀不收謂之饑。歲饉,則仕者大夫以下皆損祿五分之一。旱,則損五分之 二。凶則損五分之三。餽,則損五分之四。饑,則盡無祿,稟食而已矣。故凶饑存乎國,人君徹鼎食五分之三,大夫徹縣,士不入學,君朝之衣不革制,諸侯之客,四鄰之使,雍飧而不盛,徹驂騑,塗不芸,馬不食粟,婢妾不衣帛,此告不足之至也。

今有負其子而汲者,隊其子於井中,其母必從而道之。今歲凶,民饑道餓,重其子此疚於隊,其可無察邪?故時年歲善,則民仁且良;時年歲凶,則民吝且惡。夫民 何常此之有?為者疾,食者眾,則歲無豐。故曰:“財不足則反之時,食不足則反之用。”故先民以時生財,固本而用財,則財足。故雖上世之聖王,豈能使五穀常 收而旱水不至哉?然而無凍餓之民者,何也?其力時急而自養儉也。故《夏書》曰:“禹七年水。”《殷書》曰:“湯五年旱。”此其離凶餓甚矣。然而民不凍餓者,何也?其生財密,其用之節也。

故倉無備粟,不可以待凶饑;庫無備兵,雖有義不能征無義;城郭不備全,不可以自守;心無備 慮,不可以應卒。是若慶忌無去之心,不能輕出。夫桀無待湯之備,故放;紂無待武之備,故殺。桀、紂貴為天子,富有天下,然而皆滅亡於百里之君者,何也?有 富貴而不為備也。故備者,國之重也;食者,國之寶也;兵者,國之爪也。城者所以自守也。此三者國之具也。

故曰:以其極賞,以賜無功,虛其府庫,以備車馬、衣裘、奇怪,苦其役徒,以治宮室觀樂;死又厚為棺槨,多為衣裘。生時治臺榭,死又脩墳墓。故民苦於外,府庫單於內,上不厭其樂,下不堪其苦。故國離寇敵則傷,民見凶饑則亡,此皆備不具之罪也。且夫食者,聖人之所寶也。故《周書》曰:“國無三年之食者,國非其國也;家無三年之食者,子非其子也。”此之謂國備。

辭過
子墨子曰:古之民,未知為宮室時,就陵阜而居,穴而處,下潤濕傷民,故聖王作為宮室。為宮室之法,曰:室高足以辟潤濕,邊足以圉風寒,上足以待雪霜雨露,宮牆之高,足以別男女之禮,謹此則止。凡費財勞力,不加利者,不為也。役,脩其城郭,則民勞而不傷;以其常正,收其租稅,則民費而不病。民所苦者非此也,苦於厚作斂於百姓。是故聖王作為宮室,便於生,不以為觀樂也。作為衣服帶履,便於身,不以為辟怪也,故節於身,誨於民,是以天下之民可得而治,財用可得而足。

當今之主,其為宮室則與此異矣。必厚作斂於百姓,暴奪民衣食之財,以為宮室,臺榭曲直之望,青黃刻鏤之飾。為宮室若此,故左右皆法象之,是以其財不足以待凶饑、振孤寡,故國貧而民難治也。君實欲天下之治,而惡其亂也,當為宮室不可不節。

古之民,未知為衣服時,衣皮帶茭,冬則不輕而溫,夏則不輕而凊。聖王以為不中人之情,故作誨婦人治絲麻,梱布絹,以為民衣。為衣服之法:冬則練帛之中,足以為輕且暖;夏則絺綌之中,足以為輕且凊,謹此則止。故聖人之為衣服,適身體和肌膚而足矣。非榮耳目而觀愚民也。當是之時,堅車良馬不知貴也,刻鏤文采,不知喜也。何則?其所道之然。故民衣食 之財,家足以待旱水凶饑者,何也?得其所以自養之情,而不感於外也。是以其民儉而易治,其君用財節而易贍也。府庫實滿,足以待不然。兵革不頓,士民不勞, 足以征不服。故霸王之業,可行於天下矣。

當今之主,其為衣服則與此異矣,冬則輕煥,夏則輕凊,皆已具矣。必厚作斂於百姓,暴奪民衣食之財,以為錦繡文采靡曼之衣,鑄金以為鉤,珠玉以為珮,女工作文采,男工作刻鏤,以為身服,此非云益煥之情也。單財勞力,畢歸之於無用也,以此觀之,其為衣服非為身體,皆為觀好,是以其民淫僻而難治,其君奢侈而難諫也。夫以奢侈之君,御妤淫僻之民,欲國無亂,不可得也。君實欲天下之治而惡其亂,當為衣服不可不節。

古之民未知為飲食時,素食而分處,故聖人作誨男耕稼樹藝,以為民食。其為食也,足以增氣充虛,彊體適腹而巳矣。故其用財節,其自養儉,民富國治。今則不 然,厚作斂於百姓,以為美食芻豢,蒸炙魚鱉,大國累百器,小國累十器,前方丈,目不能遍視,手不能遍操,口不能遍味,冬則凍冰,夏則餲饐,人君為飲食如此,故左右象之。是以富貴者奢侈,孤寡者凍餒,雖欲無亂,不可得也。君實欲天下治而惡其亂,當為食飲,不可不節。

古之民未知為舟車時,重任不移,遠道不至,故聖王作為舟車,以便民之事。其為舟車也,完固輕利,可以任重致遠,其為用財少,而為利多,是以民樂而利之。故法令不急而行,民不勞而上足用,故民歸之。

當今之主,其為舟車與此異矣。完固輕利皆已具,必厚作斂於百姓,以飾舟車。飾車以文采,飾舟以刻鏤,女子廢其紡織而脩文采,故民寒。男子離其耕稼而脩刻鏤,故民饑。人君為舟車若此,故左右象之,是以其民饑寒並至,故為姦邪。姦邪多則刑罰深,刑罰深則國亂。君實欲天下治而惡其亂,當為舟車,不可不節。

凡回於天地之間,包於四海之內,天壤之情,陰陽之和,莫不有也,雖至聖不能更也。何以知其然?聖人有傳:天地也,則曰上下;四時也,則曰陰陽;人情也,則 曰男女;禽獸也,則曰牡牝雄雌也。真天壤之情,雖有先王不能更也。雖上世至聖,必蓄私,不以傷行,故民無怨。宮無拘女,故天下無寡夫。內無拘女,外無寡 夫,故天下之民眾。當今之君,其蓄私也,大國拘女累千,小國累百,是以天下之男多寡無妻,女多拘無夫,男女失時,故民少。君實欲民之眾而惡其寡,當蓄私不可不節。

凡此五者,聖人之所儉節也,小人之所淫佚也。儉節則昌,淫佚則亡,此五者不可不節。夫婦節而天地和,風雨節而五穀孰,衣服節而肌膚和。


三辯
程繁問於子墨子曰:“夫子曰:‘聖王不為樂’,昔諸侯倦於聽治,息於鐘鼓之樂;士大夫倦於聽治,息於竽瑟之樂;農夫春耕、夏耘、秋斂、冬藏,息於瓴缶之樂。今夫子曰:‘聖王不為樂’,此譬之猶馬駕而不稅,弓張而不弛,無乃非有血氣者之所不能至邪?”

子墨子曰:“昔者堯舜有茅茨者,且以為禮,且以為樂。湯放桀於大水,環天下自立以為王,事成功立,無大後患,因先王之樂,又自作樂,命曰《護》,又脩《九招》。武王勝殷殺紂,環天下自立以為王,事成功立,無大後患,因先王之樂,又自作樂,命曰《象》。周成王因先王又自作樂,命曰《騶虞》。周成王之治天下也,不若武王。武王之治天下也,不若成湯。成湯之治天下也,不若堯舜。故其樂逾繁者,其治逾寡。自此觀之,樂非所以治天下也。”

程繁曰:“子曰:‘聖王無樂’。此亦樂已,若之何其謂聖王無樂也?”子墨子曰:“聖王之命也,多寡之。食之利也,以知饑而食之者智也,因為無智矣。今聖有樂而少,此亦無也。”

2008年12月14日 星期日

迷人的 git

如果你常常寫 code,一定會遇到一種情況:寫改目前會動的 code,又怕會改壞…這時,就是 SCM (Source Code Management) 程式的時候了。

前一陣子,不知怎麼的,好幾個朋友問我,他們公司/專案要選 SCM,要選用那一個呢?

SCM 百百種… CVS SVN SVK Monotone bitkeeper git etc. etc.
要用那一個比較好呢?

在過去…我會說 SVN, SVN 比 CVS 方便多了,流水號的機制讓開發過程相當的清晰。
現在我強烈推薦 git
自從用了 git 之後~我已經離不開 git 了…

為什麼呢?
1. 因為我用 notebook 寫 code, 這表示我可能會在辦公室寫,在家寫,睡不著時在床上寫,在無聊的會議中寫,在坐車時寫,在山林中寫… 而且我寫的東西大多要merge 回 upstream。可是很多地方是沒有網路的。或是網路不好…如果我用SVN 的話…就必需開始用 quilt寫 patch 了…管理 Code 變得相當的麻煩。
Git 是一個分散式的 SCM,也就是在你目前工作的環境下,就是一個完整的 source code repository. 當你從網路上用 git 抓下 code 的同時,你已經把完整的開發 tree 抓回來,放在你的電腦之中了…而 commit code 時也是 commit 到你 local 端之中。所以你就可以一直寫,到處寫,直到你有網路之時再一次 push 回去…
2. 我很愛改 Code,而 git 的版本管理是用 patch 做出來的,也就是說 branch 會變得相當的容易。當我想做任何風險較大的變動時,可以先開一個 branch 出來,在裏面惡搞一翻。如果結果不錯的話,就 merge 回主要的 branch。
3. git 超級快,因為 git 把所有的 patch 都抓回來了,要做 diff ,翻 log 就變成超級快速而且穩定的事。
4. 支援 SVN 和 CVS,git-svn 可以把 svn 之中的所有 commit 變成 git 之中的一個 branch。
也就是不管upstream 用的是 SVN or CVS ,我都可以用 git 來管理。事實上,還有一些更好玩的玩法
5. SHA1-hash 的版本管理方式,讓 git 跳脫 SVN 之類強烈線性的版本管理…可以 rebase, cherry-pick ...
6. 開始一個 repository 超級方便,git init 就好了

Anyway 說了這麼多好處…怎麼用呢?就先給 link 嘍…
戒色夫 "我愛 Git"
Git User manual

我不打算在這寫另一個 manual 就寫幾個個人覺得很實用的 use cases.
1.做實驗
當你的 master branch 可以 run,但你想要對某個演算法大修時…
a. git checkout -b test_xxxx
b. 大修你的演算法…且 做細部的 commit,直到完成
c. git checkout master 回到本來的 master
d. git pull 把再新的 master 拉回來
e. git checkout test_xxxx
f. git rebase master 把再新的 master commit rebase 上去…可能會要解 conflict
(c, d, e, f, 可變成 git fetch origin/master; git rebase -i origin/master)
g. git checkout master
h.1 git rebase test_xxxx 把 test_xxxx 的東西再 rebase 過來
h.2 git cherry-pick xxxxxx 把某個 patch 挑過來
i. git push 把修改送回main stream

2.用 git-svn 搬 SVN repository
如 project P 要從 repository A 搬到 B 玩法如下
a. mkdir A_svn; pushd A_svn; git svn init http://A/trunk/ ;git svn fetch; popd
b git clone file://`pwd`/A_svn B_svn
c. cd B_svn; git svn init http://B/trunk/
d. git checkout -b master_tmp
e. git svn init http://B/trunk/ ; git svn fetch
f. git checkout -b svn --track git-svn
g. git checkout master; git rebase svn
h. git-rev-list master_tmp (suppose the last line is 532d2f35aa73331d409475efa84c00a1afa0e1a0)
i. git svn set-tree 532d2f35aa73331d409475efa84c00a1afa0e1a0
j. git rebase master_tmp; git svn dcommit

3. 粉飾太平
當 git commit 了一些笨笨的 code
可以用 git rebase -i xxxx 來拿掉/合並 一些 commit

2008年11月3日 星期一

心目中的 Linux development 課程建議

早上讀了一封某國立大學資訊系教授的信,百感交集。也不想評論些什麼…
就說說自已的想法罷了
我個人覺得,一個活在 AC 2008 Embedded GNU/Linux Software Developer 要會以下一些東西。
我認為…這只是基礎。這些會了,再來談創意…
光是空想,手上沒有工具,或是有工具不會用…只是白搭。

技術方面
* C programming
-- study forever...
-- Learning how to tracing code - Learning from the master

* Shell programming
-- Bash & awk & sed & grep & diff & patch
-- Python | Perl | Ruby

* Software testing
-- smoke test
-- boundary test
-- stress test
...

* cross toolchain.
-- Static link & Share Library
-- ABI
-- Dependency tree
-- How kernel execute programs & ELF study

* SCM
-- git
-- svn
-- cvs
-- patch
---- quilt

* Distribution structure
-- How system boots
-- Build a distribution from scratch

* Misc tools
-- gdb
-- valgrind
-- gprof
-- gcov
-- doxygen
-- autotools

文化方面
* Mailing List
* Bugzilla
* Hacker ethics
* IRC
* English
* Eat your dog food
* Coding style
* Knowledge management skill - search & skip

很明顯以上不是一門課就可以上完的,不過可以分散在幾門課之中。
0. 計概
1. OS
2. C programming
3. System programming
4. XXX 專題

作為:
. 老師自已開始始用 GNU/Linux or any Unix like system 把自已丟進 FOSS 的世界…會更有 fu

. 鼓勵學生在大一時,就學習用 GNU/Linux,以及使用公開格式文件。
學校為什麼要為 MS 做免費的廣告呢?
要求學生使用不是每個人都買得起的東西,使用不公開格式的文件…
這是不道德也不經濟的。
學生也可以真正的體會 FOSS 的文化,有興趣的人還可以真正深入了解系統的運作。

. 要求學生使用 gpg keys 以及使用 ssh key

. 作業用 git+ssh 繳交…

. 教導學生使用 Unix 下的一些超級工具
-- 一旦學會了…一輩子受益。可惜…很多老師自已不會,學一下吧。 ~>_<~

. 要求學生加入有名的 open source 的專案,成為期中作業。(以 commit log 為準)

. OS 課程之中,指派學生 Trace Linux kernel code ,對照 textbook 內容,且 present 給大家,作為作業。

. Algorithm 課程中,指派學生 Trace glibc | stdc | stdc++ | java library code ,使用,且學習用它們的 API 自已 cleanroom 一個出來,用 test framwork 來測。

. C programming 中,學生的每個程式作業,都要擺出 autotools 的架式,以及使用 doxygen 產生文件 (或不同工具)

. RTFM, 選一些重要的 manual 叫學生讀,學會讀文件和學會讀 code 是一樣重要的。

. 出幾題如 pythonchallenge 之類的上機作業給學生…

. 要求程式作業要先交 .h 檔,先上 git

. 鼓勵學生訂 mailing list, 為課程開 mailing list,在上面討論課程和作業

. 老師也要學習新把戲 ;-) 如果您在教 GNU/Linux development 而上面的任何 Item 不清楚的話,或不了解怎麼做的話…也許要再 update 一下您的 knowledge 了。

基礎很重要。手中有工具,才能玩遊戲。

小弟其實懂得不多,每天也還忙著學新東西,不過看完了某教授的信後,心裏是這麼想的。

2008年10月30日 星期四

Neo 機器人

月初從朋友那拿了一個控制 servo 的 LSC chip,以及一雙由 servo 組成的腳…
就在想,能不能拿 Neo 來做機器人呢?

Neo 上有兩個 g-sensor ,GPS chip,2.5G GSM chip, bluetooth,還有 wifi…
如果它能動…那會有多可怕… 拿它來開船、開飛機。可用 bluetooth wifi 和 GSM 來遙控…
應該會是一個很好玩的東西…

為了可以在 Neo 上能快快樂樂的玩 servo ,我開了個小案子:LSCD

把 servo 的 driver 寫好,再寫一個 python-binding... 就可以快快樂樂的玩了

liblscd 是控制 chip 的 API 可讀寫每個servo 的角度和速度。
pylsc 是 liblscd 的 python binding
在 tests 中還有一個 robot.py ,可以用來控制由 servo 組合而成的 robot...
未來想把 pylsc 寫成 freesmartphone 的一個 service 如此就可以和 phone event manager 整合在一起… (感覺起來可以做很多壞事 :P )


怎麼玩呢?
1. kernel 要有 HIDDEV drvier (Debian default 有,Ubuntu 沒有), Neo 從今天開始的 stable kernel 就會有 :P

2.1 在 laptop 上玩:
a. 安裝 gcc python cython pyrex python2.5-dev intltool libgettextpo-dev libtool automake autoconf make subversion
b. > svn checkout http://lscd.googlecode.com/svn/trunk/ lscd
c. > cd lscd
> ./autogen.sh
> make
> sudo make install
d. 接上 LSC device, sudo chmod 777 /dev/usb/hiddev0
e. 就可以進 test 來玩 robot.py 了
2.2 在 Neo 上玩
a. wget http://lscd.googlecode.com/files/liblscd0_armv4t.opk
b. opkg install
liblscd0_armv4t.opk
c. 用 wifi or bluetooth 連進Neo
http://wiki.openmoko.org/wiki/Wifi

http://wiki.openmoko.org/wiki/Manually_using_Bluetooth#Bluetooth_networking_with_a_Linux_system
d. 把 usb 切到 host mode http://wiki.openmoko.org/wiki/USB_host#Selecting_USB_host_modes
e. 接上 LSC device (要有一個 mini 公 <----> USB B公的線, 可以用組合的)
example:
(mini公 <--> A 公 | A 母 <--> A 母 | A公<-->B 公)
f. 就可以玩了 ^_^

除了接線外…一切都可寫成 script :P




2008年10月23日 星期四

kernel indent 備忘

indent -kr -i8 -ts8 -sob -l80 -ss -bs -ps1

也可以看 scripts/Lindent