编写应用程序进行测试
设置定时器,每5秒打印一次hello world
- #include <linux/init.h>
- #include <linux/module.h>
- #include<linux/of.h>
- #include<linux/of_gpio.h>
- #include<linux/fs.h>
- #include<linux/io.h>
- #include<linux/gpio.h>
- /* myled
- {
- led1-gpio=<&gpioe 10 0>;
- led2-gpio=<&gpiof 10 0>;
- led3-gpio=<&gpioe 8 0>;
- };
- */
- struct device_node *dnode;
- unsigned int gpiono;
- unsigned int gpiono2;
- unsigned int gpiono3;
- struct timer_list mytimer;
- char kbuf[128]={0};
- int major;
-
- //定时器处理函数
- void mytimer_function(struct timer_list *timer)
- {
- //打印
- printk("hello world\n");
- //再次启用定时器
- mod_timer(timer,jiffies+5*HZ);
- }
-
- ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
- {
- int net = copy_from_user(kbuf, ubuf, size);
- if (net)
- {
- printk("copy_from_user filed\n");
- return -EIO;
- }
- switch(kbuf[0]){
- case '1'://LED1
- if(kbuf[1]=='0')//关灯
- gpio_set_value(gpiono,0);
- else
- //灯亮
- gpio_set_value(gpiono,1);
- break;
- case '2'://LED2
- if(kbuf[1]=='0')//关灯
- gpio_set_value(gpiono2,0);
- else
- //灯亮
- gpio_set_value(gpiono2,1);
- break;
- case '3'://LED3
- if(kbuf[1]=='0')//关灯
- gpio_set_value(gpiono3,0);
- else
- //灯亮
- gpio_set_value(gpiono3,1);
- break;
- }
- return 0;
- }
-
- struct file_operations fops={
- .write=mycdev_write,
- };
-
- static int __init mycdev_init(void)
- {
- //字符设备驱动注册
- major=register_chrdev(0,"mychrdev",&fops);
- if(major<0)
- {
- printk("字符设备驱动注册失败\n");
- return major;
- }
- printk("字符设备驱动注册成功:major=%d\n",major);
-
-
- //解析设备树节点信息
- dnode=of_find_node_by_path("/myled");
- if(dnode==NULL)
- {
- printk("解析设备树节点失败\n");
- return -ENXIO;
- }
- //获取LED1 GPIO编号
- gpiono=of_get_named_gpio(dnode,"led1-gpio",0);
- if(gpiono<0)
- {
- printk("获取GPIO编号失败\n");
- return -ENXIO;
- }
- gpiono2=of_get_named_gpio(dnode,"led2-gpio",0);
- if(gpiono2<0)
- {
- printk("获取GPIO编号失败\n");
- return -ENXIO;
- }
- gpiono3=of_get_named_gpio(dnode,"led3-gpio",0);
- if(gpiono3<0)
- {
- printk("获取GPIO编号失败\n");
- return -ENXIO;
- }
- //申请gpio编号
- int ret=gpio_request(gpiono,NULL);
- if(ret)
- {
- printk("申请GPIO编号失败\n");
- return -ENXIO;
- }
- printk("申请GPIO编号成功:%d\n",gpiono);
- //申请gpio编号
- int ret2=gpio_request(gpiono2,NULL);
- if(ret2)
- {
- printk("申请GPIO编号失败\n");
- return -ENXIO;
- }
- printk("申请GPIO编号成功:%d\n",gpiono2);
- //申请gpio编号
- int ret3=gpio_request(gpiono3,NULL);
- if(ret3)
- {
- printk("申请GPIO编号失败\n");
- return -ENXIO;
- }
- printk("申请GPIO编号成功:%d\n",gpiono3);
-
- //初始化定时器对象
- timer_setup(&mytimer,mytimer_function,0);
- mytimer.expires=jiffies+5*HZ;//定时1s;
- //注册定时器
- add_timer(&mytimer);
-
- //设置GPIO为输出
- ret=gpio_direction_output(gpiono,0);
- if(ret)
- {
- printk("GPIO输出设置失败\n");
- return -1;
- }
- //设置GPIO为输出
- ret2=gpio_direction_output(gpiono2,0);
- if(ret2)
- {
- printk("GPIO输出设置失败\n");
- return -1;
- }
- //设置GPIO为输出
- ret3=gpio_direction_output(gpiono3,0);
- if(ret3)
- {
- printk("GPIO输出设置失败\n");
- return -1;
- }
- // //灯亮
- // gpio_set_value(gpiono,1);
- // //灯亮
- // gpio_set_value(gpiono2,1);
- // //灯亮
- // gpio_set_value(gpiono3,1);
- return 0;
- }
- static void __exit mycdev_exit(void)
- {
- //注销定时器
- del_timer(&mytimer);
- //gpiod_set_value(gpiono,0);
- gpio_set_value(gpiono,0);
- gpio_set_value(gpiono2,0);
- gpio_set_value(gpiono3,0);
- //释放GPIO编号
- gpio_free(gpiono);
- //释放GPIO编号
- gpio_free(gpiono2);
- //释放GPIO编号
- gpio_free(gpiono3);
- //注销字符设备驱动
- unregister_chrdev(major,"mychrdev");
-
- }
- module_init(mycdev_init);
- module_exit(mycdev_exit);
- MODULE_LICENSE("GPL");
-
-
应用程序
- #include<stdlib.h>
- #include<stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include<unistd.h>
- #include<string.h>
-
-
- int main(int argc, char const *argv[])
- {
- char buf[128]={0};
- int fd=open("/dev/mychrdev",O_RDWR);
- if(fd<0)
- {
- printf("打开设备文件失败\n");
- exit(-1);
- }
- while(1)
- {
- //从终端读取
- printf("请输入两个字符\n");
- printf("第一个字符:1(LED1) 2(LED2) 3(LED3)\n");
- printf("第二个字符:0(关灯) 1(开灯)\n");
- printf("请输入>");
- fgets(buf,sizeof(buf),stdin);
- buf[strlen(buf)-1]='\0';
- //向设备文件中写
- write(fd,buf,sizeof(buf));
- }
- return 0;
- }