2020년 6월 17일 수요일

Linux Device Driver for Embedded Processors 에피소드 3 - STM32MP157C Discovery Kit 소개(4)

지난 시간에 이어 STM32MP157C Discovery Kit 분석, 네번째 시간이다. 😙

이번 시간에는 HTU21D 온/습도 센서를 DK2 보드에 연결(i2c interface)하고, 관련 device tree와 device driver를 작성하는 방법을 소개할 것이다.


Raspberry Pi나 Arduino를 가지고 응용 program(python, C ...) 수준에서 HTU21D 온/습도 센서를 제어하는 작업은 크게 어렵지 않다. 하지만, 이를 linux device driver(w/ device tree)로 작업하는 것은 생각보다 험난한(?) 과정을 겨쳐야 한다. 하지만, 한번 해 보면 다른 유형의 device driver 개발에도 많은 도움이 될 것이다. 자, 그럼 시작할 준비가 되었는가 ?

5. Device Tree 분석 및 Device Driver 시험하기
이번 장에서 소개하고자 하는 내용은 대략 다음과 같다. 
   1) DK2 board의 전체 device tree 구조 분석(특히 i2c를 중심으로..)
   2) HTU21D 온습도 센서와 DK2 보드 연결 방법 소개
   3) device tree 수정 사항 소개
   4) 관련 device driver 분석
   5) 동작 시험

a) DK2 보드의 device tree 구조 분석
사실, 특정 SoC & board의 device tree를 한번에 이해하기는 쉬운 일이 아니다. 특히나 h/w를 전문적으로 다루지 않는 경우라면 더더욱 그렇다. 하지만 device driver 개발 관점에서만 생각해 본다면 모든 것을 속속들이 다 이해해야 하는 것도 아니다. 이번 posting에서는 i2c device를 하나 장착하고 이를 올바르게 동작시키는 게 목적인 만큼, 그 취지에 맞에 제한된 범위 내에서 device tree 분석을 시작해 보도록 하겠다. 

[Tip] Device Tree의 기초적인 내용을 파악할 필요가 있는 분들은  본 저자가 오래전에 작성한 아래 blog post를 한번 훑어 보시기 바란다.



먼저 DK2 보드의 device tree 계층 구조를 대략적으로 살펴 보자. 파일 위치는 우리가 익히 알고 있는 바와 같이 arch/arm/boot 이다. 

stm32mp151.dtsi
^
|
stm32mp153.dtsi
^
|
stm32mp157.dtsi

stm32mp15xc.dtsi
stm32mp15-pinctrl.dtsi
stm32mp15xxac-pinctrl.dtsi
stm32mp15xx-dkx.dtsi
^
|
stm32mp157c-dk2.dts

[그림 5.1] output/build/linux-5.7.1/arch/arm/boot/stm32mp157c-dk2.dts

아래 그림은 STM32MP157 MPU의 memory map이다. Memory map은 memory mapped system(요즘 대부분의 embedded system의 유형, i/o device도 memory 주소로 인식)에서 다양한 장치의 register 주소 등을 파악하는데 도움을 준다.

[그림 5.2] Memory map

이중, 우측 하단에 그려져 있는 i2c controller node의 종류 및 각각의 주소를 파악해 볼 필요가 있는데, 이를 device tree 파일 내용과 매뉴얼 내용(그림 5.3)을 토대로 정리해 보면 다음과 같다.

<DK2 보드에서 사용하는 i2c controller>
i2c1: i2c@40012000
i2c2: i2c@40013000
i2c3: i2c@40014000
i2c4: i2c@5c002000
i2c5: i2c@40015000
i2c6: i2c@5c009000


[그림 5.3] i2c register 주소

DK2 보드의 block도를 살펴 보면 i2c device로는 어떤 것들이 있는지 한눈에 알 수가 같다. Device Tree 내용 분석에 앞서 아래 그림의 의미를 숙지할 필요가 있다.

[그림 5.4] DK2 보드의 block diagram

i2c controller node & device node와 관련해서는 여러 device tree file에 걸쳐 기술되어 있으므로, 각각의 내용을 하나씩 따져 보도록 하자.

먼저 그림 5.5(stm32mp151.dtsi)에서 i2c controller node의 status 값을 확인해 본 결과, 모두 disabled되어 있는데, status="okay"로 정의하기 시작한 곳은 아래 그림 5.6-5.7(stm32mp15xx-dkx.dtsi)에서 부터임을 알 수 있다. stm32mp15xx-dkx.dtsi 파일은 i2c1과 i2c4 controller node와 그에 연결되어 있는 device node 만을 기술하고 있다.

[그림 5.5] stm32mp151.dtsi 파일 내용 중 i2c controller node 부분(모두 status="disabled"로 설정되어 있음)


[그림 5.6] i2c1 controller node - stm32mp15xx-dkx.dtsi 파일에서 발췌

<i2c1 controller & device node 내용 추출>
  => i2c1 controller와 여기에 붙어 있는 i2c device를 요약해 보면 다음과 같다.
  => i2c1 controller에는 hdmi transceiver와 audio codec이 연결되어 있다.
 &i2c1 {
         status = "okay";
 
         hdmi-transmitter@39 {                   /* sii90022 HDMI transceiver */
                 compatible = "sil,sii9022";
                 reg = <0x39>;
          }; 

          cs42l51: cs42l51@4a {                       /* cs42151 audio codec */
                  compatible = "cirrus,cs42l51";
                  reg = <0x4a>;
          };
};

[그림 5.7] i2c4 controller node - stm32mp15xx-dkx.dtsi 파일에서 발췌

<i2c4 controller & device node 내용 추출>
  => i2c4 controller node에는 PMIC device가 연결되어 있다.
 &i2c4 {
         status = "okay";

         pmic: stpmic@33 {
                compatible = "st,stpmic1";        /* stpmic1 PMIC  */
                reg = <0x33>;
         };
};
[Tip] 그림 5.4의 block도와는 다르게 USB type-C용 device node(???)와 관련된 내용은 어디에도 보이질 않는다. 이는 아무래도 STM32MP157A-DK1 Discovery Board와 관련된 내용인 듯 싶다(stm32mp157a-dk1.dts 파일에는 관련 내용이 보임).

마지막으로 stm32mp157c-dk2.dts 파일에는 i2c1 controller에 touch device(focaltech ft6236)를 추가한 내용(&i2c1의 & 표시는 override를 의미함)이 보인다.

[그림 5.8] i2c1 controller node - stm32mp157c-dk2.dts 파일에서 추출

이상의 내용을 정리해 보면, 다음과 같다.
   i2c1 controller <-------i2c bus--------> hdmi(sii9022, 0x39) | audio codec(cs42l51, 0x4a) | touch panel(f6236, 0x38)
   i2c4 controller <-------i2c bus--------> pmic(stpmic1, 0x33)

[Tip] i2c device는 reg=<0x38>과 같이 7bit i2c slave address(장치 구분용 주솟값)가 중요한 역할을 한다.

i2c2, i2c3, i2c5 controller에는 아무런 device도 연결되어 있지 않음을 알 수가 있다. 따라서 얘네 들 중 하나에 HTU21D 온/습도 센서를 연결하면 좋을 것 같다는 생각이 든다. 물론 이 중에서 확장 pin으로 정의된 녀석이어야 하지만 말이다.

b) HTU21D 온/습도(temperature/humidity) 센서 연결
이번 절에서는 Measurement Specialties사가 제조하여 판매하는 HTU21D 온/습도 센서를 살펴 보고, 이를 DK2 보드와 어떻게 연결하는게 좋을지 살펴 보고자 한다.
[그림 5.9] HTU21D 온/습도 센서 외관

아래 그림은 HTU21D의 회로도인데, HTU21D 센서 모듈은 Vdd(3.3V power), GND(ground), DATA(SDA), SCK(SCL) 4개의 pin이 외부로 표출되어 있다. 따라서 이를 DK2 board의 해당 pin에 1대1일로 연결해 주면 된다. 참고로, 회로도 아래 부분의 7 bit I2C address 0x40은 device tree 구현시 꼭 필요한 내용이다.
[그림 5.10] HTU21D 온/습도 센서 회로도

[Tip] 아주 당연한 얘기지만, HTU21D 센서 모듈은 VDD로 3.3V의 전원이 인가된다. 따라서 DK2의 5V VDD pin에 연결하지 않도록 주의하자.

그럼, 이번에는 DK2 보드 확장 pin 중 i2c pin으로 사용 가능한 녀석을 찾아 보도록 하자.

DK2 확장 pin에는 크게 다음과 같이 두 종류가 있다.
    - Raspberry Pi 호환 connector(CN2) ....................................................... board top에 위치
    - Arduino UNO 호환 connector(CN13, CN14, C17, CN18)가 있다.  ........ board bottom에 위치

먼저 아래 그림 5.11 ~ 5.12는 Raspberry Pi 호환 connector를 보여준다.
[그림 5.11] CN2(Raspberry Pi 호환 pin) - 40 pin connector

[그림 5.12] CN2 pin 중 I2C로 사용 가능한 pin - pin 3, 5 & pin 27, 28

CN2 pin에서 i2c로 사용 가능한 pin을 살펴 보면, 다음과 같다

pin 3, 5 = PA12, PA11  (i2c5 용)  ..................................................................................... (A)
pin 27, 28 = PF15, PD12 (i2c1 용)  ................................................................................. (B)

다음으로 Arduino 호환 connector를 살펴 보도록 하자.

[그림 5.13] CN13, CN14, CN17, CN18 Arduino connector



[그림 5.14] Arduino connector 중 I2C로 사용 가능한 pin


[그림 5.15] Arduino connector 중 VIN(Vcc), GND pin


Arduino pin 중 i2c 용으로 사용 가능한 pin은 딱 한쌍 뿐이다.

CN13 pin 9, 10 = PA12, PA11(I2C5 용)  ................................................................... (C)

이 세쌍의 pin(노락색으로 표시) 중, 어느 것을 사용해도 무방하나, 여기서는 (C) pin을 사용하도록 하겠다.
[Tip] CN2 pin은 불행하게도 (아래 그림과 같이) LCD screen 바로 아래에 위치하고 있어, jumper cable을 연결하기가 좀 불편해 보인다.

[그림 5.16] CN2 connector의 위치(jumper cable을 연결하기 좀 불편함)

======
드디어 센서 모듈이 도착했다. 😎  생각했던 것보다 크기가 작다(엄지 손톱 정도 크기다).

[그림 5.17] HTU21D 온습도 센서 모듈

먼저 센서 모듈 쪽에 jumper cable을 연결해 보자.

빨간색: 3.3V
갈색(보통 검정색으로 연결): GND
노란색: SDA
녹색: SCL

[그림 5.18] DK2 보드에 HTU21D 온/습도 센서 연결 모습(1)

[Tip] 집에 납땜 용 인두가 없는 관계로, (좀 허접하지만) 스카치 테이프로 고정해 보았다.

다음으로 해당 jumper cable을 (board 전원을 off한 상태에서) target board에 연결해 보도록 하자.

빨간색3.3V                          <==================>  CN16 pin 4(V3.3)
갈색(보통 검정색으로 연결): GND  <=============> CN16 pin 6(GND)
노란색SDA                         <===============> CN13 pin 9(ARD_D14)
녹색SCL                            <===============> CN13 pin 10(ARD_D15)

[그림 5.19] DK2 보드에 HTU21D 온/습도 센서 연결 모습(2)

전원을 켜고 동작을 확인하기 위해서는 device tree 및 device driver 관련 작업을 해야 한다. 따라서 아래 내용을 계속 살펴 보도록 하자.

c) HTU21D 온/습도 센서 연결을 위한 device tree 작업
앞 절에서 HTU21D 센서를 DK2 보드의 i2c5 controller에 연결하는 것까지 설명하였다. 따라서 이 절에서는 이를 device tree로 구현하는 내용을 소개해 본다.

[그림 5.20] linux-5.7.1/arch/arm/boot/dts/stm32mp157c-dk2.dts 파일 수정 내용

먼저 status = "okay"로 해야 i2c5 controller node를 사용할 수 있다.
clock-frequency = <100000> 는 i2c5 bus speed를 100kHz로 지정한 것이다. 이는 "STM32MP157 advanced Arm-based 32bit-bit MPUs" Reference manual(section 52.2)을 참조하여 결정하였다.


pinctrl 관련 3줄은 pin muxing과 관련된 것이다. 보통은 pinctrl-names와 pinctrl-0만 설정하면 되나, 다른 i2c controller를 참조하여 pinctrol-1(sleep mode 용)도 추가해 주었다.

    pinctrl-names = "default", "sleep";
    pinctrl-0 = <&i2c5_pins_a>;
    pinctrl-1 = <&i2c5_pins_sleep_a>;

[Tip] 위의 설정은 해도 그만 안해도 그만인 설정이 아니라, 반드시 해 주어야 하는 설정이다. i2c5 controller를 위한 pin(SDA, SCK)은 다른 pin(예: GPIO)과 pin muxing이 되어 있기 때문에, 정확한 pinmux 설정을 통해 i2c 용으로 사용 가능하게 만들어야 한다.

위의 i2c5_pins_a 및 i2c5_pins_sleep_a에 대한 정보는 아래 파일에 이미 정의되어 있다.

[그림 5.21]  stm32mp15-pinctrl.dtsi 파일에서 발췌

위의 내용 중 STM32_PINMUX macro는 다시 아래 파일에 정의되어 있다. 아래 내용의 정확한 의미를 파악하기 위해서는 DK2 board user manual 내용 중 pin mux 관련 테이블을 확인할 필요가 있다.

[그림 5.22] include/dt-bindings/pinctrl/stm32-pinfunc.h 파일 내용

[Tip] 위의 내용에는 불행하게도 아래 코드(stm32-pinfunc.h)에 기술된 AFX 값에 대한 부분이 표시되어 있지 않다.


암튼,  여러가지 정황으로 봐서는 'A', 11 => PA11, 'A', 12 => PA12를 뜻하며, AF4 = 0x5(mode 값)로 지정해야 i2c 용으로 사용 가능한 것 같다. 참고로, AF4 자리에 0x0을 지정하면 GPIO로 사용된다.
-----------------------------------
pinmux = <STM32_PINMUX('A', 11, AF4)>, /* I2C5_SCL */
                 <STM32_PINMUX('A', 12, AF4)>; /* I2C5_SDA */

-----------------------------------
[Tip] AF는 Alternate Function을 뜻한다. stm32mpu pinctrl과 관련해서는 아래 문서를 참조할 필요가  있다.

Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml

[그림 5.23] st,stm32-pinctrl.yaml에서 발췌한 내용

<여기서 잠깐 !>
-----------------------------
아래 내용은 foo device(가상의 device)에 대해 pinctrl 설정을 어떻게 하는지를 소개하고 있다. 이 내용은 앞서 설명한 pinmux의 내용을 이해하는데 도움을 준다.


조건:
    - foo device는 PC13, PG8, PI2 번 pin을 사용한다.
    - AF2는 P13 pin의 alternate function이고,
    - AF5는 PG8과 PI2의 alternate function 이다.
    - 각 pin은 내부에 pull-up 저항을 필요로 한다.

[그림 5.24] foo device에 pinctrl 예제
-----------------------------

(다시 htu21d 관련 device tree 구현 내용으로 돌아와서) 마지막으로 추가된 부분은 i2c5 controller bus에 붙어 있는 htu21d 온/습도 센서 node에 관한 내용이다.  이를 위해서는 Documentation/devicetree/bindings/iio/humidity/htu21.txt 파일을 확인해 볼 필요가 있다.

    htu21: htu21@40 {
        compatible = "meas,htu21";
        reg = <0x40>;
    };

[그림 5.25]  Documentation/devicetree/bindings/iio/humidity/htu21.txt 파일 내용


d) HTU21D 온/습도 센서 device driver 분석
앞서 HTU21D용 device tree 작업을 하였으니, 이제는 이를 기반으로 실제 동작을 담당하는 device driver 코드를 작성할 차례이다.

HTU21D 온/습도 센서용 device driver는 이미 mainline kernel에 포함되어 있다(일부러 device driver가 구현되어 있는 센서를 찾았다).

linux-5.7.1/drivers/iio/humidity/htu21.c

HTU21D 온/습도 센서는 IIO(Industiral I/O) subsystem framework을 이용하여 구현되어 있는데, 이러한 범주에 속하는 device들에는 다음과 같은 것들이 있다.

  • analog to digital converters (ADCs)
  • accelerometers
  • capacitance to digital converters (CDCs)
  • digital to analog converters (DACs)
  • gyroscopes
  • inertial measurement units (IMUs)
  • color and light sensors
  • magnetometers
  • pressure sensors
  • proximity sensors
  • temperature sensors

[그림 5.26] Industrial I/O subsystem 아키텍쳐(1)


[그림 5.27] Industrial I/O subsystem 아키텍쳐(2)

[그림 5.28] linux-5.7.1/drivers/iio/humidity/htu21.c

probe 함수를 중심으로 주요 코드 흐름을 정리해 보면 다음과 같다.
==================
struct ms_ht_dev
         struct i2c_client *client; 
         struct mutex lock;
         u8 res_index;
};

static int htu21_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *channel, int *val, int *val2, long mask)
{
         ...
}

static int htu21_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask)
{
         ...
}

static const struct iio_info htu21_info = {
        .read_raw = htu21_read_raw,
        .write_raw = htu21_write_raw,
        .attrs = &htu21_attribute_group,
};

static const struct iio_chan_spec htu21_channels[] = {
        {
            .type = IIO_TEMP,
            .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_PROCESSED),
            .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
        },
       {
            .type = IIO_HUMIDITYRELATIVE,
            .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_PROCESSED),
            .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
        }
};

static int htu21_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
         struct ms_ht_dev *dev_data;
         struct iio_dev *indio_dev;

         indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*dev_data));

         dev_data = iio_priv(indio_dev);
         dev_data->client = client;
         dev_data->res_index = 0;
 
         indio_dev->info = &htu21_info;
         indio_dev->name = id->name;
         indio_dev->dev.parent = &client->dev;
         indio_dev->modes = INDIO_DIRECT_MODE;
    
         indio_dev->channels = htu21_channels;
         indio_dev->num_channels = ARRAY_SIZE(htu21_channels);

         i2c_set_clientdata(client, indio_dev);

         ms_sensors_reset(client, HTU21_RESET, 15000);

         ms_sensors_read_serial(client, &serial_number);

         return devm_iio_device_register(&client->dev, indio_dev);
}

static struct i2c_driver htu21_driver = {
        .probe = htu21_probe,
        .id_table = htu21_id,
        .driver = {
               .name = "htu21",
               .of_match_table = of_match_ptr(htu21_of_match),
           },
};
==================

마지막으로 아래 앞서 정의한 device tree와 device driver를 연결 시켜 주는 코드는 아래(그림 5.29)와 같다.

    htu21: htu21@40 {
        compatible = "meas,htu21";
        reg = <0x40>;
    };

[그림 5.29] htu21 driver compatible 정보


e) HTU21D 온/습도 센서 동작 시험
자, 모든 것이 준비되었으니, 수정한 device tree를 포함한 상태에서 kernel을 재 build하여 보도록 하자.

$ make linux-menuconfig
  => 먼저 앞절에서 설명한 htu21d device driver를 enable시켜야 한다.
  => Device Drivers ==> Industrial I/O support ==> Humidity sensors ==>
                          <*> Measurement Specialties HTU21 humidity & temperature sensor

[그림 5.30] HTU21 humidity sensor enable

$ make linux-update-defconfig
    => 앞서 수정한 kernel config를 저장한다.
    => board/stmicroelectronics/stm32mp157c-dk2/linux.config 파일에 관련 내용이 저장된다.

$ make
   => 앞서 수정한 kernel config와 device tree 내용이 반영되어 build된다.

$ cd output/images
$ ls -la
합계 132180
drwxr-xr-x 3 chyi chyi      4096  6월 16 17:03 .
drwxr-xr-x 6 chyi chyi      4096  6월 16 17:03 ..
-rw-r--r-- 1 chyi chyi 125829120  6월 16 17:03 rootfs.ext2
lrwxrwxrwx 1 chyi chyi        11  6월 16 17:03 rootfs.ext4 -> rootfs.ext2
-rw-r--r-- 1 chyi chyi 126822400  6월 16 17:03 sdcard.img
-rwxr-xr-x 1 chyi chyi     49696  6월 16 17:02 stm32mp157c-dk2.dtb
drwxr-xr-x 2 chyi chyi      4096  6월 12 15:37 tmp
-rw-r--r-- 1 chyi chyi     75983  6월 12 10:30 u-boot-spl.stm32
-rw-r--r-- 1 chyi chyi    806344  6월 12 10:29 u-boot.img
-rw-r--r-- 1 chyi chyi   4155936  6월 16 17:02 zImage

Target  board의 zImage 및 stm32mp157c-dk2.dtb 파일(/boot 디렉토리에 있음)과 파일 크기를 비교해 보니, 차이가 나는 것으로 보아, 정상적으로 build가 된 것 같다.

Build 결과물을 dd로 microSD에 full writing을 할게 아니라, 이번에는 zImage와 dtb 파일만 target board로 복사하여 사용해 보자.

<Desktop PC>

[그림 5.31] scp로 zImage와 dtb 파일 upload

<Target board>

[그림 5.32] zImage와 dtb 파일을 /boot 디렉토리로 복사

# sync; sync
# reboot

자, 이제 target board가 재 부팅되었으니, htu21d 온/습도 센서가 정상 동작하는지를 확인해 보도록 하자.

[그림 5.33] kernel booting messages

먼저 /sys/bus/i2c/devices 디렉토리 아래에서 i2c5: i2c@40015000가 i2c device 몇번 bus로 인식되지를 확인해 보자.

[그림 5.34] /sys/bus/i2c/devices 내용 확인

i2c-2 -> ../../../devices/platform/soc/40015000.i2c/i2c-2

두번째(i2c-2)로 인식되고 있다. 그러면 busybox에 기본으로 포함되어 있는 i2cdetect 명령으로 i2c5 controller에 i2c device가 붙어 있는지를 확인해 보자. 아래 그림을 보면 알 수 있는 바와 같이 1개의 i2c device가 보이는데, 0x40 번지를 사용하고 있다. 이는 앞서 DK2 보드에 장착한 HTU21D 센서 모듈에 해당한다. 이로써 센서 연결이 (1차적으로) 정상임을 알 수 있다.

[그림 5.35] i2c-2(linux에서 인식하는 값 - 실제 DK2 보드의 I2C5 controller에 해당) bus에 붙어 있는 device 확인 모습

다음으로 확인할 사항은 실제 센서 data에 대한 것이다.

2-0040 -> ../../../devices/platform/soc/40015000.i2c/i2c-2/2-0040

# cd 2-0040

[그림 5.36] i2c-2 bus(실제로는 I2C5 controller임)에 붙어 있는 0x40 주소 device 내용 확인

[Tip] /sys/bus/iio/devices 디렉토리로 이동해서 확인해도 된다(동일한 디렉토리임).

뭔가 많은 내용이 보인다.

# cd iio\:devices/

[그림 5.37] htu21 센서 모듈 정보

다시, 이 중에서 습도와 온도 값을 확인해 보면 다음과 같다. Wow, 정상적으로 센서 data가 출력된다.
# cat in_humidityrelative_input 
36480
=> 습도 36.480%
# cat in_temp_input 
31142
=> 섭씨 31.142도

위의 센서 data의 정확한 의미를 파악하기 위해서는 아래 파일을 참조할 필요가 있다.

Documentation/ABI/testing/sysfs-bus-iio


[그림 5.38] htu21 센서 모듈 정보 - 단위 계산 방법


지금까지 작업한 내용을 buildroot에 반영하는 작업 등이 남아 있으나, 지면 관계상 생략하기로 한다.
자세한 사항은 reference [1] 문서를 참조해 주기 바란다.



6. 온습도 센서 출력용 Qt application 만들기
이번 장에서는 앞서 5장에서 장착한 온습도 센서의 출력 결과를 확인할 수 있는 Qt application을 만드는 과정을 소개해 보고자 한다.

To be continued ...




8. References
   => 위의 내용을 많이 참조하였음.
   =>  HTU21D 온/습도 센서 datasheet & 회로도
[6] Industrial I/O Subsystem: The HOme of Linux Sensors, daniel.baluta@intel.com
[7] IIO, a new kernel subsystem, maxime.ripard@bootlin.com
[8] GNU/Linux Rapid Embedded Programming, Rodolfo Giometti


Slowboot


댓글 3개:

  1. 블로그 관리자가 댓글을 삭제했습니다.

    답글삭제
  2. 블로그 관리자가 댓글을 삭제했습니다.

    답글삭제
  3. 블로그 관리자가 댓글을 삭제했습니다.

    답글삭제