Chapter 5. pinctrl

Hyunjin Lee·2025년 8월 13일

pinctrl은 SoC의 각 핀을 어떤 기능과 전기적 상태로 쓸지 결정하는 Devicetree의 설정으로, pinctrl이 zephyr에서 어떤 역할을 하는지, 어떻게 사용하는지, 왜 필요한지 등을 정의해보려 함.
(https://docs.zephyrproject.org/latest/hardware/pinctrl/index.html 참고)

1. pinctrl의 목적

  • HW독립성: 핀 기능과 전기적 특성을 Devicetree로 선언 -> HW에 관계없이 핀 설정 방식이 통일됨
  • 중앙 관리: 하드코딩 대신 DTS에서 핀 설정 가능
  • 상태 기반 전환: default / sleep / idle 등 상태별로 핀 설정이 가능해짐
  • power / ground pin 등 물리적으로 기능이 핀들은 pinctrl, IDE설정, 레지스터 변경 등으로 바꿀 수 없음.

2. pin 설정: Centralized vs Distributed 방식

  • 핀 설정에서 Centralized와 Distributed방식은 SoC에서 각 핀의 전기적 / 기능적 상태를 변경하는 대표적인 방법임.
  • 공통점: HW에서 어떤 방식으로 핀 설정을 하건, 특정 핀의 사용 가능한 기능 목록은 정해져있음.
  • Centralized: MCU가 전용 Pinmux 컨트롤러 하나로 모든 핀 기능을 설정.
    - ex: STM32, NXP -> pinmux_set(pin, function) 이런식으로 한 레지스터 블록에서 제어함.(pinmux HW를 사용)
    - 설정 코드가 단순해짐.
    ../../_images/hw-cent-control.svg
  • Distributed: 각 peripheral이 자기 핀 설정 레지스터를 가짐
    - ex: nordic nRF -> UART0, SPI0, PWM0 등등이 각자의 핀을 지정하는 레지스터가 따로 존재함.(각 peripheral레지스터에서 어떤 핀을 사용할지 정함)
    - 구현 시 각 peripheral별 설정을 모아야 하므로, 드라이버 코드가 복잡해짐.
    - 하드웨어 단순화 가능하며, 핀 간 독립성이 높다는 장점 있음.
    ../../_images/hw-dist-control.svg

3. pinctrl DTS구조

  • pinctrl-<index> / pinctrl-names:
    - 여러 상태(예: default, sleep, idle)을 DTS에서 관리 가능
  • 각 peripheral 노드 안에 pinctrl-<index> 속성 넣음.
  • 예:
&uart0 {
pinctrl-0 = <&uart0_default>;
pinctrl-names = "default";
}

&pinctrl {
uart0_default: uart0_default {
	group1 {
		psels = <NRF_PSEL(UART_TX, 0, 6)>,
				<NRF_PSEL(UART_RX, 0, 8)>;
		bias-pull-up;
	};
};
};

4. 상태 전환

  • 전력 절약을 위하 런타임에 핀 설정 변경 가능
  • 예: SPI사용 -> 슬립모드 진입시 모든 관련 핀을 High-Z로 변경

5. 구현 세부사항

  • 드라이버는 pinctrl_apply_state()로 DTS 정의를 적용

  • 각 보드별 pinctrl노드에 핀 그룹 정의.

  • 하드웨어가 distributed이면, 드라이버가 peripheral마다 핀 정보를 분리해 적용해야 함.

  • pinctrl: 핀 기능을 정의하는 Devicetree 노드 블럭(보통 &pinctrl로 존재)

  • pinctrl-0: default 상태에서 사용할 핀 설정 그룹

  • pinctrl-1: sleep 상태에서 사용할 핀 설정 그룹

  • pinctrl-names: 각 상태에 대한 이름 정의("default","sleep"등)

  • psels: Nordic 전용 매크로. 핀 기능을 정의(NRF_PSEL(UART_TX, 0, 14)등)

nRF pinctrl shared properties

  • bias-disable: pull-up/down 비활성화.(default임. 명시 필요 없음)
  • bias-pull-up: pull-up 저항 활성화
  • bias-pull-down: pull-down 저항 활성화
  • low-power-enable: input buffer disconnected 모드로 변경해서 pin을 low power모드로 변경함.(ChatGPT에선, 입력감지 불가, 출력은 이전값 유지한상태로 변경 불가라는데, 실험이 필요할듯)

6. nRF52840에 pinctrl 수정하기(.overlay사용)

/ {
    chosen {
        zephyr,console = &uart1; // console을 uart 1로 변경
    };
};

&uart1 {
    status = "okay";
};

&pinctrl {
   uart1_default_alt: uart1_default_alt {
      group1 {
         psels = <NRF_PSEL(UART_TX, 0, 14)>,
                 <NRF_PSEL(UART_RX, 0, 16)>;
      };
   };
   uart1_sleep_alt: uart1_sleep_alt {
      group1 {
         psels = <NRF_PSEL(UART_TX, 0, 14)>,
                 <NRF_PSEL(UART_RX, 0, 16)>;
         low-power-enable;
      };
   };
};

&uart1 {
  pinctrl-0 = <&uart1_default_alt>;
  pinctrl-1 = <&uart1_sleep_alt>;
  pinctrl-names = "default", "sleep";
};

DTS 주요 내용

  • uart1_default_alt, uart1_sleep_alt 2가지 pinctrl을 정의하고, uart1의 모드별 핀 설정으로 사용
  • uart1_sleep_alt를 보면, sleep모드인 경우 저전력 모드로 변경하도록 함.

동작은 Chapter 3과 마찬가지로, zephyr,consolep0.14, p0.16으로 변경됨.

profile
real-time system과 physical AI에 관심이 많습니다.

0개의 댓글