驱动开发
模块和编译进内核
Makefile中,obj-m是编译成模块,形成.ko的文件,用insmod指令进行加载模块。
obj-y是编译进内核,这无疑会加大内核的体积,所以我们练习的时候用的都是obj-m,随时裁剪内核,方便快捷。
如果用的是编译进内核,那需要重新把内核烧进SD卡或eMMC上,再重新启动开发板。
模块格式
#include <linux/kernel.h>
#include <linux/module.h>
void myfun_module(void);
static int __init onemodule_init(void)
{
myfun_module();
return 0;
}
static void __exit onemodule_exit(void)
{
}
module_init(onemodule_init); //声明
module_exit(onemodule_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("HY");
杂项设备注册
杂项设备是一个杂物间,本来各个设备应该是有各自的分类,这杂项呢就是各种分类的设备都可以放进这个杂物间。
杂项设备的主设备号是10,子设备号写成255表示由系统分配子设备号。
示例代码
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/miscdevice.h>
#define LED1(x) x?(*((unsigned int *)GPM4_DAT)&=~(0xF)):(*((unsigned int *)GPM4_DAT)|=0xF)
void __iomem * GPM4_CON = NULL;
void __iomem * GPM4_DAT = NULL;
struct file_operations myfops;
struct miscdevice mymisc;
int myopen (struct inode *inode,struct file *file)
{
LED1(1);
return 0;
}
int myclose (struct inode *inode,struct file *file)
{
LED1(0);
return 0;
}
static int __init myled1_init(void)
{
GPM4_CON = ioremap(0x110002E0,4);
GPM4_DAT = ioremap(0x110002E4,1);
//config led1
*((unsigned int *)GPM4_CON) |= 0x1111;
myfops.owner = THIS_MODULE;
myfops.open = myopen;
myfops.release = myclose;
mymisc.minor = 255;
mymisc.name = "led1";
mymisc.fops = &myfops;
misc_register(&mymisc);
return 0;
}
static void __exit myled1_exit(void)
{
misc_deregister(&mymisc);
}
module_init(myled1_init);
module_exit(myled1_exit);
MODULE_LICENSE("GPL");