2010年9月10日星期五

[转载]宏定义中字符串连接操作


关于记号粘贴操作符(token paste operator): ##
1. 简单的说,“##”是一种分隔连接方式,它的作用是先分隔,然后进行强制连接。
   其中,分隔的作用类似于空格。我们知道在普通的宏定义中,预处理器一般把空格
   解释成分段标志
,对于每一段和前面比较,相同的就被替换。但是这样做的结果是,
   被替换段之间存在一些空格
。如果我们不希望出现这些空格,就可以通过添加一些
   ##来替代空格
。
   另外一些分隔标志是,包括操作符,比如 +, -, *, /, [,], …,所以尽管下面的
   宏定义没有空格,但是依然表达有意义的定义: define add(a, b)  a+b
   而其强制连接的作用是,去掉和前面的字符串之间的空格,而把两者连接起来。
2. 举列 – 试比较下述几个宏定义的区别
   #define A1(name, type)  type name_##type##_type 或
   #define A2(name, type)  type name##_##type##_type
   A1(a1, int);  /* 等价于: int name_int_type; */
   A2(a1, int);  /* 等价于: int a1_int_type;   */
   解释:
        1) 在第一个宏定义中,”name”和第一个”_”之间,以及第2个”_”和第二个
   ”type”之间没有被分隔,所以预处理器会把name_##type##_type解释成3段:
   “name_”、“type”、以及“_type”,这中间只有“type”是在宏前面出现过
    的,所以它可以被宏替换。
        2) 而在第二个宏定义中,“name”和第一个“_”之间也被分隔了,所以
   预处理器会把name##_##type##_type解释成4段:“name”、“_”、“type”
   以及“_type”,这其间,就有两个可以被宏替换了。
        3) A1和A2的定义也可以如下:
           #define A1(name, type)  type name_  ##type ##_type 
                                      <##前面随意加上一些空格>
           #define A2(name, type)  type name ##_ ##type ##_type
    结果是## 会把前面的空格去掉完成强连接,得到和上面结果相同的宏定义
3. 其他相关 – 单独的一个 #
   至于单独一个#,则表示 对这个变量替换后,再加双引号引起来。比如
      #define  __stringify_1(x)   #x
那么
      __stringify_1(linux)   <==>  ”linux”
所以,对于MODULE_DEVICE_TABLE
     1) #define MODULE_DEVICE_TABLE(type,name)                       
             MODULE_GENERIC_TABLE(type##_device,name)
     2) #define MODULE_GENERIC_TABLE(gtype,name)                     
             extern const struct gtype##_id __mod_##gtype##_table    
             __attribute__ ((unused, alias(__stringify(name))))
得到 
      MODULE_DEVICE_TABLE(usb, products) 
                             /*notes: struct usb_device_id products; */
 <==> MODULE_GENERIC_TABLE(usb_device,products)
 <==> extern const struct usb_device_id __mod_usb_device_table    
             __attribute__ ((unused, alias(”products”)))   
注意到alias attribute需要一个双引号,所以在这里使用了__stringify(name)来
给name加上双引号。另外,还注意到一个外部变量”__mod_usb_device_table”被alias
到了本驱动专用的由用户自定义的变量products<usb_device_id类型>。这个外部变量
是如何使用的,更多的信息请参看《probe()过程分析》。
4. 分析方法和验证方式 – 编写一个简单的C程序
   用宏定义一个变量,同时用直接方式定义一个相同的变量,编译报告重复定义;
   用宏定义一个变量,直接使用该宏定义的变量名称,编译通过且运行结果正确;
   使用printf打印字符串数据。printf(”token macro is %s”, __stringify_1(a1));

2010年9月9日星期四

S3C ADC API


data struct

  46struct s3c_adc_client {
  47        struct platform_device  *pdev;
  48        struct list_head         pend;
  49        wait_queue_head_t       *wait;
  50
  51        unsigned int             nr_samples;
  52        int                      result;
  53        unsigned char            is_ts;
  54        unsigned char            channel;
  55
  56        void    (*select_cb)(struct s3c_adc_client *c, unsigned selected);
  57        void    (*convert_cb)(struct s3c_adc_client *c,
  58                              unsigned val1, unsigned val2,
  59                              unsigned *samples_left); 
60}; 
API

Register and unregister function:
 24extern struct s3c_adc_client *
  25        s3c_adc_register(struct platform_device *pdev,
  26                         void (*select)(struct s3c_adc_client *client,
  27                                        unsigned selected),       /*********Called when the ADC core selects (or deslects) us as a client.**********/

  28                         void (*conv)(struct s3c_adc_client *client,
  29                                      unsigned d0, unsigned d1,
  30                                      unsigned *samples_left),    /*****Called when a conversion has finished.**************/
31 unsigned int is_ts);  /***whether to used for touch screen.***/

--usually be used in the driver's probe() function.

release:
33extern void s3c_adc_release(struct s3c_adc_client *client);
To use ADC

  19extern int s3c_adc_start(struct s3c_adc_client *client, 
20 unsigned int channel, unsigned int nr_samples); 

--just call this function when using touchscreen mode, and convert will be accomplished in the interrupt handle.


or another way :
extern int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch);
this function is useful when using normal ADC mode.
example for two function: select and conv
/**
 187 * s3c24xx_ts_conversion - ADC conversion callback
 188 * @client: The client that was registered with the ADC core.
 189 * @data0: The reading from ADCDAT0.
 190 * @data1: The reading from ADCDAT1.
 191 * @left: The number of samples left.
 192 *
 193 * Called when a conversion has finished.
 194 */
 195static void s3c24xx_ts_conversion(struct s3c_adc_client *client,
 196                                  unsigned data0, unsigned data1,
 197                                  unsigned *left)
 198{
 199        dev_dbg(ts.dev, "%s: %d,%d\n", __func__, data0, data1);
 200
 201        ts.xp += data0;
 202        ts.yp += data1;
 203
 204        ts.count++;
 205
 206        /* From tests, it seems that it is unlikely to get a pen-up
 207         * event during the conversion process which means we can
 208         * ignore any pen-up events with less than the requisite
 209         * count done.
 210         *
 211         * In several thousand conversions, no pen-ups where detected
 212         * before count completed.
 213         */
 214}
 215
 216/**
 217 * s3c24xx_ts_select - ADC selection callback.
 218 * @client: The client that was registered with the ADC core.
 219 * @select: The reason for select.
 220 *
 221 * Called when the ADC core selects (or deslects) us as a client.
 222 */
 223static void s3c24xx_ts_select(struct s3c_adc_client *client, unsigned select)
 224{
 225        if (select) {
 226                writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST,
 227                       ts.io + S3C2410_ADCTSC);
 228        } else {
 229                mod_timer(&touch_timer, jiffies+1);
 230                writel(WAIT4INT | INT_UP, ts.io + S3C2410_ADCTSC);
 231        } 
232} 

[转载]提问的智慧(图解)

2010年9月8日星期三

A bash tip

shell里面调用vi编辑命令,编辑完以后又可以回 到命令行编辑好的命令:

先export EDITOR=/usr/bin/vim
然后crtl+x,crtl+e

2010年9月7日星期二

解决ubuntu 10.04 休眠后黑屏的方法

ubuntu默认安装的电源管理软件是pm-utils-powersave-policy
但是这个软件在我的acer 4710G休眠后,常常唤醒不了,只能强行关机。
google了以下,把这个软件卸载后,装上laptop-mode-tools
然后修改配置文件/etc/default/acpi-support,更改ENABLE_LAPTOP_MODE=true
就能顺利休眠了


以下是原文:
想必大家都用习惯windows的待机,但是ubuntu的挂起总是让人很头痛,每次挂起出去了,回来后就打不开,
硬盘启动,灯都亮的很正常,就是屏幕是黑色的。
下面让我们来一起解决这个问题:
首先 安装这个包:sudo apt-get install pm-utils
由于缺失laptop_mode,导致系统无法唤醒,发现只要打开laptop_mode,Laptop挂起之后无法唤醒的问题
已经就不存在了。
关于laptop_mode
在默认情况下,你通过安装完系统到笔记本上后,就安装上了laptop-mode-tools工具包。如果你不缺认自
已是否安装了laptop-mode-tools工具包,可以在终端中输入下列命令来确认是否安装。
dpkg -l | grep laptop-mode-tools
如果你的电脑执行命今后无结果输出,那么你可以通过下列命令来安装。
sudo apt-get install laptop-mode-tools
虽然系统已自动安装了laptop-mode-tools,但是是不是就自动启动了laptop_mode模式了呢?我们用下
列命令来判断Laptop是否启用了laptop_mode,如果显示结果为0,则表示未启动,如果为非0的数字则表示启动了。
cat /proc/sys/vm/laptop_mode
怎样启动laptop_mode模式呢?
1.修改配置文件/etc/default/acpi-support,更改ENABLE_LAPTOP_MODE=true
sudo gedit /etc/default/acpi-support
2.然后在默认情况下UBUNTU系统会在你切换电源到电池供电时启动laptop_mode,如果你现在就
想启动laptop_mode模式,请直接在终端中输入
sudo laptop_mode start
启动了laptop_mode之后,在ubuntu挂起后,基本上就不会遇到无法唤醒的情况了。 

a script for ssh proxy under linux (using expect)

#/bin/bash

expect << END
set timeout 15
#kill the existing progress that have already be running
spawn sudo killall ssh
expect "sudo" {send "yourpwd\r"}
spawn sudo ssh -L .... #something you specify
expect {
    "sudo" {
        send "yourpwd\r"
        exp_continue
    }
    "yes" {
     send "yes\r"
     exp_continue
    }
    -nocase "password:" {
        send "sshpwd\r"
        exp_continue
    }
}
wait

END

2010年8月18日星期三

【转载】请不要做浮躁的人

1.不要看到别人的回复第一句话就说:给个代码吧!你应该想想为什么。当你自己想出来再参考别人的提示,你就知道自己和别人思路的差异。 
2.初学者请不要看太多太多的书那会误人子弟的,先找本系统的学,很多人用了很久都是只对部分功能熟悉而已,不系统还是不够的。 
3.看帮助,不要因为很难而自己是初学者所以就不看;帮助永远是最好的参考手册,虽然帮助的文字有时候很难看懂,总觉得不够直观。 
4.不要被对象、属性、方法等词汇所迷惑;最根本的是先了解最基础知识。 
5.不要放过任何一个看上去很简单的小问题--他们往往并不那么简单,或者可以引伸出很多知识点;或者可以引伸出很多知识点;不会举一反三你就永远学不会。 
6.知道一点东西,并不能说明你会写脚本,脚本是需要经验积累的。 
7.学脚本并不难,ASP、PHP等等也不过如此--难的是长期坚持实践和不遗余力的博览群书; 
8.看再多的书是学不全脚本的,要多实践 
9.把时髦的技术挂在嘴边,还不如把过时的技术记在心里; 
10.学习脚本最好的方法之一就是多练习; 
11.在任何时刻都不要认为自己手中的书已经足够了; 
12.看得懂的书,请仔细看;看不懂的书,请硬着头皮看; 
13.别指望看第一遍书就能记住和掌握什么——请看第二遍、第三遍; 
14.请把书上的例子亲手到电脑上实践,即使配套光盘中有源文件; 
15.把在书中看到的有意义的例子扩充;并将其切实的运用到自己的工作中; 
16.不要漏掉书中任何一个练习——请全部做完并记录下思路; 
17.当你用脚本到一半却发现自己用的方法很拙劣时,请不要马上停手;请尽快将余下的部分粗略的完成以保证这个代码的完整性,然后分析自己的错误并重新编写和工作。 
18.别心急,写脚本确实不容易;水平是在不断的实践中完善和发展的; 
19.每学到一个脚本难点的时候,尝试着对别人讲解这个知识点并让他理解----你能讲清楚才说明你真的理解了; 
20.记录下在和别人交流时发现的自己忽视或不理解的知识点; 
21.保存好你做过的所有的源文件----那是你最好的积累之一; 
22.对于网络,还是希望大家能多利用一下,很多问题不是非要到论坛来问的,首先你要学会自己找答案,比如google、百度都是很好的搜索引擎,你只要输入关键字就能找到很多
相关资料,别老是等待别人给你希望,看的出你平时一定也很懒! 
23,到一个论坛,你学会去看以前的帖子,不要什么都不看就发帖子问,也许你的问题早就有人问过了,你再问,别人已经不想再重复了,做为初学者,谁也不希望自己的帖子没人回的。 
24,虽然不是打击初学者,但是这句话还是要说:论坛论坛,就是大家讨论的地方,如果你总期望有高手总无偿指点你,除非他是你亲戚!!讨论者,起码是水平相当的才有讨论的说法,如果水平真差距太远了,连基本操作都需要别人给解答,谁还跟你讨论呢。 
浮躁的人容易问:我到底该学什么;----别问,学就对了; 
浮躁的人容易问:JS有钱途吗;----建议你去抢银行; 
浮躁的人容易说:我要中文版!我英文不行!----不行?学呀! 
浮躁的人分两种:只观望而不学的人;只学而不坚持的人; 
浮躁的人永远不是一个高手。