Giriş
Şuna benzer satırlar dahil edilir.
Şöyledir
Her sürücü için modülü yükleyen şu metod lazım.
Her sürücü için modülü kaldıran şu metod lazım.
Şöyle yaparız.
Şöyle yaparız.
Device Deriver yazarken bir sürü struct ve function pointer kullanıyoruz. Mantık şuna benziyor. Önce bir header dosyasında struct ve function imzaları tanımlarız.
1. pci_module_init metodu
mydriver_init içinde pci_module_init metodu çağrılarak yapılır. Önce cihazımız için kullanacağımız metodları bir yapıya yerleştiririz. Aşağıdaki örnekte suspend ve resume alanlar gösterilmiyor.
2. pci_enable_device metodu
Bu metod pci_request_regions() çağrısından önce yapılır.
3. id_table alanı
Kullanılan değerler şöyle
Şuna benzer satırlar dahil edilir.
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/time.h>
#include <linux/delay.h>
İskeletŞöyledir
MODULE_LICENSE("GPL");
MODULE_AUTHOR("...");
static int __init irq_ex_init(void)
{
...
}
static void __exit irq_ex_exit(void)
{
...
}
module_init(irq_ex_init);
module_exit(irq_ex_exit);
module_initHer sürücü için modülü yükleyen şu metod lazım.
module_init(mydriver_init);
mydriver_init'in imzası şöyle. Metodun static olması isteğe bağlıstatic int mydriver_init(void)
{...}
veya bazen __init ile kullanılıyor. Yani şöylestatic int __init mydirver_init(void)
{...}
Bu metodun içinde printk kullanılabilir. Sonuç olarak 0 dönülebilir. Şöyle yaparız.int mydriver_init(void)
{
printk(KERN_DEBUG "module initiated\n");
...
return 0;
}
module_exitHer sürücü için modülü kaldıran şu metod lazım.
module_exit(mydriver_exit);
mydriver_exit'in imzası şöyle.
static void mydriver_exit(void)
{...}
veya bazen __exit ile kullanılıyor. Yani şöylestatic void __exit mydriver_exit(void)
{...}
Bu metodun içinde print kullanılabilir. Şöyle yaparız.void mydriver_exit(void)
{
...
printk(KERN_DEBUG "module removed\n");
}
MODULE_X MacrolarıŞöyle yaparız.
module_init(initialize);
module_exit(final);
MODULE_AUTHOR("...");
MODULE_DESCRIPTION("...");
MODULE_LICENSE MacrosuŞöyle yaparız.
MODULE_LICENSE("GPL");
Şöyle yaparız.MODULE_LICENSE("Dual BSD/GPL");
Struct ve Function PointerDevice Deriver yazarken bir sürü struct ve function pointer kullanıyoruz. Mantık şuna benziyor. Önce bir header dosyasında struct ve function imzaları tanımlarız.
struct tune_if_t
{
void (*init_radio) (void);
void (*calibrate_radio) (void);
};
extern const struct tune_if_t tune_if;
Daha sonra bu struct'ın bir nesnesini yaratırız ve ilklendiririz.// function bodies that do things
void radio1_init_radio(void) {}
void radio1_calibrate_radio(void) {}
// populate global tune interface
const struct tune_if_t tune_if =
{
.init_radio = radio1_init_radio,
.calibrate_radio = radio1_calibrate_radio
}
Bu struct artık class gibi kullanılabilir. Sanırım bu yüzden Linux Device Drive kodlarındaki alanlar . karakteri ile başlıyor.int main( void )
{
// interface calls
tune_if.init_radio();
tune_if.calibrate_radio();
return 0;
}
pci sürücü yaratma1. pci_module_init metodu
mydriver_init içinde pci_module_init metodu çağrılarak yapılır. Önce cihazımız için kullanacağımız metodları bir yapıya yerleştiririz. Aşağıdaki örnekte suspend ve resume alanlar gösterilmiyor.
static struct pci_driver pci_drv = {
.name= "pci_drv",
.id_table= pci_drv_tbl,
.probe= device_init,
.remove= device_deinit,
};
Daha sonra cihazımı ilklendiririz.
pci_module_init(&pci_drv)
Bu çağrı sonucu tanımladığımız probe metodumuz tetiklenir.
pci_driver yapısını ilklendirirken kullanacağımız metodların imzaları şöyle.
2. pci_enable_device metodu
Bu metod pci_request_regions() çağrısından önce yapılır.
3. id_table alanı
Kullanılan değerler şöyle
// Hardware specific part
#define MY_VENDOR_ID 0x5333
#define MY_DEVICE_ID 0x8e40
Yapısı şöylestatic struct pci_device_id pci_drv_tbl[] __devinitdata = {
{ MY_VENDOR_ID, // manufacturer identifier
MY_DEVICE_ID, // device identifier
PCI_ANY_ID, // subsystem manufacturer identifier
PCI_ANY_ID, // subsystem device identifier
0, // device class
0, // mask for device class
0 }, // driver specific data
{ 0, }
};
4. probe metodu
probe metodu şöyle bir imzaya sahip.
// Check if this driver is for the new device
static int device_init(struct pci_dev *dev,const struct pci_device_id *id)
{...}
5. remove
remove metodu şöyle bir imzaya sahip.
// Function for deinitialization of the device
static void device_deinit( struct pci_dev *pdev )
{...}
6. request_irq metodu
Interrupt callback için kullanılır. İmzası şöyle. Birinci parametre IRQ index sayısıdır.
bus alanı
Şöyledir
Açıklaması şöyle.
Şöyledir
Interrupt callback için kullanılır. İmzası şöyle. Birinci parametre IRQ index sayısıdır.
request_irq(int num, void * interrupt_handler, static char *interrupt_name,
struct platform_device *platform);
pci_dev yapısıbus alanı
Şöyledir
struct pci_bus *bus;
devfn AlanıAçıklaması şöyle.
Devfn contains the device number in bits 7:3 and the function number in bits 2:0.Şöyle yaparız.
device = PCI_SLOT(pdev->devfn);
fn = PCI_FUNC(pdev->devfn);
function alanıŞöyledir
unsigned int devfn;
printk metodu
Bu metod tek parametre alır. Şöyle yaparız.
printk(KERN_ALERT "hello, this is hello module");
Şu örnek derlenmez.printk(KERN_ALERT, "hello, this is hello module");
Hiç yorum yok:
Yorum Gönder