历史上的今天
今天是:2025年02月15日(星期六)
2019年02月15日 | ARM开发之杂项设备的编写----以LED驱动为例
2019-02-15 来源:eefocus
平台:S5PV210
杂项设备的好处:
有了字符型设备后,为什么要用杂项设备?
1.节省主设备号,所有杂项设备的主设备号都是10
2.杂项设备开发起来比字符型设备简单
开发步骤:
1.定义1个杂项设备
2.定义杂项设备的文件操作集
3.申请物理内存区
4.获取相应的虚拟地址
5.注册混杂设备
6.示例代码
1.定义杂项设备
static struct miscdevice led_misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = "misc_led",
.fops = &fops,
};
如上代码:其中.minor代表动态生成次设备号,不用改。
.name表示这个混杂设备文件结点的名字,用户程序用open在 /dev 目录下打开文件的就是 .name 的值。
.fops代表杂项设备的文件操作集
2.定义文件操作集
static struct file_operations fops =
{
.owner = THIS_MODULE,
.open = misc_open,
.write = misc_write,
};
文件操作集表示了杂项设备用了哪些系统调用,如上代码就是用了 open 和 write。
第一个参数不用变,.owner一定写THIS_MODULE,用于初始化。
3.申请物理内存区
static struct resource *res = NULL;
res = request_mem_region(0xE0200280,8,"LED");
上面表示,控制LED的物理地址为0XE0200280开始,8个字节,并把这段内存起名为LED
4.获取相应虚拟地址。
操作系统操作的都是虚拟地址。
static unsigned int va = NULL;
va = ioremap(0xE02000A0,8);
va就是物理地址映射的虚拟地址的起始地址。
5.注册杂项设备
int ret;
ret = misc_register(&led_misc);
if(ret < 0)
{
printk("misc register is error\n");
return -1;
}
misc_register()的参数就是第一步定义的杂项设备变量。
6.示例代码(LED驱动)
#include
#include
#include
#include
#include
#include
#include
#include
#include
static struct resource* res = NULL;
static unsigned int *GPJ2CON_VA = NULL;
static unsigned int *GPJ2DAT_VA = NULL;
static char wbuf[1];
static ssize_t misc_write(struct file *f, const char __user*buf,
size_t len, loff_t *t)
{
copy_from_user(wbuf,buf,len);
if(wbuf[0] == '0')
{
*GPJ2DAT_VA &=~0xf;
}
if(wbuf[0] == '1')
{
*GPJ2DAT_VA &=~0xf;
*GPJ2DAT_VA |=0xf;
}
return 0;
}
/*2.定义文件操作集*/
static struct file_operations fops={
.owner = THIS_MODULE,
.write = misc_write,
};
/*1.定义misc杂项设备变量*/
static struct miscdevice misc_led={
.minor = MISC_DYNAMIC_MINOR,
.name = "led_misc",
.fops = &fops,
};
static int __init misc_init(void)
{
int ret;
/*3.申请物理内存*/
res = request_mem_region(0xe0200280,8,"LED");
if(res == NULL)
{
printk("failed to request_mem_region\n");
goto failed_request_mem;
}
/*4.获取虚拟地址*/
GPJ2CON_VA = ioremap(0xe0200280,8);
if(GPJ2CON_VA == NULL)
{
printk("failed to ioremap\n");
goto failed_ioremap;
}
GPJ2DAT_VA = GPJ2CON_VA + 1;
/*5注册杂项设备*/
ret = misc_register(&misc_led);
if(ret<0)
{
printk("failed to register misc\n");
goto failed_register;
}
printk("init completed\n");
return 0;
failed_register:
iounmap(GPJ2CON_VA);
failed_ioremap:
release_mem_region(0xe0200280,8);
failed_request_mem:
return -1;
}
static void __exit misc_exit(void)
{
iounmap(GPJ2CON_VA);
release_mem_region(0xe0200280,8);
misc_deregister(&misc_led);
}
module_init(misc_init);
module_exit(misc_exit);
MODULE_LICENSE("GPL");
用户程序测试代码:
#include
#include
int main()
{
char buf[1];
buf[0]='0';
int fd = open("/dev/led_misc",O_WRONLY);
if(fd<0)
{
perror("failed to open");
return -1;
}
while(1)
{
write(fd,buf,1);
sleep(1);
buf[0] = '1';
write(fd,buf,1);
sleep(1);
buf[0] = '0';
}
return 0;
}
史海拾趣
|
屏幕尺寸:14.1英寸 重量:2.27Kg 处理器:AMD 炫龙 II M340 主板芯片组:AMD RX881 显卡:ATI HD 4330 光驱类型:DVD刻录机 内存大小:2GB 硬盘大小:320GB 用途 单片机开发 程序开发… 查看全部问答> |
|
我有一台wince5.0的设备,装上调试版运行一程序,正常情况下,按键等操作都会在超级终端上打印出信息;我做了一些操作后(会频繁读写SD卡的操作),按键消息都打印不出来了。。。。那是驱动打印出来的,是不是驱动异常了?但超级终端上也没有异常信息 ...… 查看全部问答> |
|
发光二极管(LED)照明为标新立异、舒适和用户定制开启了一片新天地。这些设计机遇在迅速提升LED在车内的应用程度和速度。当把LED用在车内、车前和车尾照明时,有几种方法和设计技术可供选择。 对车用LED来说,其相对抗振、寿命长、高能效及 ...… 查看全部问答> |
|
干这行最核心的就是使用测试机了。先放一张我见过比较牛逼的测试机镇楼--安捷伦93k(1024 channel),开开眼,据说intel的cpu也是有用这个平台测试的。某司的费用是100$/hour。不过还没那么幸运能玩弄这个东西,too 贵(当然还有一些其他niubil ...… 查看全部问答> |




