목적 : Zephyr를 통한 LED 제어하기
STM32H573I-DK 보드에는 다음과 같이 4개의 LED (LD1, LD2, LD3, LD4)가 존재한다.
사용에 필요한 LED IO 들이 Device Tree에 설정되어 있는지 확인이 필요하다.
아래 파일의 경우 ST에서 작성해둔 파일로 보드 개발 시, 본 내용을 참조 변경하면 될 것으로 판단 된다.
(본인도 Device Tree 경험이 없지만.. Zephyr를 활용 하려면 Device Tree에 대한 이해가 요구된다..)
# zephyrproject/zephyr/boards/arm/stm32h573i_dk/stm32h573i_dk.dts
해당 파일을 참조해보면, 아래와 같이 정의 되어 있다.
다음과 같은 설정이 있으면, 이제부터 IO 제어를 할 수 있는 구성이 완료 된다.
leds {
compatible = "gpio-leds";
green_led_0: led_1 {
gpios = <&gpioi 9 GPIO_ACTIVE_LOW>;
label = "User LD1";
};
orange_led_0: led_2 {
gpios = <&gpioi 8 GPIO_ACTIVE_LOW>;
label = "User LD2";
};
red_led_0: led_3 {
gpios = <&gpiof 1 GPIO_ACTIVE_LOW>;
label = "User LD3";
};
blue_led_0: led_4 {
gpios = <&gpiof 4 GPIO_ACTIVE_LOW>;
label = "User LD4";
};
};
추가적으로 Device Tree 파일을 보면 aliases 라는 기능을 통해서도 사용이 가능하기 때문에 함께 예제를 통해 알아보고자 한다.
aliases {
led0 = &blue_led_0;
sw0 = &user_button;
watchdog0 = &iwdg;
spi-flash0 = &mx25lm51245;
die-temp0 = &die_temp;
volt-sensor0 = &vref;
volt-sensor1 = &vbat;
};
아래 설명에 대한 상세 코드는 아래 링크 참조
https://github.com/HY-PARK/ZephyrStudy
IO를 사용하기 위해서는 prj.conf 파일 내, 아래와 같은 설정이 요구된다.
CONFIG_GPIO=y
사실 아래 명시된 파일에, 이미 CONFIG_GPIO에 대한 설정이 켜져 있어서, prj.con에 설정이 있으나 없으나 동일하다.
(stm32h573i_dk_defconfig에 CONFIG_GPIO 라인을 주석 처리 후 빌드 수행해길 추천한다.)
# zephyrproject/zephyr/boards/arm/stm32h573i_dk/stm32h573i_dk_defconfig
Device Binding을 활용하려면, 아래와 같이 사용을 해야한다.
서두에 언급한 것처럼 Device Tree에서 정의된 label 을 활용하거나, label을 aliase한 정보를 사용한다.
- label 활용 시, DT_NODELABEL
- label aliase 활용 시, DT_ALIAS
GPIO_DT_SPEC_GET을 통해, Device Tree에 정의된 IO들을 제어할 수 있는 객체를 획득하게 된다.
#define LD1_NODE DT_NODELABEL(green_led_0)
#define LD2_NODE DT_NODELABEL(orange_led_0)
#define LD3_NODE DT_NODELABEL(red_led_0)
#define LD4_NODE DT_ALIAS(led0)
static const struct gpio_dt_spec ld1 = GPIO_DT_SPEC_GET(LD1_NODE, gpios);
static const struct gpio_dt_spec ld2 = GPIO_DT_SPEC_GET(LD2_NODE, gpios);
static const struct gpio_dt_spec ld3 = GPIO_DT_SPEC_GET(LD3_NODE, gpios);
static const struct gpio_dt_spec ld4 = GPIO_DT_SPEC_GET(LD4_NODE, gpios);
gpio_pin_configure_dt를 통해 OUPUT 설정을 수행한다.
gpio_pin_toggle_dt를 통해 IO를 토글한다.
int main(void)
{
gpio_pin_configure_dt(&ld1, GPIO_OUTPUT_ACTIVE);
gpio_pin_configure_dt(&ld2, GPIO_OUTPUT_ACTIVE);
gpio_pin_configure_dt(&ld3, GPIO_OUTPUT_ACTIVE);
gpio_pin_configure_dt(&ld4, GPIO_OUTPUT_ACTIVE);
while (1) {
gpio_pin_toggle_dt(&ld1);
gpio_pin_toggle_dt(&ld2);
gpio_pin_toggle_dt(&ld3);
gpio_pin_toggle_dt(&ld4);
k_msleep(SLEEP_TIME_MS);
}
return 0;
}