GNU/Linux >> Znalost Linux >  >> Linux

Ovladač zařízení IOCTL Linux

ioctl Funkce je užitečná pro implementaci ovladače zařízení pro nastavení konfigurace na zařízení. např. tiskárna, která má možnosti konfigurace pro kontrolu a nastavení rodiny písem, velikosti písma atd. ioctl lze použít k získání aktuálního písma a také k nastavení písma na nové. Uživatelská aplikace používá ioctl k odeslání kódu do tiskárny, který jí řekne, že má vrátit aktuální písmo nebo nastavit písmo na nové.

int ioctl(int fd, int request, ...)
  1. fd je deskriptor souboru, který vrací open;
  2. request je kód požadavku. např. GETFONT získá aktuální písmo z tiskárny, SETFONT nastaví písmo na tiskárně;
  3. třetí argument je void * . V závislosti na druhém argumentu může nebo nemusí být přítomen třetí, např. pokud je druhý argument SETFONT , třetím argumentem může být název písma, například "Arial";

int request není jen makro. Uživatelská aplikace je vyžadována ke generování kódu požadavku a modulu ovladače zařízení k určení, se kterou konfigurací na zařízení je třeba hrát. Aplikace odešle kód požadavku pomocí ioctl a poté použije kód požadavku v modulu ovladače zařízení k určení, kterou akci provést.

Kód požadavku má 4 hlavní části

    1. A Magic number - 8 bits
    2. A sequence number - 8 bits
    3. Argument type (typically 14 bits), if any.
    4. Direction of data transfer (2 bits).  

Pokud je kód požadavku SETFONT pro nastavení písma na tiskárně bude směr přenosu dat z uživatelské aplikace do modulu ovladače zařízení (Uživatelská aplikace odešle název písma "Arial" do tiskárny). Pokud je kód požadavku GETFONT , směr je od tiskárny k uživatelské aplikaci.

Aby bylo možné vygenerovat kód požadavku, Linux poskytuje některá předdefinovaná makra podobná funkcím.

1._IO(MAGIC, SEQ_NO) oba jsou 8 bitů, 0 až 255, např. řekněme, že chceme tiskárnu pozastavit. To nevyžaduje přenos dat. Vygenerovali bychom tedy kód požadavku, jak je uvedeno níže

#define PRIN_MAGIC 'P'
#define NUM 0
#define PAUSE_PRIN __IO(PRIN_MAGIC, NUM) 

a nyní použijte ioctl jako

ret_val = ioctl(fd, PAUSE_PRIN);

Odpovídající systémové volání v modulu ovladače obdrží kód a pozastaví tiskárnu.

  1. __IOW(MAGIC, SEQ_NO, TYPE) MAGIC a SEQ_NO jsou stejné jako výše a TYPE udává typ dalšího argumentu, připomene třetí argument z ioctl je void * . W v __IOW označuje, že datový tok je z uživatelské aplikace do modulu ovladače. Předpokládejme například, že chceme nastavit písmo tiskárny na "Arial" .
#define PRIN_MAGIC 'S'
#define SEQ_NO 1
#define SETFONT __IOW(PRIN_MAGIC, SEQ_NO, unsigned long)

dále,

char *font = "Arial";
ret_val = ioctl(fd, SETFONT, font); 

Nyní font je ukazatel, což znamená, že jde o adresu nejlépe reprezentovanou jako unsigned long , tedy třetí část _IOW zmiňuje typ jako takový. Tato adresa písma je také předána odpovídajícímu systémovému volání implementovanému v modulu ovladače zařízení jako unsigned long a před použitím jej musíme přetypovat na správný typ. Prostor jádra může přistupovat k uživatelskému prostoru, a proto to funguje. další dvě makra podobná funkci jsou __IOR(MAGIC, SEQ_NO, TYPE) a __IORW(MAGIC, SEQ_NO, TYPE) kde tok dat bude probíhat z prostoru jádra do uživatelského prostoru a oběma způsoby.

Prosím, dejte mi vědět, jestli to pomůže!


ioctl , což znamená, že „řízení vstupu a výstupu“ je druh systémového volání specifického pro zařízení. V Linuxu existuje jen několik systémových volání (300-400), která nestačí k vyjádření všech jedinečných funkcí, které zařízení mohou mít. Ovladač tedy může definovat ioctl, který umožňuje aplikaci v uživatelském prostoru odesílat příkazy. Ioctl však nejsou příliš flexibilní a mají tendenci být trochu nepřehledné (desítky „magických čísel“, která prostě fungují... nebo ne) a mohou být také nejisté, protože do jádra předáváte vyrovnávací paměť – špatná manipulace se může zlomit věci snadno.

Alternativou je sysfs rozhraní, kde nastavíte soubor pod /sys/ a číst/zapisovat to, abyste získali informace z a do ovladače. Příklad, jak to nastavit:

static ssize_t mydrvr_version_show(struct device *dev,
        struct device_attribute *attr, char *buf)
{
    return sprintf(buf, "%s\n", DRIVER_RELEASE);
}

static DEVICE_ATTR(version, S_IRUGO, mydrvr_version_show, NULL);

A během nastavování ovladače:

device_create_file(dev, &dev_attr_version);

Pak byste měli soubor pro své zařízení ve formátu /sys/ , například /sys/block/myblk/version pro blokový ovladač.

Další metodou pro náročnější použití je netlink, což je metoda IPC (inter-process communication) pro komunikaci s vaším ovladačem přes rozhraní soketu BSD. Toho využívají například ovladače WiFi. Poté s ním komunikujete z uživatelského prostoru pomocí libnl nebo libnl3 knihovny.


Linux
  1. Linux – myšleno montáží zařízení v Linuxu?

  2. Linux:Jak najít ovladač zařízení používaný pro zařízení?

  3. Linux – Jak najít ovladač (modul) spojený se zařízením v Linuxu?

  1. Huawei Linux Driver na Ubuntu 13.04?

  2. Jak vytvořit virtuální blokové zařízení (smyčkové zařízení/systém souborů) v Linuxu

  3. Proč je v ovladačích zařízení Linux kromě init potřeba metoda sondy?

  1. Jaký je rozdíl mezi ovladačem platformy Linux a normálním ovladačem zařízení?

  2. Jak připojit zařízení v Linuxu?

  3. Konzistentní výčet zařízení Linux