편집자 주: 임베디드 리눅스가 사물인터넷의 중추가 되고 있으며, 디바이스 드라이버는 애플리케이션과 하드웨어 사이의 다리입니다. "Linux Device Drivers Development"의 저자 John Madieu가 이 드라이버 구축에 대한 상세하고 코드 풍부한 가이드를 제공합니다.
이 발췌문(책의 14장)은 커널과 커스텀 하드웨어를 인터페이스해야 하는 개발자에게 중요한 영역인 핀 컨트롤과 GPIO를 다룹니다. 첫 번째 편에서는 핀 컨트롤 서브시스템을 소개합니다.
John Madieu의 Linux Device Drivers Development에서 발췌 및 각색.
14장. 핀 컨트롤 및 GPIO 서브시스템 작성자: John Madieu
임베디드 리눅스에서 드라이버는 거의 항상 GPIO와 상호작용하거나 핀 멀티플렉싱을 구성합니다. "핀"은 구성요소의 물리적 출력 라인이며, 많은 SoC가 동일한 핀을 여러 기능에 재사용합니다. 예를 들어 i.MX6QDL 핀 MX6QDL_PAD_SD3_DAT1은 SD 데이터 라인, UART RTS/CTS 라인, FlexCAN Rx 라인, 또는 범용 GPIO로 사용될 수 있습니다.
핀의 기능을 선택하는 과정을 핀 멀티플렉싱(pin muxing)이라 하며, 이를 조정하는 커널 구성요소가 핀 컨트롤러(pin controller)입니다. 이 장의 두 번째 부분에서는 핀의 일반적인 기능인 범용 입출력(GPIO) 서브시스템을 탐구합니다.
이 장에서 다룰 내용:
핀 컨트롤 서브시스템을 살펴보고 디바이스 트리에서 핀 컨트롤 노드를 선언하는 방법 학습
레거시 정수 기반 GPIO API와 최신 디스크립터 기반 인터페이스 비교
인터럽트로도 사용되는 GPIO 처리
GPIO 관리를 위한 sysfs 인터페이스 탐구
핀 컨트롤 서브시스템
pinctrl 서브시스템은 핀 멀티플렉싱과 구성을 관리합니다. 특정 핀 배열이 필요한 기기는 디바이스 트리에서 해당 배열을 설명해야 합니다. 핀 컨트롤러 드라이버는 이 설명을 파싱하고 SoC의 I/O 컨트롤러를 그에 맞게 프로그래밍합니다.
서브시스템이 제공하는 기능:
핀 멀티플렉싱 – 단일 핀을 여러 역할(UART TX, GPIO, HSI 등)로 그룹 단위 또는 핀 단위로 재사용
핀 구성 – 풀업/풀다운, 드라이브 강도, 디바운스 등 전기적 특성 설정
이 책은 핀 컨트롤러 API 사용에 초점을 맞추며, 핀 컨트롤러 드라이버 작성 자체는 다루지 않습니다.
Pinctrl과 디바이스 트리
디바이스 트리에서 핀 컨트롤러 노드는 사용 가능한 모든 핀 그룹과 기능을 설명합니다. 각 그룹에는 정수 ID가 할당되며, 선택적으로 pinctrl-name이 붙어 사람이 읽을 수 있는 이름을 ID에 매핑합니다.
기기의 바인딩은 필요한 핀 상태를 지정합니다. 두 속성이 기기를 핀 상태에 연결합니다:
pinctrl- – 핀 구성 노드를 가리키는 핸들 리스트. 여러 항목으로 기기가 여러 핀 컨트롤러에 의해 구성되거나 단일 컨트롤러에 여러 노드가 결합되도록 허용.
pinctrl-name – 각 상태 ID에 이름을 할당하는 병렬 리스트. 상태 0은 보통 default로 명명되며 include/linux/pinctrl/pinctrl-state.h에 정의된 표준 리스트를 따릅니다.
첫 번째 토큰(MX6QDL_PAD_DISP0_DAT15__GPIO5_IO09)은 핀 기능을 식별하고, 두 번째 토큰(0x80000000)은 구성 비트(풀업/다운, 드라이브 강도 등)를 인코딩합니다. 이 매크로는 arch/arm/boot/dts/imx6q-pinfunc.h 같은 아키텍처별 헤더 파일에 정의됩니다.
드라이버 코드에서 핀 상태를 프로그래밍하려면 초기화 시(일반적으로 probe()에서) 다음 단계를 따르세요:
struct pinctrl *pinctrl; pinctrl = devm_pinctrl_get_select_default(&pdev->dev); if (IS_ERR(pinctrl)) dev_warn(&pdev->dev, "pins are not configured from the driver");
도우미 pinctrl_get_select_default()는 자동으로 default 상태를 검색하고 적용합니다. 기기가 init 상태를 제공하면 코어는 probe() 전에 해당 상태를 적용한 후 드라이버가 변경하지 않는 한 default로 되돌립니다.
완료되면 pinctrl_put(pinctrl) 또는 리소스 관리 변형 devm_pinctrl_put(pinctrl)으로 컨트롤러를 해제하세요.
John Madieu는 파리 기반 임베디드 리눅스 및 커널 엔지니어입니다. 자동화, 운송, 의료, 에너지, 국방 분야 클라이언트를 위해 드라이버와 BSP를 개발합니다. John은 컴퓨터-온-모듈 설계의 선구자인 EXPEMB에서 근무하며, 지식 공유가 혁신을 가속화한다고 믿는 활발한 오픈소스 옹호자입니다.