用一個例項來理解驅動程式編寫流程 (自用)
阿新 • • 發佈:2019-01-10
#include <linux/kernel.h>
#include <asm/io.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
//流水燈程式碼
#define GPM4CON 0x110002e0#define GPM4DAT 0x110002e4
static unsigned long* ledcon = NULL;
static unsigned long* leddat = NULL;
//自定義write檔案操作(不自定義的話,核心有預設的一套檔案操作函式)
static ssize_t test_write (struct file * filp, const char __user * buff, size_t count, loff_t * offset)
{
int value = 0;
int ret = 0;
ret = copy_from_user(&value, buff, 4);
//底層驅動只定義基本操作動作,不定義功能
{
*leddat |= 0x0f;
*leddat &= 0xfe;
}
if(value == 2)
{
*leddat |= 0x0f;
*leddat &= 0xfd;
}
if(value == 3)
{
*leddat |= 0x0f;
*leddat &= 0xfb;
}
if(value == 4)
{
*leddat |= 0x0f;
*leddat &= 0xf7;
}
return 0;
}
//檔案操作結構體初始化
.owner = THIS_MODULE,
.write = test_write,
};
//雜裝置資訊結構體初始化
static struct miscdevice g_tmisc = {.minor = MISC_DYNAMIC_MINOR,
.name = "test_led",
.fops = &g_tfops,
};
//驅動入口函式 雜裝置初始化
static int __init test_misc_init(void)
{
//IO地址空間對映到核心的虛擬地址空間
ledcon = ioremap(GPM4CON, 4);leddat = ioremap(GPM4DAT, 4);
//初始化led
*ledcon &= 0xffff0000;*ledcon |= 0x00001111;
*leddat |= 0x0f;
//雜設備註冊函式
misc_register(&g_tmisc);return 0;
}
//驅動出口函式
static void __exit test_misc_exit(void){
//釋放地址對映
iounmap(ledcon);
iounmap(leddat);
}
//指定模組的出入口函式
module_init(test_misc_init);module_exit(test_misc_exit);
MODULE_LICENSE("GPL");