实现平台: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
阅读(309) | 评论(0) | 转发(0) |
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
实现工具: 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
相关热门文章
给主人留下些什么吧!~~
评论热议