linux这一个点灯应用程序,嵌入式Linux 底层到到应用层 点灯 (基于iTOP4412)

编程入门 行业动态 更新时间:2024-10-13 10:27:21

linux<a href=https://www.elefans.com/category/jswz/34/1768373.html style=这一个点灯应用程序,嵌入式Linux 底层到到应用层 点灯 (基于iTOP4412)"/>

linux这一个点灯应用程序,嵌入式Linux 底层到到应用层 点灯 (基于iTOP4412)

其实这篇博客就是上篇博客

先在总线上注册LED这个设备 ,这里我的设备名命名为 MyLED_device

#include #include #include MODULE_LICENSE("Dual BSD/GPL");

MODULE_AUTHOR("HQU_Orange");

#define DEVICE_NAME"MyLED_device"

void MyLED_device_release(struct device *dev);

struct platform_device MyLED_device =

{

.name=DEVICE_NAME,

.id=-1, //-1代表设备数量为1

.dev=

{

.release=MyLED_device_release ,

}

};

static int Mini_Linux_Device_Module_Init (void)

{

int Device_Status;

printk(KERN_EMERG "Mini Liunx Device Module Enter ! \r\n");

Device_Status=platform_device_register(&MyLED_device);

printk(KERN_EMERG "Module Device Status is %d \n",Device_Status);

return 0;

}

static void Mini_Linux_Device_Module_Exit (void)

{

platform_device_unregister(&MyLED_device);

printk(KERN_EMERG "Mini Linux Device Module Exit ! \r\n");

}

void MyLED_device_release(struct device *dev)

{

printk(KERN_EMERG DEVICE_NAME "\tdevice release wolk!\r\n");

}

module_init(Mini_Linux_Device_Module_Init);

module_exit(Mini_Linux_Device_Module_Exit);

下面是最重要的部分,LED的驱动编写,我先将代码贴出来

#include #include #include #include #include #include #include #include #include MODULE_LICENSE("Dual BSD/GPL");

MODULE_AUTHOR("HQU_Orange");

#define DEVICE_NAME"MyLED_device"

#define DEVICENODE_NAME"MyLED"

int MyLED_driver_probe(struct platform_device* MyLED_device);

int MyLED_driver_remove(struct platform_device* MyLED_device);

void MyLED_driver_shutdown(struct platform_device* MyLED_device);

int MyLED_driver_suspend(struct platform_device* MyLED_device,pm_message_t state);

int MyLED_driver_resume(struct platform_device* MyLED_device);

int MyLED_driver_fops_open(struct inode* p_inode,struct file* p_file);

int MyLED_driver_fops_release(struct inode* p_inode,struct file* p_file);

long MyLED_driver_fops_unlocked_ioctl(struct file* p_file ,unsigned int ID ,unsigned long cmd);

struct platform_driver MyLED_driver =

{

.probe=MyLED_driver_probe,

.remove=MyLED_driver_remove,

.shutdown=MyLED_driver_shutdown,

.suspend=MyLED_driver_suspend,

.resume=MyLED_driver_resume,

.driver=

{

.name=DEVICE_NAME,

.owner=THIS_MODULE,

}

};

struct file_operations MyLED_driver_fops =

{

.owner=THIS_MODULE,

.open=MyLED_driver_fops_open,

.release=MyLED_driver_fops_release,

.unlocked_ioctl=MyLED_driver_fops_unlocked_ioctl,

};

struct miscdevice MyLED_misc_device=

{

.minor=MISC_DYNAMIC_MINOR,

.name=DEVICENODE_NAME,

.fops=&MyLED_driver_fops,

};

static int Mini_Linux_Driver_Init (void)

{

int Driver_Status;

printk(KERN_EMERG "Mini Liunx Module Enter ! \r\n");

Driver_Status=platform_driver_register(&MyLED_driver);

printk(KERN_EMERG "Driver Status is %d \n",Driver_Status);

return 0;

}

static void Mini_Linux_Driver_Exit (void)

{

platform_driver_unregister(&MyLED_driver);

printk(KERN_EMERG "Mini Linux Module Exit ! \r\n");

}

int MyLED_driver_probe(struct platform_device* MyLED_device)

{

int res;

printk(KERN_EMERG "device-> name = %s device -> id = %d probe !\r\n",MyLED_device->name,MyLED_device->id);

gpio_free(EXYNOS4_GPL2(0));

gpio_free(EXYNOS4_GPK1(1));

res=gpio_request(EXYNOS4_GPL2(0),"MyLED_1");

if(res==-1)

{printk(KERN_EMERG "%s L2(0) gpio request fail !\r\n",MyLED_device->name);return res ;}

res=gpio_request(EXYNOS4_GPK1(1),"MyLED_2");

if(res==-1)

{printk(KERN_EMERG "%s K1(1) gpio request fail !\r\n",MyLED_device->name);return res ;}

s3c_gpio_cfgpin(EXYNOS4_GPL2(0),S3C_GPIO_OUTPUT);

gpio_set_value(EXYNOS4_GPL2(0),0);

s3c_gpio_cfgpin(EXYNOS4_GPK1(1),S3C_GPIO_OUTPUT);

gpio_set_value(EXYNOS4_GPK1(1),0);

misc_register(&MyLED_misc_device);

return 0;

}

int MyLED_driver_remove(struct platform_device* MyLED_device)

{

printk(KERN_EMERG "device-> name = %s device -> id = %d remove!\r\n",MyLED_device->name,MyLED_device->id);

misc_deregister(&MyLED_misc_device);

return 0;

}

void MyLED_driver_shutdown(struct platform_device* MyLED_device)

{

printk(KERN_EMERG "device-> name = %s device -> id = %d shutdown!\r\n",MyLED_device->name,MyLED_device->id);

}

int MyLED_driver_suspend(struct platform_device* MyLED_device,pm_message_t state)

{

printk(KERN_EMERG "device-> name = %s device -> id = %d suspend!\r\n",MyLED_device->name,MyLED_device->id);

return 0;

}

int MyLED_driver_resume(struct platform_device* MyLED_device)

{

printk(KERN_EMERG "device-> name = %s device -> id = %d resume!\r\n",MyLED_device->name,MyLED_device->id);

return 0;

}

int MyLED_driver_fops_open(struct inode* p_inode,struct file* p_file)

{

printk(KERN_EMERG "MyLED_file_open \r\n");

return 0;

}

int MyLED_driver_fops_release(struct inode* p_inode,struct file* p_file)

{

printk(KERN_EMERG "MyLED_file_release \r\n");

return 0;

}

long MyLED_driver_fops_unlocked_ioctl(struct file* p_file ,unsigned int ID ,unsigned long cmd)

{

printk(KERN_EMERG "ID is %d cmd is %d \r\n" ,ID , cmd);

if(ID>2||cmd>2)

{

printk(KERN_EMERG "ID and cmd must are 0 or 1\r\n");

return 1;

}

if(ID)

gpio_set_value(EXYNOS4_GPL2(0),cmd);

else

gpio_set_value(EXYNOS4_GPK1(1),cmd);

return 0;

}

module_init(Mini_Linux_Driver_Init);

module_exit(Mini_Linux_Driver_Exit);

熟悉单片机的应该知道其实驱动LED其实就是控制一个引脚的电平。

gpio_free() 其实不是必要的,因为 我之前烧进去的内核已经将这个两个引脚资源先占用了,而现在为了方便调试用了模块加载的方法,故要先释放这两个引脚的资源,才能用我们自己的驱动控制这两个引脚。

gpio_request() 请求 引脚资源

s3c_gpio_cfgpin() 引脚模式设置

gpio_set_value()引脚输出电平设置

ioctl的实现,下面应用会调用到这个函数。

编写应用程序

#include #include #include #include #include #include #include #include int main(int argc ,char* argv[])

{

int fd ;

int res;

char* file_node = argv[1];

char id = atoi(argv[2]);

char cmd = atoi(argv[3]);

fd=open(file_node,O_RDWR|O_NOCTTY|O_NDELAY);

if(fd==-1)

{

perror(file_node);

exit(EXIT_FAILURE);

}

res=ioctl(fd,id,cmd);

if(res==-1)

{

perror("ioctl");

close(fd);

exit(EXIT_FAILURE);

}

close(fd);

exit(EXIT_SUCCESS);

}

编写Makeflie

obj-m +=MyLED_Device.o

obj-m +=MyLED_Driver.o

KDIR := /home/topeet/zImage/iTop4412_Kernel_3.0

PWD?= $(shell pwd)

all:

make -C$(KDIR) M=$(PWD) modules

clean:

rm -rf *.o *.mod.c *.order *.symvers

make编译

再编译 应用程序 arm-none-linux-gnueabi-gcc -o  linux_file_ioctl linux_file_ioctl.c  -static

将这个三个文件传输到板子上。

先加载设备在加载驱动

此时两个LED灭了,说明在probe函数里面将gpio电平拉低的程序起作用了

查看/dev目录 生成了我们的设备节点

调用应用程序试试看

输入命令  ./linux_file_ioctl  /dev/MyLED  0 1

发现板子上的靠近蜂鸣器的led亮了

再输入命令  ./linux_file_ioctl /dev/MyLED  1 1

                                                                              发现靠近按键的另外一个灯也亮了

结合ioctl程序

说明LED驱动工作正常。

其实熟悉了Linux框架后,就是调用厂家提供的库函数进行开发驱动,相信熟悉单片机的都知道,这套流程下来除去与Linux内核

打交道的代码外,其实就是一个gpio模式设置和一个gpio电平变化。

更多推荐

linux这一个点灯应用程序,嵌入式Linux 底层到到应用层 点灯 (基于iTOP4412)

本文发布于:2024-02-12 12:00:07,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1687705.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:这一   底层   嵌入式   应用程序   应用层

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!