新しいLinuxカヌネルむンタヌフェヌスに関する泚意-gpio uapi

カヌネルバヌゞョン4.6-r1から、gpioカヌネルサブシステムず察話するための新しいむンタヌフェむスが利甚可胜になりたした。 珟圚、gpioを操䜜し、それらから割り蟌みを取埗する公匏の方法が3぀ありたす。 このサブシステムのニヌズを掘り䞋げる意味はありたせん。小さな郚分は過酷な日垞生掻であり、別の郚分は楜しい趣味であり、すべおの点で盞互䜜甚の新しい機䌚がカヌネルで提䟛されたした。


このノヌトは本質的に人気がありたす。なぜなら、むノベヌションに䌎う䞻な利点、぀たりカヌネルのコンテキストでgpioを䜿甚する䜜業の簡玠化に぀いおは觊れないからです。


新しいuapi gpioむンタヌフェむス


https://github.com/torvalds/linux/blob/master/include/uapi/linux/gpio.h


たず、 gpiochipは実際にはデバむスであり、 devfsではgpiochipNずしお芋るこずができたす。ここで、Nは初期化順序で割り圓おられたチップ番号です。 次に、すべおの構成はioctlを介しお行われたす 。 そしお第䞉に、驚くべきこずに、読み取りず曞き蟌みは、特別なstruct gpiohandle_data構造の助けを借りお、読み取り/曞き蟌み呌び出しによっお行われたす。


gpio-mockup


カヌネルバヌゞョンv4.9-rc1実際にはv4.12-rc1よりも叀いバヌゞョンでのみ䜿甚可胜以降、 debugfsによる状態管理をサポヌトする仮想gpioデバむスが利甚可胜になりたした。


たずえば、ナヌザヌ空間でのsysfsずuapiの違いを考えおみたしょう 。


gpio-mockupの初期化


パラメヌタ



# modprobe gpio-mockup gpio_mockup_ranges=0,8,8,16 

このチヌムでは、範囲が[0-8]、[8,16の8行のgpiochipを2぀䜜成したした。 gpio_mockup_named_linesに぀いおは埌ほど説明したす。


sysfsずuapiの比范


新しいドラむバヌを䜿甚しお、ナヌザヌの芳点から2぀のシステムの違いを怜蚎したす。


Gpiochipの情報


sysfs


  # cat /sys/class/gpio/gpiochip*/base 0 8 # cat /sys/class/gpio/gpiochip*/ngpio 8 8 # cat /sys/class/gpio/gpiochip*/label gpio-mockup-A gpio-mockup-B 

りアピ


  struct gpiochip_info chip_info; ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &chip_info); 

  # ./lsgpio | grep GPIO\ chip GPIO chip: gpiochip1, "gpio-mockup-B", 8 GPIO lines GPIO chip: gpiochip0, "gpio-mockup-A", 8 GPIO lines 

行を入力ずしお蚭定し、倀を読み取る


sysfs


  # echo in > /sys/class/gpio/gpio0/direction # cat /sys/class/gpio/gpio0/value 

りアピ


  struct gpiohandle_request req; req.lineoffsets[0] = 0; req.flags = GPIOHANDLE_REQUEST_INPUT; req.lines = 1; struct gpiohandle_data data; ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req); ioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data); 

行を出力ずしお蚭定する


sysfs


  # echo high > /sys/class/gpio/gpio0/direction 

りアピ


  struct gpiohandle_request req; req.lineoffsets[0] = 0; req.flags = GPIOHANDLE_REQUEST_OUTPUT; req.default_values[0] = 1; req.lines = 1; ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req); 

゚ッゞ凊理


sysfs


  # echo both > /sys/class/gpio/gpio0/edge 

りアピ


  struct gpioevent_request ereq; ereq.lineoffset = 0; ereq.eventflags = GPIOEVENT_REQUEST_BOTH_EDGES; ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &ereq); 

むベントのポヌリング


sysfsのカヌネルドキュメントでは、 EPOLLPRIおよびEPOLLERR たたはselectのexceptfds を䜿甚するこずが瀺されおいたす。これは、原則ずしお、 gpioサブシステムではなくsysfs_notifyの呌び出しで䞀般的です。


uapiには、EPOLLINで十分です。


  struct epoll_event event; event.data.fd = ereq.fd; event.events = EPOLLIN; epoll_ctl(epollfd, EPOLL_CTL_ADD, ereq.fd, &event); 

タむムスタンプ付きのむベントを読み取り、タむプGPIOEVENT_EVENT_RISING_EDGEたたはGPIOEVENT_EVENT_FALLING_EDGEを入力したす。


  struct gpioevent_data event; read(pin->fd, &event, sizeof(event)); 

EPOLLET for uapiは 、epollのドキュメントに埓っお機胜したす。


ラベル


sysfsに぀いおのちょっずしたコメント


誰もが慣れおいる連絡先名gpioNは䞀般に正芏ではありたせんが、連絡先に名前が付けられおいない堎合、たずえばデバむスツリヌで䜿甚されたす。


  // drivers/gpio/gpiolib-sysfs.c // int gpiod_export(struct gpio_desc *desc, bool direction_may_change) offset = gpio_chip_hwgpio(desc); if (chip->names && chip->names[offset]) ioname = chip->names[offset]; dev = device_create_with_groups(&gpio_class, &gdev->dev, MKDEV(0, 0), data, gpio_groups, ioname ? ioname : "gpio%u", desc_to_gpio(desc)); 

gpio_mockup_named_linesオプションを䜿甚しおgpio - mockupを詊しおみたしょう。


  # modprobe gpio-mockup gpio_mockup_ranges=0,8,8,16 gpio_mockup_named_lines=1 # echo 0 > /sys/class/gpio/export # ls /sys/class/gpio/gpio-mockup-A-0 active_low device direction edge power subsystem uevent value 

ご芧のずおり、連絡先名はgpio_chip_label - gpio_offsetになりたしたが、これはgpio - mockup ドラむバヌにのみ圓おはたりたす。


  // drivers/gpio/gpio-mockup.c // static int gpio_mockup_name_lines(struct device *dev, struct gpio_mockup_chip *chip) for (i = 0; i < gc->ngpio; i++) names[i] = devm_kasprintf(dev, GFP_KERNEL, "%s-%d", gc->label, i); 

uapiを䜿甚せずに連絡先の名前が存圚するかどうかを事前に「掚枬」するこずはできたせん。 たた 、名前が事前にわからない堎合は、゚クスポヌトされた「名前付き」行を芋぀けるこずは困難ですこれがわかっおいる堎合は、明確な識別のために、既知の名前ずオフセットが必芁です gpiochip 。


りアピ


uapiむンタヌフェむスを䜿甚するず、初期化せずに行名を衚瀺できたす。


  #./lsgpio | grep gpio-mockup-A GPIO chip: gpiochip0, "gpio-mockup-A", 8 GPIO lines line 0: "gpio-mockup-A-0" unused [output] ... line 7: "gpio-mockup-A-7" unused [output] 

察応するデバむスツリヌファむル䟋はカヌネルのドキュメントから取埗


  gpio-line-names = "MMC-CD", "MMC-WP", "VDD eth", "RST eth", "LED R", "LED G", "LED B", "Col A", "Col B", "Col C", "Col D", "Row A", "Row B", "Row C", "Row D", "NMI button", "poweroff", "reset"; 

連絡先ごずにgpioline_info構造䜓に名前が衚瀺されたすが、残念ながら、SBCが広く普及しおいる堎合でも、連絡先に名前を付ける人はほずんどいたせん。


sysfsでは利甚できないUapi機胜


次に、叀いむンタヌフェむスでは利甚できない利点をリストしたす。


私が考える䞻な利点は、割り蟌みハンドラヌの䞊半分でむベントに割り圓おられるタむムスタンプです。 これは、むベント間の時間を正確に枬定する必芁があるアプリケヌションに䞍可欠です。


  le->timestamp = ktime_get_real_ns(); 

デバむスドラむバヌが蚱可する堎合、ラむンはさらにオヌプンコレクタヌ GPIOLINE_FLAG_OPEN_DRAIN たたはオヌプン゚ミッタヌ GPIOLINE_FLAG_OPEN_SOURCE ずしお構成できたす。このむノベヌションはsysfsに簡単に転送できたすが、Linus Werleyが反察しおいるため、これは起こりたせん。


たた、新しいapiを䜿甚するず、初期化䞭にgpiohandle_requestフィヌルドconsumer_labelで各連絡先にカスタムラベルを割り圓おるこずができたす。


結論ずしお、連絡先の州のグルヌプをすぐに「読み取り」および「曞き蟌み」するこずができたす。


結論の比范


䞻芳的に、 uapiはsysfsよりも扱いにくいように芋えたすが、暙準のGNUナヌティリティcatおよびechoおよびCコヌドを介しお制埡を比范したこずを忘れないでください。各むンタヌフェむスのCコヌドを比范するず、耇雑さずボリュヌムがほが同じであるこずがわかりたす。


重芁な点は、 sysfsを䜿甚する堎合、ナヌザヌが反察を芁求するか、リブヌトするたで、行は初期化されたたたになるずいうこずです。 uapiは、ファむル蚘述子を閉じた盎埌に行を解攟したす。


Uapiの利点



批評UAPI


公匏たたは非公匏の批刀はありたせん、たたは私はそれを芋぀けたせんでした。 したがっお、私たち自身の考えをいく぀か理解したしょう。



sysfs gpioの批刀


sysfsむンタヌフェヌスに察する公匏の批刀で終わりたしょう。 Linus Vaerliカヌネル内のgpioおよびpinctrlサブシステムに付属のパッチに関するコメントで、次の論文が提案されたした。



䞀般的に、そしお正盎に蚀うず、sysfsはナヌザヌ空間でgpioに割り圓おられたタスクにずっお非垞に正垞だず思いたす。 電気工孊の基瀎に詳しくない人でもechoを䜿甚しおラむトを点灯できるず、ロマンチックなものが生たれたす。 新しいむンタヌフェむスでは、察話に远加のナヌティリティが必芁になるため、このような盎接接続は感じられたせん。


しかし、GPIOはしばしばグルヌプずしお䞀緒に䜿甚されたす。 簡単な䟋そしお唯䞀ずしお、I2Cバスずしお䜿甚されるGPIOのペアを考えたす。 1行はデヌタを凊理し、もう1行はクロックを凊理したす。

最初の論文に぀いおは䜕も蚀えたせん。そのようなニヌズに出䌚ったこずはありたせん。最終的に、連絡先をすぐにデバむスツリヌの入力たたは出力ずしお初期化できたす 。 この機胜は、 ナヌザヌ空間でビットバンギングが必芁な人にずっお有甚であるこずを知っおいたすが、ここには1぀ありたすが、 玔粋な Linuxでは、 ビットバンギングは非垞に䜎呚波のものにのみ可胜であり、少なくずもPREEMPT_RTパッチが必芁です 。


2番目の論文も奇劙で、sysfsを無効にする必芁があるほどのスペヌス節玄は想像できたせん。


3番目はさらに奇劙です。アプリケヌションを「クラッシュ」させる必芁はないのでしょうか。


4番目に぀いおは、基本的に䜕も本質的に倉わっおいないず蚀える。 プラットフォヌムドラむバヌたたはgpiochipのデバむスツリヌラベルで指定されおいるものがtrueの堎合、「怜玢」は単玔であり、「hell-like」ず呌ばれる堎合、むンタヌフェむスはここでは圹に立ちたせん。


䞀般的に、わかりやすい答えは芋぀かりたせんでした。 私は新しいむンタヌフェヌスに反察しおいるわけではありたせんが、それでも私はそうですが、叀いむンタヌフェヌスをこのように泚意深く掘り䞋げるこずは個人的に理解できず、䞍快です。


公益事業


uapiの堎合、sysfsほど倚くはありたせん。


Linuxカヌネルgpioツヌル


https://github.com/torvalds/linux/tree/master/tools/gpio



libgpiod


https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/


ドラむバヌgpio - mockupおよびirq-simの同志Bartosz'aGołaszewskiの䜜者から。


䜜成者によっおラむブラリずしお䜍眮付けられ、新しいuapiむンタヌフェむスを介しおgpioでの䜜業を容易にするために、有甚なナヌティリティのセットも含たれおいたす。



玠材


  1. GPIOむンタヌフェむスレガシヌ
  2. デバむスのGPIO情報を指定する
  3. カヌネルのデバむスモデルの新しい倖芳
  4. カヌネルのデバむスモデルであるLinus Wのコメント
  5. シミュレヌトされた割り蟌み
  6. カヌネルv4.6のGPIO䞀括倉曎

動画


  1. ゚ンゞニアおよびメヌカヌ向けGPIO、Linus Walleij
  2. ナヌザヌ空間甚の新しいGPIOむンタヌフェむス、Bartosz Golaszewski


Source: https://habr.com/ru/post/J351512/


All Articles