1.結(jié)構(gòu)體platform_driver(vim include/linux/platform_device.h)
struct platform_driver {
? ? ? ? int (*probe)(struct platform_device *);
? ? ? ? int (*remove)(struct platform_device *);
? ? ? ? void (*shutdown)(struct platform_device *);
? ? ? ? int (*suspend)(struct platform_device *, pm_message_t state);
? ? ? ? int (*resume)(struct platform_device *);
? ? ? ? struct device_driver driver;
? ? ? ? const struct platform_device_id *id_table;
};
struct device_driver {
? ? ? ? const char? ? ? ? ? ? ? *name;
? ? ? ? struct bus_type? ? ? ? *bus;
? ? ? ? struct module? ? ? ? ? *owner;
? ? ? ? const char? ? ? ? ? ? ? *mod_name;? ? ? /* used for built-in modules */
? ? ? ? bool suppress_bind_attrs;? ? ? /* disables bind/unbind via sysfs */
? ? ? ? const struct of_device_id? ? ? *of_match_table;
? ? ? ? int (*probe) (struct device *dev);
? ? ? ? int (*remove) (struct device *dev);
? ? ? ? void (*shutdown) (struct device *dev);
? ? ? ? int (*suspend) (struct device *dev, pm_message_t state);
? ? ? ? int (*resume) (struct device *dev);
? ? ? ? const struct attribute_group **groups;
? ? ? ? const struct dev_pm_ops *pm;
? ? ? ? struct driver_private *p;
};
? ? ——注冊結(jié)構(gòu)體
? ? ?驅(qū)動常見的幾種狀態(tài),初始化,移除,休眠,復位
? ? ? ?–就像PC一樣,有的驅(qū)動休眠之后無法使用,有的可以使用;有的系統(tǒng)喚醒之后,驅(qū)動需要重新啟動才能正常工作,也有直接就可以使用等等
? ? ?probe函數(shù)
? ? ? ?–platform_match函數(shù)匹配之后,驅(qū)動調(diào)用的初始化函數(shù)
? ? ??remove函數(shù)
? ? ? ? –移除驅(qū)動函數(shù)
? ? ?suspend函數(shù)
? ? ? ?–懸掛(休眠)驅(qū)動函數(shù)
? ? ??resume函數(shù)
? ? ? ?–休眠后恢復驅(qū)動
? ? ?device_driver數(shù)據(jù)結(jié)構(gòu)的兩個參數(shù)
? ? ? ? ? ? ?–name和注冊的設(shè)備name要一致
? ? ? ? ? ? ?–owner一般賦值THIS_MODULE
2.驅(qū)動注冊函數(shù)
? ? ? ? extern int platform_driver_register(struct platform_driver *);
? ? ? ? extern void platform_driver_unregister(struct platform_driver *);
3.驅(qū)動例子(hello_module.c)
? ? ? ? #include <linux/init.h>
? ? ? ? #include <linux/module.h>
? ? ? ?/*驅(qū)動注冊的頭文件,包含驅(qū)動的結(jié)構(gòu)體和注冊和卸載的函數(shù)*/
? ? ? ?#include <linux/platform_device.h>
? ? ? ?#define DRIVER_NAME "hello_ctl"
? ? ? ? MODULE_LICENSE("Dual BSD/GPL");
? ? ? ? MODULE_AUTHOR("WENDONG");
? ? ? ? static int hello_probe(struct platform_device *pdv){
? ? ? ? ? ? ? ? printk(KERN_EMERG "\tprobe initialized\n");?
? ? ? ? ? ? ? ? return 0;
? ? ? ? }
? ? ? ?/*Drive Remove*/
? ? ? ? static int hello_remove(struct platform_device *pdv){
? ? ? ? ? ? ? ??return 0;
? ? ? ? }
? ? ? ?static void hello_shutdown(struct platform_device *pdv){
? ? ? ? ? ? ? ?;
? ? ? ? }
? ? ? /*Driver 睡眠*/
? ? ? static int hello_suspend(struct platform_device *pdv,?pm_message_tstate){
? ? ? ? ? ? ? return 0;
? ? ? ?}
? ? ? ?/*Driver喚醒*/
? ? ? static int hello_resume(struct platform_device *pdv){
? ? ? ? ? ? ? return 0;
? ? ? ? }
? ? ? ? struct platform_driver hello_driver = {
? ? ? ? ? ? ? ? .probe = hello_probe,
? ? ? ? ? ? ? ? .remove = hello_remove,
? ? ? ? ? ? ? ? .shutdown = hello_shutdown,
? ? ? ? ? ? ? ? .suspend = hello_suspend,
? ? ? ? ? ? ? ? .resume = hello_resume,
? ? ? ? ? ? ? ?.driver = {
? ? ? ? ? ? ? ? ? ? ? ?.name = DRIVER_NAME,
? ? ? ? ? ? ? ? ? ? ? ?.owner = THIS_MODULE,
? ? ? ? ? ? ? }
? ? ? };
? ? ? static int hello_init(void)
? ? ? {
? ? ? ? ? ? ? printk(KERN_EMERG "HELLO WORLD enter!\n");
? ? ? ? ? ? ??int DriverState = platform_driver_register(&hello_driver);
? ? ? ? ? ? ??printk(KERN_EMERG "\tDriverState is %d\n",DriverState);
? ? ? ? ? ? ? return 0;
? ? ? }
? ? ? ? static void hello_exit(void)
? ? ? ? {
? ? ? ? ? ? ? ? printk(KERN_EMERG "HELLO WORLD exit!\n");
? ? ? ? ? ? ? ? platform_driver_unregister(&hello_driver);
? ? ? ? }
? ? ? ? ?/*模塊進入*/
? ? ? ? module_init(hello_init);
? ? ? ? ?/*模塊退出 */
? ? ? ? module_exit(hello_exit);
4. Makefile文件
#!/bin/bash
#通知編譯器我們要編譯模塊的哪些源碼
#這里是編譯hello_module.c這個文件編譯成中間文件hello_module.o
obj-m += hello_module.o
#源碼目錄變量,這里用戶需要根據(jù)實際情況選擇路徑
#作者是將Linux的源碼拷貝到目錄/home/topeet/kernal/4.4/下并解壓的
KDIR := /home/topeet/kernal/4.4/iTop4412_Kernel_3.0
#當前目錄變量
PWD ?= $(shell pwd)
#make命名默認尋找第一個目標
#make -C就是指調(diào)用執(zhí)行的路徑
#$(KDIR)Linux源碼目錄,作者這里指的是/home/topeet/kernal/4.4/iTop4412_Kernel_3.0
#$(PWD)當前目錄變量
#modules要執(zhí)行的操作
all:
make -C $(KDIR) M=$(PWD) modules
#make clean執(zhí)行的操作是刪除后綴為o的文件
clean:
rm -rf *.o
5.make,編譯生成驅(qū)動ko文件
6.
? ? insmod hello.ko 注冊模塊
? ? lsmod , cat /proc/modules | grep hello* 查看模塊?
? ? rmmod 移除模塊