做兵去

好久沒有動我的部落格了
要去當兵囉 ~~~
發表一下感想好了

等當兵的日子超無聊
不過說真的 當兵完以後就沒有辦法過這樣悠閒的日子了
就要開始準備工作 面對其他的壓力了

11個月而已 很快就出來了
話是這樣說 可是進去以後應該還是會覺得時間過的很慢很慢 哈哈

真想趕快當完兵去工作
我不想再過這種地位很低的日子

wxWidgets cross-Platform GUI Library

wxWidgets 是一個跨平台開發 gui 介面的函式庫
官方網站:http://www.wxwidgets.org/

支援的平台:
- Win32
- Mac OS X
- GTK+
- X11
- Motif
- WinCE

可以去下載 wxDev-C++ 或是 wxFormBuilder 來輔助開發 (個人比較推薦 wxFormBuilder)  

Windows 上使用 wxWidgets 開發
Widgets 版本: wxMSW-2.8.7
編譯器: Visual Stdio 2005

設定編譯器:
- 加入 Include 目錄: <wxMSX-2.8.7>/include
- 加入 lib 目錄: <wxMSX-2.8.7>/lib/vc_lib
- 加入連接的 lib 檔: wxmsw28d_core.lib wxbase28d.lib wxtiffd.lib wxjpegd.lib
                                wxpngd.lib wxzlibd.lib wxregexd.lib wxexpatd.lib winmm.lib

                                comctl32.lib rpcrt4.lib wsock32.lib odbc32.lib

- 設定前置處理器定義: WIN32;__WXMSW__;_WINDOWS
- 選擇成: 多執行緒偵錯 DLL (/MDd)

附註:
1. 依照自己需要加入 lib 檔
2. lib 檔名 - debug 結尾有 "d", unicode 結尾有 "u"
3. 如果要用編譯器 debug 要設定 "產生偵錯資訊"
4. 大致上是要設定這些東西,其他細節就自行嘗試吧!!


參考資料:
http://wiki.wxwidgets.org/User%27s_Guide_For_VCpp_6.0

http://wiki.wxwidgets.org/Microsoft_Visual_CPP_Guide#Visual_C.2B.2B_2005_Express_and_Text_Editor_of_Your_Choice

http://www.christoph-mewes.de/wxwidgets/

OpenSER

OpenSER 是一個 open source  的 SIP Server
提供了大部分常用的 SIP Server 功能 :
- SIP proxy server
- SIP register server
- SIP redirect server

系統需求:
- gcc compiler
- flex
- bison
- libmysqlclient15-dev
- openssl
- mysql

編譯安裝 OpenSER
這裡下載最新的版本
我使用的版本是:openser-1.3.2-tls.tar.gz

修改 Makefile 把 mysql 從 exclude modules 去除
....

exclude_modules?= .... mysql ...

....

make all
make install

附註:
如果不想改 Makefile 可以改用下面指令
make all include_modules="mysql"
make install include_modules="mysql"

會將相關檔案安裝在 /usr/local 底下
執行檔會出現在 /usr/local/sbin 底下 (openser openserctl openserdbctl openserunix)
config 檔會出現在 /usr/local/etc/openser 底下 (dictionary.radius openser.cfg openserctlrc) 

建立 openser log 檔
修改 /etc/syslog.cfg 檔,加入藍色部份
.....

#
# don't log messages with LOG_LOCAL0 in /var/log/syslog anymore
*.*;auth,authpriv.none,local0.none -/var/log/syslog

#
# log messages with LOG_LOCAL0 in /var/log/openser.log
local0.* -/var/log/openser.log


.....


會在 /var/log/ 底下出現 openser.log

如果想要修改 openser log 設定
要修改 openser.cfg
相關參數:
- debug: set log level (0~9).
- log_stderror: If set to "yes", print debugging information to standard error output.
                      If set to "no", syslog will be used.
                      Default is "no" (printing to syslog).
- log_facility: is used to specify what type of program is logging the message. 
                    Valid values are "LOG_LOCAL0" through "LOG_LOCAL7". 
                    See the manual page of syslog for more information.

參考資料:
http://www.openser.org/dokuwiki/doku.php/tutorials:debug-syslog-messages#introduction


啟用認證使用者功能 (Mysql)
修改 openserctlrc
......

SIP_DOMAIN=<your server domain>

......

DBENGINE=MYSQL

......


修改 openser.cfg 取消以下的註解
......

loadmodule "mysql.so"

loadmodule "auth.so"
loadmodule "auth_db.so"

.......

modparam("usrloc", "db_mode",   2)

modparam("auth_db", "calculate_ha1", yes)
modparam("auth_db", "password_column", "password")

.......

if (!www_authorize("<your server domain>", "subscriber"))
{
     www_challenge("<your server domain>", "0");
     exit;
}

.......


建立 openser 的 mysql tabel
openserdbctl create

會建立兩個 mysql 使用者: openser openserro
預設密碼分別為: openserrw openserro 

使用 openserct add 指令加入新帳號

參考資料:
http://www.openser.org/mos/view/-OpenSER-Installation-Notes/
 

使用方式
開啟服務: openserctl start
停止服務: openserctl stop
查詢誰在線上: openserctl online
新增帳號: openserctl add <username> <password> <email>

參考資料:
http://www.openser.org/dokuwiki/doku.php/install:openser-from-svn

MMC/SD Driver

2.6.24.3 沒有 s3c24XX 系列的 mmc/sd 驅動作出來
可以去抓相關的 patch

patch: http://svnweb.openmoko.org/branches/src/target/kernel/2.6.24.x/patches/s3c_mci.patch?rev=3700&sortby=date&view=markup 

參考資料:
S3C2410中SD卡驅動的移植
s3c2410平台SD卡驅動分析
s3c2440linux2.6mmc/sd驅動程序


menuconfig 要選:
System Type  --->
     [*] S3C2410 DMA support 

附註:不知道 2410 和 2440 DMA 操作的方試是不是一樣??
相關筆記
SDCLK   -> GPE5
SDCMD  -> GPE6
SDDAT0 -> GPE7
SDDAT1 -> GPE8
SDDAT2 -> GPE9
SDDAT3 -> GPE10
Card Detect -> GPG2
Write Protect -> ??
SD POWER -> GPB9

有用到 tasklet 機制 (軟體中斷)
1. 使用 tastklet_init 建立一個 tasklet
2. 再使用 tasklet_schedule 把其 tasklet 放在 tasklet_vec 的最前面。

參考資料:
http://blog.chinaunix.net/u/24474/showart_227121.html
http://mechgouki.blogdriver.com/mechgouki/282365.html


讀取資料 -> do_pio_read ??
寫入資料 -> do_pio_write ??

irq      -> s3cmci_irq
irq_cd -> s3cmci_irq_cd 

發送CMD8,檢查卡是否 SD2.0。SD1.1 是不支持 CMD8 的,因此在 SD2.0 Spec中提出了先發送CMD8,如果回應為無效命令,則卡為SD1.1,否則就是SD2.0

參考資料:
http://blog.chinaunix.net/u1/42456/showart_523584.html


卡插入後似乎是正常的
但是會出現
mmc0: error -110 whilst initialising SD card
應該是卡在 linux/driver/mmc/core/sd.c 的
mmc_sd_init_card() --> mmc_send_app_op_cond(host, ocr, NULL)

ocr 是指 card 內部的 Operation Condition Register (OCR) 讀出來的值
發送 CMD41 CMD55  讀取 OCR 的值
問題是出在 OCR[31] 一直是 0 <--- 初始化沒有完成??
結果問題是出在電壓不足,要把 sd power enable
( color 是大功臣 )

struct mmc_command 中的變數代表意思:
opcode -> 要發送的 command
arg      -> 要傳送的參數 
flags    -> command 的類型

kernel 已經有抓到 sd 卡的資料
但是會出現 kernel panic
好像是在送 CMD18 時候出錯??
CMD18 是 adtc 類的 command:continuously transfers data blocks from card to host
                                         until interrupted by a STOP_TRANSMISSION command.


錯誤訊息:
Unable to handle kernel paging request at virtual address c4000000
pgd = c3e2c000
[c4000000] *pgd=00000000
Internal error: Oops: 805 [#1]
Modules linked in:
CPU: 0    Not tainted  (2.6.24.3 #166)
PC is at pio_tasklet+0x2f8/0x61c
LR is at __init_begin+0x3fff8000/0x34
pc : [<c01bc870>]    lr : [<00000000>]    psr: 20000013
sp : c3cf9ce4  ip : 00000003  fp : c3cf9d04
r10: c3cf9f0c  r9 : 00000000  r8 : c3cf9f64
r7 : c02b4460  r6 : 0000000a  r5 : c3c349a0  r4 : c5400040
r3 : c4000001  r2 : c4000000  r1 : 00000000  r0 : c3e37040
Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
Control: c000717f  Table: 33e2c000  DAC: 00000017
Process mmcqd (pid: 799, stack limit = 0xc3cf8258)
Stack: (0xc3cf9ce4 to 0xc3cfa000)
9ce0:          c0054788 c3cf9ce8 c0292c60 c02b4484 0000000a c3cf9d1c c3cf9d08
9d00: c0042ea4 c01bc588 00000001 c02b44c4 c3cf9d3c c3cf9d20 c00429ec c0042e34
9d20: c02921dc 00000025 c02c048c 00000000 c3cf9d4c c3cf9d40 c0042c10 c00429a0
9d40: c3cf9d6c c3cf9d50 c0023048 c0042bdc ffffffff f4000000 00200000 c3cf9e18
9d60: c3cf9dcc c3cf9d70 c0023a84 c0023010 c3c17660 c02b4460 00000020 00000000
9d80: c02921dc 80000013 00000003 c3cf9e18 c3cf9f64 00000000 c3cf9f0c c3cf9dcc
9da0: c02b4484 c3cf9db8 c0060e80 c00605d8 60000013 ffffffff c3c349a0 c3cf9f64
9dc0: c3cf9e00 c3cf9dd0 c01bc55c c0060550 c3cf9ef8 c3c34800 c3c34800 c3c34800
9de0: 00000000 c3cf9e18 c3da8074 00000000 00000000 c3cf9e14 c3cf9e04 c01bcbd4
9e00: c01bbfd0 c3cf9ef8 c3cf9e40 c3cf9e18 c01b48b4 c01bcba4 00000000 c3cf9e1c
9e20: c3cf9e1c c3e12f64 c3cf9ef8 c3cf8000 c3e05e00 c3cf9fb8 c3cf9e44 c01baa40
9e40: c01b47a8 00000001 c3e12f60 00000000 00000000 00000000 00000000 00000000
9e60: 00000000 c3cf9e64 c3cf9e64 00000000 00000000 00000000 00000000 00000000
9e80: 00000000 00000000 00000000 00000000 00000000 c3cf9e94 c3cf9e94 c3cf9e9c
9ea0: c3cf9e9c 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9ec0: c02a36d0 00000001 00000000 00000000 00000000 c3cf9f0c c3cf9ee4 c0036fa4
9ee0: c0104e40 00000001 c02a36d0 c3c17950 c3c79d50 c3da8074 c3cf9f0c c3cf9f64
9f00: c3cf9f38 c3cf9e18 c01b4780 00000012 00000000 00000000 00000000 00000000
9f20: 00000000 000000b5 00000000 00000000 c3cf9f64 c3cf9ef8 0000000c 00000000
9f40: 00000000 00000000 00000000 00000000 0000049d 00000000 00000000 00000000
9f60: c3cf9ef8 05f5e100 00000000 00000200 00000008 00000000 00000200 00000000
9f80: c3cf9f38 c3cf9ef8 00000001 c3dd2000 c3e12f6c c3e12f64 c3cf8000 00000000
9fa0: c3db90ec 00000000 00000000 c3cf9fdc c3cf9fbc c01bb38c c01ba850 fffffffc
9fc0: c01bb29c 00000000 00000000 00000000 c3cf9ff4 c3cf9fe0 c005151c c01bb2ac
9fe0: 00000000 00000000 00000000 c3cf9ff8 c0040080 c00514d8 0c104400 fbf5ebbe
Backtrace:
[<c01bc578>] (pio_tasklet+0x0/0x61c) from [<c0042ea4>] (tasklet_action+0x80/0xcc)
r6:0000000a r5:c02b4484 r4:c0292c60
[<c0042e24>] (tasklet_action+0x0/0xcc) from [<c00429ec>] (__do_softirq+0x5c/0xc8)
r5:c02b44c4 r4:00000001
[<c0042990>] (__do_softirq+0x0/0xc8) from [<c0042c10>] (irq_exit+0x44/0x4c)
r7:00000000 r6:c02c048c r5:00000025 r4:c02921dc
[<c0042bcc>] (irq_exit+0x0/0x4c) from [<c0023048>] (asm_do_IRQ+0x48/0x5c)
[<c0023000>] (asm_do_IRQ+0x0/0x5c) from [<c0023a84>] (__irq_svc+0x24/0xa0)
Exception stack(0xc3cf9d70 to 0xc3cf9db8)
9d60:                                     c3c17660 c02b4460 00000020 00000000
9d80: c02921dc 80000013 00000003 c3cf9e18 c3cf9f64 00000000 c3cf9f0c c3cf9dcc
9da0: c02b4484 c3cf9db8 c0060e80 c00605d8 60000013 ffffffff
r7:c3cf9e18 r6:00200000 r5:f4000000 r4:ffffffff
[<c0060540>] (enable_irq+0x0/0xb0) from [<c01bc55c>] (s3cmci_send_request+0x59c/0x5b8)
r5:c3cf9f64 r4:c3c349a0
[<c01bbfc0>] (s3cmci_send_request+0x0/0x5b8) from [<c01bcbd4>] (s3cmci_request+0x40/0x48)
[<c01bcb94>] (s3cmci_request+0x0/0x48) from [<c01b48b4>] (mmc_wait_for_req+0x11c/0x13c)
r4:c3cf9ef8
[<c01b4798>] (mmc_wait_for_req+0x0/0x13c) from [<c01baa40>] (mmc_blk_issue_rq+0x200/0x670)
r7:c3e05e00 r6:c3cf8000 r5:c3cf9ef8 r4:c3e12f64
[<c01ba840>] (mmc_blk_issue_rq+0x0/0x670) from [<c01bb38c>] (mmc_queue_thread+0xf0/0x12c)
[<c01bb29c>] (mmc_queue_thread+0x0/0x12c) from [<c005151c>] (kthread+0x54/0x7c)
r8:00000000 r7:00000000 r6:00000000 r5:c01bb29c r4:fffffffc
[<c00514c8>] (kthread+0x0/0x7c) from [<c0040080>] (do_exit+0x0/0x6d0)
r5:00000000 r4:00000000
Code: e35c0000 e1a02003 e2833001 e5853068 (e5c21000)
Kernel panic - not syncing: Fatal exception in interrupt

用新的 patch 就可以解決所有問題 = =
詳情請看 color 的 blog

Touch Screen Driver - 游標抖動

現在在使用時游標會一直抖動,在 ts_test 中顯示的座標很不穩定。
定點不動時,抓到的座標數值會一直變化(大概是 +2 -2 的範圍變化)
應該是驅動不穩定造成的
在網路上有找到類似的文章

參考資料:
http://www.mcublog.com/blog/blog2007/dzzjhjl/archives/2008/26543.html


要把 Pen Filtering 實做出來才能解決這個問題
好加在 WinCE 裡面有程式碼可以參考

s3c2410_ts 程式碼筆記:
有設定 GPIO G ,不過把他註解調也可以正常使用,應該是跟 touch screen 沒關係
好像是針對 2410 的設定,我們是用 2440 所以註解掉也沒差。 
s3c2410_gpio_cfgpin(S3C2410_GPG12, S3C2410_GPG12_XMON);
s3c2410_gpio_cfgpin(S3C2410_GPG13, S3C2410_GPG13_nXPON);
s3c2410_gpio_cfgpin(S3C2410_GPG14, S3C2410_GPG14_YMON);
s3c2410_gpio_cfgpin(S3C2410_GPG15, S3C2410_GPG15_nYPON);


當點下或放開會觸發
static irqreturn_t stylus_updown(int irq, void *dev_id)

當觸控有動作會觸發
static irqreturn_t stylus_action(int irq, void *dev_id) 

回報座標和是否觸控 
input_report_abs(ts.dev, ABS_X, ts.xp);
input_report_abs(ts.dev, ABS_Y, ts.yp);
input_report_key(ts.dev, BTN_TOUCH, 1);
input_report_abs(ts.dev, ABS_PRESSURE, 1);

判斷是點下或是放開動作
updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && 
         (!(data1 & S3C2410_ADCDAT0_UPDOWN)); 


驅動內取樣的頻率定義在 oversampling_shift 

原本作法是取樣 (1<<oversampling_shift) 次,
然後取平均值當作最後抓到的座標。

修改 touch screen 驅動
把 smdk2410_ts_cfg.delay 改成 20000 後 (原本為100)
游標穩定很多,但是還是會輕微抖動,不過已經比之前好多了。
應該是之前可能是因為硬體取樣頻率太高,所以會比較不穩定??

附註:ADCDLY 設定為 delay 的值。  

現在試著把 Filter 的程式碼加進去,看會不會不要抖 XD
果然加進去後就不會抖動了,只是滑鼠靈敏度會比較差一點。

主要修改的部份:
1. 當很短時間內取樣點差異很小時,視為取樣點不動。
2. 去除不合法的取樣點。

加入一個函式:
#define TRUE 1
#define FALSE 0
#define FILTER_LIMIT 25
static int touch_pen_filtering(int *px, int *py)
{
    int RetVal = TRUE;
    // TRUE  : Valid pen sample
    // FALSE : Invalid pen sample 

    static int count = 0;
    static int x[2], y[2];
    int TmpX, TmpY;
    int dx, dy; 

    count++; 

    if(count > 2) {
        // apply filtering rule
        count = 2; 

        // average between x,y[0] and *px,y
        TmpX = (x[0] + *px) / 2;
        TmpY = (y[0] + *py) / 2; 

        // difference between x,y[1] and TmpX,Y
        dx = (x[1] > TmpX) ? (x[1] - TmpX) : (TmpX - x[1]);
        dy = (y[1] > TmpY) ? (y[1] - TmpY) : (TmpY - y[1]); 

        if ((dx > FILTER_LIMIT) || (dy > FILTER_LIMIT)) {
            // Invalid pen sample  
            *px = x[1];
            *py = y[1];
            RetVal = FALSE;
            count = 0;
        } else {
            // Valid pen sample
            x[0] = x[1];
            y[0] = y[1];
            x[1] = *px;
            y[1] = *py; 

            RetVal = TRUE;
        }
    } else {
        // till 2 samples, no filtering rule
        x[0] = x[1];
        y[0] = y[1];
        x[1] = *px;
        y[1] = *py;     // reserve pen samples 

        RetVal = FALSE;

    } 
    return RetVal;
}


修改後的程式碼:
static irqreturn_t stylus_action(int irq, void *dev_id)

     unsigned long data0; 
     unsigned long data1;        
     
     static long last_x ,last_y; 
     static long sum_x, sum_y; 
     long dx, dy; 
     long tmpX, tmpY;

               
     data0 = readl(base_addr+S3C2410_ADCDAT0); 
     data1 = readl(base_addr+S3C2410_ADCDAT1);        

     ts.xp += data0 & S3C2410_ADCDAT0_XPDATA_MASK;
     ts.yp += data1 & S3C2410_ADCDAT1_YPDATA_MASK;
     tmpX = data0 & S3C2410_ADCDAT0_XPDATA_MASK; 
     tmpY = data1 & S3C2410_ADCDAT1_YPDATA_MASK;
     ts.count++;

     if (ts.count < (1<<ts.shift)) {  
          ts.xp += tmpX; 
          ts.yp += tmpY;

          
          .....

     } else {  
          sum_x = ts.xp; 
          sum_y = ts.yp; 
          ts.xp >>= ts.shift; 
          ts.yp >>= ts.shift; 
          dx = (ts.xp>last_x)?(ts.xp-last_x):(last_x-ts.xp); 
          dy = (ts.yp>last_y)?(ts.yp-last_y):(last_y-ts.yp); 
          
          if(dx>10 || dy>10) {
               last_x = ts.xp; 
               last_y = ts.yp; 
          } else { 
               ts.xp = last_x; 
               ts.yp = last_y; 
          }
          
          ..... 
     }

     return IRQ_HANDLED;
}


static void touch_timer_fire(unsigned long data)
{
     .....

     if(updown) {
          if (ts.count != 0) { 
               .....

              if(touch_pen_filtering(&ts.xp, &ts.yp)) { 
                   input_report_abs(ts.dev, ABS_X, ts.xp); 
                   input_report_abs(ts.dev, ABS_Y, ts.yp);
 
                  input_report_key(ts.dev, BTN_TOUCH, 1); 
                   input_report_abs(ts.dev, ABS_PRESSURE, 1); 
                   input_sync(ts.dev); 
              }
          }

          .....
     }
    
     .....
}


附註:
1. 其中程式碼的 FILTER_LIMITif(dx>10 || dy>10) { 的數值可以修改調整。
2. 但是我懶得在試了