문맥
ㅏ플랫폼 드라이버온칩 구성 요소 및 기타 검색할 수 없는 장치용으로 작성된 장치 드라이버입니다. 이런 경우에 제가 집중하고 있는 것은SNVS 전원 켜기/끄기 드라이버i.MX6 기반 플랫폼에 적용 가능합니다.
질문
나는 플랫폼의 켜기/끄기 버튼이 전환될 때 사용자 공간 프로그램이 정보를 얻을 수 있기를 원합니다. 나는 두 가지 가능한 접근 방식을 식별하고 적어도 하나를 제거했습니다.
- 등록하다캐릭터 장치드라이버와 동일한 인터럽트를 공유하는 커널 모듈입니다. 사용자 모드 프로그램이 매우 쿼리
ioctl
하고read/write
작동하도록 허용합니다.불가능: IRQ가 공유되지 않음 - 장치를 관리할 때
uevents
커널에서 게시한 정보를 듣고 다음을 사용하십시오.udev
규칙운전자를 매칭하고 조치를 취하세요. 안타깝게도uevent
버튼을 눌러도 정보가 게시되지 않습니다. 이는 단순히uevent
장치를 로드하거나 언로드할 때 정보를 출력하는 것이 목적이기 때문입니다 . 플랫폼 장치로서 장치는 부팅 시 즉시 로드되며 언로드되지 않습니다. 내 커널 구성자에 따르면 전혀 제거할 수 없습니다(커널의 일부여야 함).
솔루션 1
인터럽트를 통해 버튼을 누를 때마다 이벤트가 발생하기를 원했기 때문에 snvs_pwrkey.c
드라이버를 직접 생성하도록 수정했습니다 uevent
.이 게시물출발점으로. 드라이버를 다음과 같이 변경했습니다.
...
static irqreturn_t imx_snvs_pwrkey_interrupt (int irq, void *dev_id)
{
...
struct platform_device *pdev = dev_id;
int err = 0;
...
/* Sysfs notify: I chose "change" as the event type */
err = kobject_uevent(&(pdev->dev.kobj), KOBJ_CHANGE);
pr_err("%s :: kobject_uevent = %d\n", __FUNCTION__, err);
return IRQ_HANDLED
}
...
그런 다음 다음 udev 규칙을 사용하여 이를 캡처합니다.
# /etc/udev/rules.d/90-local.rules
KERNEL="20cc000.snvs:snvs-powerkey", SUBSYSTEM=="platform", DRIVER=="snvs_pwrkey", ACTION=="change", RUN+="/sbin/poweroff"
비록 이것이실제로 작동한다, STDOUT이 실행될 때 예외 및 스택 추적이 발생합니다(그러나 첫 번째 호출에서만). 이는 성능이나 안정성에 눈에 띄는 영향을 미치지 않더라도 분명히 바람직하지 않습니다. 그러나 더 중요한 것은 uevent
사용자 공간에 인터럽트 알림을 보내기 위해 sysfs에서 장치를 관리하는 데 사용되는 시스템을 하이재킹하고 있기 때문에 이것이 남용이라고 생각한다는 것입니다 .
그렇다면 내가 달성하려는 목표를 달성할 수 있는 더 좋은 방법이 있는지 궁금합니다. 내 모듈과 인터럽트를 공유할 수 없다는 점을 고려하면 드라이버 인터럽트가 트리거될 때 사용자 공간 애플리케이션에 알릴 수 있습니다.
첨부된:/proc/interrupts
버튼(IRQ 45)을 전환하면 실제로 인터럽트 카운터가 증가하는 것을 볼 수 있습니다. 그러나 나는 사용자 프로그램에서 그러한 이벤트를 기다리거나 폴링하는 데 사용할 수 있는 인터페이스를 모릅니다. 어쩌면 이 질문을 읽는 다른 사람이 이것을 솔루션으로 활용하는 방법을 알고 있을 수도 있습니다.