基于TQ2440的led字符设备驱动
来源:互联网 发布:南京大学软件学院地址 编辑:程序博客网 时间:2024/05/23 22:00
实现平台:Ubuntu 14.04 + TQ2440
实现工具:arm-linux-gcc + SecureCRT + Samba
实现内容:
用户空间 内核空间 实现结果
open led_open led全亮
close led_close led全灭
read led_read 读取led状态(亮或灭)
write led_write 批量设置led状态
ioctl led_ioctl 逐个设置led状态
实现过程:
[1] 原材料:无非就是头文件了
[2] 模块框架
[3] 操作接口设计
需要的函数接口:
函数接口原型:
[4] 逐个说明:
[+] led_open() 就是点亮四盏led,很简单,直接看代码,就不解释了:
[+] led_close() 同样很简单,熄灭四盏灯即可,上代码:
[+] led_read() 需要读取led管脚状态,根据s3c2410_gpio_getpin()的返回值可以判断:若返回值为0,则led灯是亮的,否则为灭。同时,led_read()接口要求将led灯总体的亮灭状态传送给用户空间,使用copy_to_user()可以做到这一点。
[+] led_write() 稍复杂一些,需要从用户空间接收参数(见参数说明)以设置led灯的状态,同时返回写入的长度。
使用copy_from_user()可以接收参数,根据参数进行点灯操作。
[+] led_ioctl() 同样根据用户空间的命令和参数进行操作,只不过不再使用copy_xxx_user()接口,因为不需要给用户空间传递信息,因此根据用户空间ioctl()传递进来的参数即可执行操作。
至此,全部操作接口设计完毕。
[4] 编译:
给模块写个Makefile:
编译成模块:
再写个应用程序test_led.c做测试:
写个Makefile,也可以直接输入命令arm-linux-gcc test_led.c -o test_led:
编译:
[4] 测试运行:
[+] 使用Samba方便快捷地将linux的上述生成的led.ko内核模块文件和test_led二进制文件文件传到windows;
[+] 把文件拷贝到开发板,此过程可以使用secureCRT的rz命令(需要安装一个lrzsz包,请自行Google之);
[+] 修改led.ko 和 test_led 的权限
chmod 777 led.ko test_led
{经测试,只要修改test_led的权限即可}
[+] 插入模块:insmod led.ko
接着运行test_led:
[6] 总结:
[+] 有些时候,开发板默认开启了led,这时进行测试就会失败,因为看不到效果啊。
所以,就需要手动终止开发板的led进程了。
kill 632,终止即可。
[+] getchar() 输入缓存区问题:
一开始,使用getchar()调试时会造成两次输出(第一次输出正常,第二次不正常),鼓捣了许久,笔者确认代码区没有问题。
于是把重点放在getchar()上,根据笔者的经验,输入输出存在缓存区的问题,现在遇到的清空很可能就是没有清空缓存区的原因。
然后,笔者试着使用Windows下经常使用的fflush(stdin)对标准输入缓存区进行清空,结果发现还是一样的.
百思不得其解,只好Google之。
于是惊奇地发现fflush()在Linux下没有清空输入缓存区的效果,于是你知道的,差点破罐破摔了。
最后总结出来,使用getchar()进行调试的最保险的做法是使用一个while循环对输入的字符进行检测,
如果不是回车符,则继续输入。同理,该方法也适用于scanf()等。
本文原创,如须转载,请注明出处:http://blog.chinaunix.net/blog/post/id/4279550.html
实现工具:arm-linux-gcc + SecureCRT + Samba
实现内容:
用户空间 内核空间 实现结果
open led_open led全亮
close led_close led全灭
read led_read 读取led状态(亮或灭)
write led_write 批量设置led状态
ioctl led_ioctl 逐个设置led状态
实现过程:
[1] 原材料:无非就是头文件了
点击(此处)折叠或打开
- #define _LED_H_
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/fs.h>
- #include <linux/types.h>
- #include <linux/cdev.h>
- #include <linux/uaccess.h>
- #include <linux/device.h>
- #include <mach/regs-gpio.h>
- #include <mach/hardware.h>
- #include <linux/ioctl.h>
- #define LED_ON 1 //亮
- #define LED_OFF 0 //灭
- int nMajor = 0; //主设备号
- int nMinor = 0; //次设备号
- //led 端口表
- static unsigned long led_port_table[] =
- {
- S3C2410_GPB5,
- S3C2410_GPB6,
- S3C2410_GPB7,
- S3C2410_GPB8,
- };
- //led 输出状态表
- static unsigned int led_state_table[] =
- {
- S3C2410_GPB5_OUTP,
- S3C2410_GPB6_OUTP,
- S3C2410_GPB7_OUTP,
- S3C2410_GPB8_OUTP,
- };
-
- //申请一个设备号
- dev_t dev;
-
- //申请一个class设备类
- static struct class *led_class;
-
- //申请一个cdev设备结构体
- struct cdev *led_cdev = NULL;
- /******************************************************************
- *函数接口声明
- ******************************************************************/
- static int led_open(struct inode *inode, struct file *filp);
- static ssize_t led_read(struct file *filp,char __user *buf,
- size_t nSize, loff_t * pos);
-
- static ssize_t led_write(struct file *filp, const char __user *buf,
- size_t size,loff_t *pos);
-
- static int led_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg);
-
- static int led_close(struct inode *inode, struct file *filp);
- /******************************************************************
- *led操作接口
- ******************************************************************/
- struct file_operations led_fops =
- {
- .owner = THIS_MODULE,
- .open = led_open,
- .read = led_read,
- .write = led_write,
- .ioctl = led_ioctl,
- .release = led_close,
- };
- #endif // _LED_H_
[2] 模块框架
点击(此处)折叠或打开
- ;这个过程是必须要懂的,不会的请先学习基础,由于篇幅较长,就不贴出代码了
- static int __init led_module_init()
- {
- /*
- ;初始化led
- ;申请设备号
- ;注册设备
- ;绑定设备文件操作接口
- ;添加设备类
- ;在设备类下创建设备节点
- */
- }
- static void __exit led_module_exit()
- {
- /*
- ;删除设备节点
- ;删除设备类
- ;释放设备结构
- ;释放设备号
- */
- }
- module_init(led_module_init);
- module_exit(led_module_exit_;
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Reyn");
- MODULE_DESCRIPTION("testing for led_driver")
[3] 操作接口设计
需要的函数接口:
点击(此处)折叠或打开
- struct file_operations led_fops =
- {
- .owner = THIS_MODULE,
- .open = led_open,
- .read = led_read,
- .write = led_write,
- .ioctl = led_ioctl,
- .release = led_close,
- };
函数接口原型:
点击(此处)折叠或打开
- static int led_open(struct inode *inode, struct file *filp);
- static ssize_t led_read(struct file *filp,char __user *buf, size_t nSize, loff_t *pos);
-
- static ssize_t led_write(struct file *filp, const char __user *buf, size_t size, loff_t *pos);
-
- static int led_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
-
- static int led_close(struct inode *inode, struct file *filp)
[4] 逐个说明:
[+] led_open() 就是点亮四盏led,很简单,直接看代码,就不解释了:
点击(此处)折叠或打开
- /******************************************************************
- *函数名称:led_open
- *函数描述:打开led灯,全亮
- *返回值 :void
- ******************************************************************/
- static int led_open(struct inode *inode, struct file *filp)
- {
- int nLedNb = 0;
- for(; nLedNb<4; ++nLedNb)
- {
- s3c2410_gpio_setpin(led_port_table[nLedNb], ~(LED_ON)); //点亮一盏灯
- printk(KERN_INFO "[Kernel] led%d on.\n", nLedNb);
- }
- return 0;
- }
[+] led_close() 同样很简单,熄灭四盏灯即可,上代码:
点击(此处)折叠或打开
- /******************************************************************
- *函数名称:led_close
- *函数描述:关闭led灯,全灭
- *返回值 :成功返回0,失败返回其他值
- ******************************************************************/
- static int led_close(struct inode *inode, struct file *filp)
- {
- int nLedNb = 0;
- for(nLedNb = 0; nLedNb < 4; ++nLedNb)
- {
- s3c2410_gpio_setpin(led_port_table[nLedNb], ~(LED_OFF));
- }
-
- printk(KERN_INFO "[Kernel] led all off.\n");
-
- return 0;
- }
[+] led_read() 需要读取led管脚状态,根据s3c2410_gpio_getpin()的返回值可以判断:若返回值为0,则led灯是亮的,否则为灭。同时,led_read()接口要求将led灯总体的亮灭状态传送给用户空间,使用copy_to_user()可以做到这一点。
点击(此处)折叠或打开
- /******************************************************************
- *函数名称:led_read
- *函数描述:读取led灯状态
- *返回值 :返回复制长度
- ******************************************************************/
- static ssize_t led_read(struct file *filp,char __user *buf,
- size_t nSize, loff_t * pos)
- {
- int nStatus = 0; //存储LED状态
- int nLedNb = 0; //LED灯编号
- int nCopyLen = 0;//复制信息的长度
- char status_buf[20] = {};
- for(; nLedNb<4; ++nLedNb)
- {
- nStatus = s3c2410_gpio_getpin(led_port_table[nLedNb]);
- if(nStatus == 0)
- {
- printk(KERN_INFO "[Kernel] led%d %s\n", nLedNb, "on");
- strcat(status_buf, "on ");
- }
- else
- {
- printk(KERN_INFO "[Kernel] led%d %s\n", nLedNb, "off");
- strcat(status_buf, "off ");
- }
- }
- //将LED灯的状态传给用户空间
- nCopyLen = strlen(status_buf);
- copy_to_user(buf, status_buf, nCopyLen);
- printk(KERN_INFO "[Kernel] copy to user:%d.\n", nCopyLen);
-
- return nCopyLen;
- }
[+] led_write() 稍复杂一些,需要从用户空间接收参数(见参数说明)以设置led灯的状态,同时返回写入的长度。
使用copy_from_user()可以接收参数,根据参数进行点灯操作。
点击(此处)折叠或打开
- /******************************************************************
- *函数名称:led_write
- *函数描述:批量设置led灯状态
- * cStatus:[0/1/2/3/4]
- * 0 - 1 - 2 - 3 - 4
- * 全灭 1-on 1,2-on 1,2,3-on all-on
- *返回值 :成功返回复制的长度,失败返回-1
- ******************************************************************/
- static ssize_t led_write(struct file *filp, const char __user *buf,
- size_t size,loff_t *pos)
- {
- char cStatus;
- int nCopyLen = sizeof(char);
-
- //从用户空间接收参数
- nCopyLen = copy_from_user(&cStatus, buf, nCopyLen) ? (-1) : nCopyLen;
- printk(KERN_INFO "[Kernel] copy from user:%d.\n", nCopyLen);
- printk(KERN_INFO "[Kernel] write led status %c.\n", cStatus);
-
- switch(cStatus)
- {
- case '0':
- {
- s3c2410_gpio_setpin(led_port_table[0], ~(LED_OFF));
- s3c2410_gpio_setpin(led_port_table[1], ~(LED_OFF));
- s3c2410_gpio_setpin(led_port_table[2], ~(LED_OFF));
- s3c2410_gpio_setpin(led_port_table[3], ~(LED_OFF));
- printk(KERN_INFO "[Kernel] led all off.\n");
- }
- break;
-
- case '1':
- {
- s3c2410_gpio_setpin(led_port_table[0], ~(LED_ON));
- s3c2410_gpio_setpin(led_port_table[1], ~(LED_OFF));
- s3c2410_gpio_setpin(led_port_table[2], ~(LED_OFF));
- s3c2410_gpio_setpin(led_port_table[3], ~(LED_OFF));
- printk(KERN_INFO "[Kernel] led 1 on.\n");
- }
- break;
-
- case '2':
- {
- s3c2410_gpio_setpin(led_port_table[0], ~(LED_ON));
- s3c2410_gpio_setpin(led_port_table[1], ~(LED_ON));
- s3c2410_gpio_setpin(led_port_table[2], ~(LED_OFF));
- s3c2410_gpio_setpin(led_port_table[3], ~(LED_OFF));
- printk(KERN_INFO "[Kernel] led 1,2 on.\n");
- }
- break;
-
- case '3':
- {
- s3c2410_gpio_setpin(led_port_table[0], ~(LED_ON));
- s3c2410_gpio_setpin(led_port_table[1], ~(LED_ON));
- s3c2410_gpio_setpin(led_port_table[2], ~(LED_ON));
- s3c2410_gpio_setpin(led_port_table[3], ~(LED_OFF));
- printk(KERN_INFO "[Kernel] led 1,2,3 on.\n");
- }
- break;
-
- case '4':
- {
- s3c2410_gpio_setpin(led_port_table[0], ~(LED_ON));
- s3c2410_gpio_setpin(led_port_table[1], ~(LED_ON));
- s3c2410_gpio_setpin(led_port_table[2], ~(LED_ON));
- s3c2410_gpio_setpin(led_port_table[3], ~(LED_ON));
- printk(KERN_INFO "[Kernel] led all on.\n");
- }
- break;
-
- default:
- printk(KERN_INFO "[Error] unrecognize status %c.\n", cStatus);
- break;
- }
- return nCopyLen;
- }
[+] led_ioctl() 同样根据用户空间的命令和参数进行操作,只不过不再使用copy_xxx_user()接口,因为不需要给用户空间传递信息,因此根据用户空间ioctl()传递进来的参数即可执行操作。
点击(此处)折叠或打开
- /******************************************************************
- *函数名称:led_ioctl
- *函数描述:逐个设置led灯的状态
- *参数描述:cmd表示led状态,arg标识led编号
- *返回值 :成功返回0,失败返回其他值
- ******************************************************************/
- static int led_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
- {
- if(arg > 4 || arg < 0)
- {
- return -EINVAL;
- }
-
- switch(cmd)
- {
- case LED_OFF:
- {
- s3c2410_gpio_setpin(led_port_table[arg], 1);
- printk(KERN_INFO "[Kernel] led%ld off.\n", arg);
- return 0;
- }
- case LED_ON:
- {
- s3c2410_gpio_setpin(led_port_table[arg], 0);
- printk(KERN_INFO "[Kernel] led%ld on.\n", arg);
- return 0;
- }
- default:
- return -EINVAL;
- }
- }
至此,全部操作接口设计完毕。
[4] 编译:
给模块写个Makefile:
点击(此处)折叠或打开
- # Led Module Makefile
- OBJ := led.o
- KERNDIR := /opt/EmbedSky/linux-2.6.30.4/
- INSTALL := /home/reyn/share/out/
- CC := arm-linux-gcc
- obj-m := $(OBJ)
- all:
- $(MAKE) -C $(KERNDIR) M=$(PWD) modules
- cp *.ko $(INSTALL)
- modules:
- $(MAKE) -C $(KERNDIR) M=$(PWD) modules
- install:
- cp *.ko $(INSTALL)
- .PHONY:modules clean
- clean:
- rm *.mod.c *.o *.order *.ko *.symvers *~
- rm $(INSTALL)*.ko
编译成模块:
点击(此处)折叠或打开
- reyn@ubuntu:led$ make
- make -C /opt/EmbedSky/linux-2.6.30.4/ M=/home/reyn/share/drivers/led modules
- make[1]: 正在进入目录 `/opt/EmbedSky/linux-2.6.30.4'
- CC [M] /home/reyn/share/drivers/led/led.o
- Building modules, stage 2.
- MODPOST 1 modules
- CC /home/reyn/share/drivers/led/led.mod.o
- LD [M] /home/reyn/share/drivers/led/led.ko
- make[1]:正在离开目录 `/opt/EmbedSky/linux-2.6.30.4'
- cp *.ko /home/reyn/share/out/
- 编译成功的话,会生成一些中间文件和最重要的.ko内核模块文件
- reyn@ubuntu:led$ ls
- led.c led.ko led.mod.o Makefile Module.symvers
- led.h led.mod.c led.o modules.order test
再写个应用程序test_led.c做测试:
点击(此处)折叠或打开
- #include <stdio.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <malloc.h>
- #include <sys/ioctl.h>
- int main(int argc, char **argv)
- {
- int nFd = 0;
- char status;
- int nRet = 0;
- char *led_buf;
- int cmd = 1;
- unsigned long arg = 0;
- int ch = 0;
- //open:
- printf("[User] Open led, if succeed, all on.\n");
- nFd = open("/dev/led_driver", O_RDWR);
- if(nFd < 0)
- {
- printf("[User] Can't open %s\n", "led_driver");
- return -1;
- }
-
- write:
- printf("[User] Ready for writing. \n");
- printf("[User] Please input [0/1/2/3/4]:\n");
- while((status = getchar()) == '\n');
- nRet = write(nFd, &status, sizeof(char));
- if(nRet != 1)
- {
- printf("[User] Write error!\n");
- return -1;
- }
- printf("[User] Write:%d.\n", nRet);
-
- if(ch==0 || ch==1 || ch==2 || ch==3)
- {
- ch++;
- goto write;
- }
- else
- {
- ch = 0;
- }
-
- //read:
- printf("[User] Ready for reading.\n");
- getchar();
- led_buf = (char *)malloc(16 * sizeof(char));
- nRet = read(nFd, led_buf, sizeof(char));
- if(nRet < 0)
- {
- printf("[User] Read error.\n");
- return -1;
- }
- printf("[User] Read led status: %s.\n", led_buf);
- free(led_buf);
-
-
- ioctl:
- printf("[User] Ready for ioctl.\n");
- for(arg=0; arg<4; arg++)
- {
- while((ch = getchar()) != '\n');
- ioctl(nFd, cmd, arg);
- printf("[User] ioctl%ld cmd:%d arg:%ld.\n", arg, cmd, arg);
- }
- cmd = !(cmd);
- goto ioctl;
- close(nFd);
-
- return 0;
- }
写个Makefile,也可以直接输入命令arm-linux-gcc test_led.c -o test_led:
点击(此处)折叠或打开
- CC:=arm-linux-gcc
- all:
- $(CC) test_led.c -o test_led -Wall -std=c99
- cp test_led /home/reyn/share/out/
-
- clean:
- rm *~ write_led
- rm /home/reyn/share/out/test_led
点击(此处)折叠或打开
- reyn@ubuntu:test$ make
- arm-linux-gcc test_led.c -o test_led -Wall -std=c99
- cp test_led /home/reyn/share/out/
- 编译成功的话,会生成可执行二进制文件test_led
- reyn@ubuntu:test$ ls
- Makefile test_led test_led.c
[4] 测试运行:
[+] 使用Samba方便快捷地将linux的上述生成的led.ko内核模块文件和test_led二进制文件文件传到windows;
[+] 把文件拷贝到开发板,此过程可以使用secureCRT的rz命令(需要安装一个lrzsz包,请自行Google之);
[+] 修改led.ko 和 test_led 的权限
chmod 777 led.ko test_led
{经测试,只要修改test_led的权限即可}
[+] 插入模块:insmod led.ko
点击(此处)折叠或打开
- [root@EmbedSky /]# insmod led.ko
- [Kernel] led init done.
- [Kernel] request dev number.
- [Kernel] dev add done.
- [major 252] [minor 0] led module inserted.
- 此时查看/proc/devices [查看已经加载的设备和分类] 和 /dev [查看所有外部设备的详细信息] ,
- 可以发现设备号申请成功,设备节点也创建起来了:
- [root@EmbedSky /]# cat /proc/devices
- Character devices:
- 1 mem
- 4 /dev/vc/0
- 4 tty
- 5 /dev/tty
- 5 /dev/console
- 5 /dev/ptmx
- 7 vcs
- 10 misc
- 13 input
- 14 sound
- 29 fb
- 81 video4linux
- 89 i2c
- 90 mtd
- 108 ppp
- 116 alsa
- 128 ptm
- 136 pts
- 180 usb
- 188 ttyUSB
- 189 usb_device
- 204 ttySAC
- 252 led_driver
- 253 usb_endpoint
- 254 rtc
- Block devices:
- 259 blkext
- 7 loop
- 8 sd
- 31 mtdblock
- 65 sd
- ... ...
- ... ...
- [root@EmbedSky /]# ls -l /dev
- crw-rw---- 1 root root 10, 60 Mar 9 2014 adc
- crw-rw---- 1 root root 14, 4 Mar 9 2014 audio
- crw-rw---- 1 root root 10, 61 Mar 9 2014 beep
- crw-rw---- 1 root root 10, 63 Mar 9 2014 bkl
- crw-rw---- 1 root root 10, 59 Mar 9 2014 camera
- crw-rw---- 1 root root 5, 1 Mar 9 13:31 console
- crw-rw---- 1 root root 116, 0 Mar 9 2014 controlC0
- crw-rw---- 1 root root 10, 58 Mar 9 2014 cpu_dma_latency
- lrwxrwxrwx 1 root root 14 Mar 9 2014 dsp -> /dev/sound/dsp
- crw-rw---- 1 root root 13, 64 Mar 9 2014 event0
- crw-rw---- 1 root root 13, 65 Mar 9 2014 event1
- crw-rw---- 1 root root 29, 0 Mar 9 2014 fb0
- crw-rw---- 1 root root 1, 7 Mar 9 2014 full
- crw-rw---- 1 root root 89, 0 Mar 9 2014 i2c-0
- crw-rw---- 1 root root 1, 11 Mar 9 2014 kmsg
- crw-rw---- 1 root root 10, 62 Mar 9 2014 led
- crw-rw---- 1 root root 252, 0 Mar 9 13:29 led_driver
- brw-rw---- 1 root root 7, 0 Mar 9 2014 loop0
- brw-rw---- 1 root root 7, 1 Mar 9 2014 loop1
- ... ...
- ... ...
接着运行test_led:
点击(此处)折叠或打开
- [root@EmbedSky /]# ./test_led
- [User] Open led, if succeed, all on. [打开文件节点]
- [Kernel] led0 on.
- [Kernel] led1 on.
- [Kernel] led2 on.
- [Kernel] led3 on.
- [User] Ready for writing. [写文件节点]
- [User] Please input [0/1/2/3/4]:
- 1
- [Kernel] copy from user:1.
- [Kernel] write led status 1.
- [Kernel] led 1 on.
- [User] Write:1.
- [User] Ready for writing. [写文件节点]
- [User] Please input [0/1/2/3/4]:
- 2
- [Kernel] copy from user:1.
- [Kernel] write led status 2.
- [Kernel] led 1,2 on.
- [User] Write:1.
- [User] Ready for writing. [写文件节点]
- [User] Please input [0/1/2/3/4]:
- 3
- [Kernel] copy from user:1.
- [Kernel] write led status 3.
- [Kernel] led 1,2,3 on.
- [User] Write:1.
- [User] Ready for writing. [写文件节点]
- [User] Please input [0/1/2/3/4]:
- 4
- [Kernel] copy from user:1.
- [Kernel] write led status 4.
- [Kernel] led all on.
- [U[Kernel] led0 on
- [Kernel] led1 on
- [Kernel] led2 on
- [Kernel] led3 on
- [Kernel] copy to user:12.
- ser] Write:1.
- [User] Ready for reading. [读文件节点]
- [User] Read led status: on on on on .
- [User] Ready for ioctl. [ioctl操作]
- 1
- [Kernel] led0 on.
- [User] ioctl0 cmd:1 arg:0.
- [Kernel] led1 on.
- [User] ioctl1 cmd:1 arg:1.
- [Kernel] led2 on.
- [User] ioctl2 cmd:1 arg:2.
- [Kernel] led3 on.
- [User] ioctl3 cmd:1 arg:3.
- [User] Ready for ioctl.
- [Kernel] led0 off.
- [User] ioctl0 cmd:0 arg:0.
- [Kernel] led1 off.
- [User] ioctl1 cmd:0 arg:1.
- [Kernel] led2 off.
- [User] ioctl2 cmd:0 arg:2.
- [Kernel] led3 off.
- [User] ioctl3 cmd:0 arg:3.
- [User] Ready for ioctl.
- [Kernel] led0 on.
- [User] ioctl0 cmd:1 arg:0.
- ^C[Kernel] led all off. [关闭文件节点]
[6] 总结:
[+] 有些时候,开发板默认开启了led,这时进行测试就会失败,因为看不到效果啊。
所以,就需要手动终止开发板的led进程了。
点击(此处)折叠或打开
- [root@EmbedSky /]# ps
- PID USER VSZ STAT COMMAND
- 1 root 2096 S init
- 2 root 0 SW< [kthreadd]
- 3 root 0 SW< [ksoftirqd/0]
- 4 root 0 SW< [events/0]
- 5 root 0 SW< [khelper]
- 11 root 0 SW< [async/mgr]
- 242 root 0 SW< [kblockd/0]
- 252 root 0 SW< [khubd]
- 255 root 0 SW< [kseriod]
- 261 root 0 SW< [kmmcd]
- 286 root 0 SW [pdflush]
- 287 root 0 SW [pdflush]
- 288 root 0 SW< [kswapd0]
- 333 root 0 SW< [aio/0]
- 337 root 0 SW< [nfsiod]
- 341 root 0 SW< [crypto/0]
- 460 root 0 SW< [mtdblockd]
- 580 root 0 SW< [usbhid_resumer]
- 596 root 0 SW< [rpciod/0]
- 613 root 1508 S EmbedSky_wdg
- 614 root 2100 S /bin/sh /bin/qtopia
- 616 root 18552 S qpe
- 619 root 0 SW< [zd1211rw]
- 632 root 1512 S led-player
- 637 root 4756 S /usr/sbin/inetd
- 642 root 2064 S /sbin/boa
- 648 root 2100 S -/bin/sh
- 658 root 9192 S < /opt/Qtopia/bin/qss
- 659 root 12748 S N /opt/Qtopia/bin/quicklauncher
- 668 root 2100 R ps
kill 632,终止即可。
[+] getchar() 输入缓存区问题:
一开始,使用getchar()调试时会造成两次输出(第一次输出正常,第二次不正常),鼓捣了许久,笔者确认代码区没有问题。
于是把重点放在getchar()上,根据笔者的经验,输入输出存在缓存区的问题,现在遇到的清空很可能就是没有清空缓存区的原因。
然后,笔者试着使用Windows下经常使用的fflush(stdin)对标准输入缓存区进行清空,结果发现还是一样的.
百思不得其解,只好Google之。
于是惊奇地发现fflush()在Linux下没有清空输入缓存区的效果,于是你知道的,差点破罐破摔了。
最后总结出来,使用getchar()进行调试的最保险的做法是使用一个while循环对输入的字符进行检测,
如果不是回车符,则继续输入。同理,该方法也适用于scanf()等。
点击(此处)折叠或打开
- while((ch = getchar()) != '\n')
本文原创,如须转载,请注明出处:http://blog.chinaunix.net/blog/post/id/4279550.html
0
上一篇:没有了
下一篇:[个人]Ubuntu编程环境配置
相关热门文章
- 会话与资源限制
- 正确使用控件证书 保证网络安...
- 鲜为人知的win8文件备份新方式...
- 小窍门,轻松修复损坏U盘...
- win8下磁盘分区的三种操作方式...
- shell中字符串操作
- shell中的特殊字符
- stagefright与opencore对比
- linux守护进程的几个关键地方...
- UBOOT移植详细 很全面
给主人留下些什么吧!~~
评论热议
0 0
- 基于TQ2440的led字符设备驱动
- 基于TQ2440开发的LED驱动
- linux设备驱动入门,最简单的LED驱动,基于tq2440
- s3c2440基于linux的gpio led字符设备驱动实践
- s3c2440基于linux的button和led字符设备驱动
- s3c2440基于linux的gpio led字符设备驱动
- s3c2440基于linux的gpio led字符设备驱动实践
- TQ2440 LINUX 2.6.30.4 LED驱动感言,从最初的打印字符,到自动分配设备号,到自动创建设备节点,到次设备号分控led
- TQ2440 LINUX 2.6.30.4 LED驱动感言,从最初的打印字符,到自动分配设备号,到自动创建设备节点,到此设备号分控led
- LED字符设备驱动
- led字符设备驱动
- 字符设备驱动---Led
- Tiny6410 简单的LED字符设备驱动
- 字符设备实现控制led的驱动
- 字符设备实现控制led的驱动
- Tiny6410 简单的LED字符设备驱动
- 字符设备驱动-LED驱动
- 基于mini2440的led字符设备驱动程序
- 数据库详解与介绍 System.Data.SQLite
- Master Page Path MasterPage 相对路径
- 水题 攒人品
- ASDFASDFASD
- 一步一步教你使用.net进行Socket通信
- 基于TQ2440的led字符设备驱动
- [个人]Ubuntu编程环境配置
- 中断驱动学习与实例——定时器0中断实现led流水灯
- Qt 错误: 无法运行 release 下的可执行文件
- Qt 技巧:设置在 debug 路径下直接运行可执行文件
- Qt 技巧:去除对话框边框 + 设置窗口可移动和透明
- 做程序架构设计时须着重考虑的几点
- Qt 代码: QComboBox 添加图片
- Qt 代码: QMessageBox 用法
原创粉丝点击
热门IT博客
热门问题
老师的惩罚
人脸识别
我在镇武司摸鱼那些年
重生之率土为王
我在大康的咸鱼生活
盘龙之生命进化
天生仙种
凡人之先天五行
春回大明朝
姑娘不必设防,我是瞎子
屁眼上长了痔疮怎么办
小纹身晕染了怎么办
半永久纹身晕色怎么办
半永久眼线晕色怎么办
纹的眼线晕染了怎么办
眼干怎么办用什么药物
上眼皮干的起皮怎么办
25岁眼角有细纹怎么办
19岁眼睛有细纹怎么办
做眼线眼睛肿了怎么办
眼睛被揉得很红怎么办
做眼线眼皮肿了怎么办
做了眼线眼睛肿怎么办
眼睛长皱纹了怎么办呢
血压低引起的头痛怎么办
20多岁眼角皱纹怎么办
30岁眼角长皱纹怎么办
一笑眼角有细纹怎么办
21岁眼睛有细纹怎么办
27岁眼角有细纹怎么办
28岁有法令纹怎么办
有鱼尾纹了怎么办才好
开眼角留下的疤怎么办
眼周松弛有细纹怎么办
在娘家睡一起了怎么办
欠医院钱500不还怎么办
欠医院钱300不还怎么办
空压机电压过高怎么办
红掌浇水多了怎么办
鞋子雨水后臭了怎么办
发财树严重烂根怎么办
发财树上面烂了怎么办
发财树顶部烂了怎么办
招财树根烂了怎么办
发财树半边烂了怎么办
发财树树根软了怎么办
新鱼缸的水浑浊怎么办
养鱼的水变浑浊怎么办
绿萝叶子长黄斑怎么办
花浇水浇多了怎么办
孕妇喝了减肥茶怎么办