2016년 12월 15일 목요일

How to connect an USB Camera with SAMA5D3 Xplained board

LCD 장치와 함께 USB Camera도 하나 구입했다. 당초 계획은 ISI(Image Sensor Interface)에 맞는 CMOS-type image 센서가 장착된 camera를 구매하는 거였으나, 이게 여유치가 않았다. 이번 blog에서는 지난 blog(LCD)에 이어, USB camera를 Atmel SAMA5D3 Xplained board에 연결시켜 보고, 그 과정에서 device driver(device tree) 관련하여 issue가 될 만한 부분을 살펴 보고자 한다. USB camera 라서 특별히 device tree를 수정할 사항이 없는 것이 좀 아쉽지만 말이다...
<목차>
1. CAM8200-U Camera 소개
2. Device Driver 관련 작업(under BuildRoot environment)
3. Camera 동작 시험(under BuildRoot environment)


1. CAM8200-U Camera 소개
CAM8200-U는 Embest Technology에서 디자인한 5 메가 픽셀 USB camera 모듈로 automatic focus, white balance, exposure control 및 gain control을 지원한다. 상세 스펙을 소개해 보면 다음과 같다.


아래 그림 1.1은 CAM8200-U의 USB 인터페이스를 보여주고 있다.

그림 1.1 CAM8200-U의 USB OTG 인터페이스 (출처 - 참고 문헌 [1])


2. Device Driver 관련 작업
이번 절에서는 USB Camera가 동작 가능하도록 kernel config를 조정해 보도록 하자.

2.1 kernel config 조정
$ cd buildroot
$ make linux-menuconfig

<Multimedia USB Adapter USB Video Class 지정>
    Device Drivers --->
          <*>   Multimedia support --->
                [*]   Media USB Adapters  --->
               <*>   USB Video Class (UVC)
               [*]     UVC input events device support (NEW)


그림 2.1 kernel menuconfig - USB Video Class 지정 화면

<Graphics Framebuffer Console support>
    Device Drivers --->
           Graphics support  --->
          Console display driver support  --->
         <*> Framebuffer Console support
          -*-   Map the console to the primary display device


그림 2.2 kernel menuconfig - framebuffer conosole 지원 지정 화면

참고로, 참고 문헌 [1]에 언급된 kernel configuration 내용이 좀 old version을 기준으로 되어 있는 듯 보인다.

2.2 kernel 재 build 및 NAND booting
  => buildroot 전체를 build할 필요 없이, kernel만 재 build하도록 하자.
==============================================================
chyi@earth:~/Atmel/buildroot$ make linux-rebuild
rm -f /home/chyi/Atmel/buildroot/output/build/linux-linux4sam_5.5/.stamp_staging_installed
rm -f /home/chyi/Atmel/buildroot/output/build/linux-linux4sam_5.5/.stamp_target_installed
rm -f /home/chyi/Atmel/buildroot/output/build/linux-linux4sam_5.5/.stamp_images_installed
rm -f /home/chyi/Atmel/buildroot/output/build/linux-linux4sam_5.5/.stamp_host_installed
rm -f /home/chyi/Atmel/buildroot/output/build/linux-linux4sam_5.5/.stamp_built
>>> linux linux4sam_5.5 Building
PATH="/home/chyi/Atmel/buildroot/output/host/bin:/home/chyi/Atmel/buildroot/output/host/sbin:/home/chyi/Atmel/buildroot/output/host/usr/bin:/home/chyi/Atmel/buildroot/output/host/usr/sbin:/home/chyi/bin:/home/chyi/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin" BR_BINARIES_DIR=/home/chyi/Atmel/buildroot/output/images /usr/bin/make -j5 HOSTCC="/usr/bin/gcc" HOSTCFLAGS="" ARCH=arm INSTALL_MOD_PATH=/home/chyi/Atmel/buildroot/output/target CROSS_COMPILE="/home/chyi/Atmel/buildroot/output/host/usr/bin/arm-buildroot-linux-gnueabihf-" DEPMOD=/home/chyi/Atmel/buildroot/output/host/sbin/depmod INSTALL_MOD_STRIP=1 -C /home/chyi/Atmel/buildroot/output/build/linux-linux4sam_5.5 zImage
  CHK     include/config/kernel.release
  CHK     include/generated/uapi/linux/version.h
  CHK     include/generated/utsrelease.h
make[3]: 'include/generated/mach-types.h'은(는) 이미 업데이트되었습니다.
  CHK     include/generated/timeconst.h
  CHK     include/generated/bounds.h
  CHK     include/generated/asm-offsets.h
  CALL    scripts/checksyscalls.sh
  CHK     include/generated/compile.h
  Kernel: arch/arm/boot/Image is ready
  Kernel: arch/arm/boot/Image is ready
  Kernel: arch/arm/boot/zImage is ready
  CHK     include/config/kernel.release
  CHK     include/generated/uapi/linux/version.h
  CHK     include/generated/utsrelease.h
make[3]: 'include/generated/mach-types.h'은(는) 이미 업데이트되었습니다.
  CHK     include/generated/timeconst.h
  CHK     include/generated/bounds.h
  CHK     include/generated/asm-offsets.h
  CALL    scripts/checksyscalls.sh
  Building modules, stage 2.
  MODPOST 42 modules
PATH="/home/chyi/Atmel/buildroot/output/host/bin:/home/chyi/Atmel/buildroot/output/host/sbin:/home/chyi/Atmel/buildroot/output/host/usr/bin:/home/chyi/Atmel/buildroot/output/host/usr/sbin:/home/chyi/bin:/home/chyi/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin" BR_BINARIES_DIR=/home/chyi/Atmel/buildroot/output/images /usr/bin/make -j5 HOSTCC="/usr/bin/gcc" HOSTCFLAGS="" ARCH=arm INSTALL_MOD_PATH=/home/chyi/Atmel/buildroot/output/target CROSS_COMPILE="/home/chyi/Atmel/buildroot/output/host/usr/bin/arm-buildroot-linux-gnueabihf-" DEPMOD=/home/chyi/Atmel/buildroot/output/host/sbin/depmod INSTALL_MOD_STRIP=1 -C /home/chyi/Atmel/buildroot/output/build/linux-linux4sam_5.5 at91-sama5d3_xplained_pda4.dtb
make[3]: 'arch/arm/boot/dts/at91-sama5d3_xplained_pda4.dtb'은(는) 이미 업데이트되었습니다.
>>> linux linux4sam_5.5 Installing to target
# Install modules and remove symbolic links pointing to build
# directories, not relevant on the target
  INSTALL crypto/af_alg.ko
  INSTALL crypto/algif_hash.ko
  INSTALL crypto/algif_skcipher.ko
  INSTALL crypto/echainiv.ko
  INSTALL drivers/leds/leds-blinkm.ko
  INSTALL drivers/leds/leds-regulator.ko
  INSTALL drivers/media/i2c/soc_camera/ov2640.ko
  INSTALL drivers/media/i2c/soc_camera/ov5642.ko
  INSTALL drivers/media/i2c/soc_camera/ov6650.ko
  INSTALL drivers/media/i2c/soc_camera/ov772x.ko
  INSTALL drivers/media/i2c/soc_camera/ov7740.ko
  INSTALL drivers/media/i2c/soc_camera/ov9640.ko
  INSTALL drivers/media/i2c/soc_camera/ov9740.ko
  INSTALL drivers/media/usb/gspca/gspca_main.ko
  INSTALL drivers/mtd/ubi/gluebi.ko
  INSTALL drivers/net/wireless/libertas_tf/libertas_tf.ko
  INSTALL drivers/net/wireless/libertas_tf/libertas_tf_usb.ko
  INSTALL drivers/net/wireless/mwifiex/mwifiex.ko
  INSTALL drivers/net/wireless/mwifiex/mwifiex_sdio.ko
  INSTALL drivers/net/wireless/mwifiex/mwifiex_usb.ko
  INSTALL drivers/net/wireless/rt2x00/rt2500usb.ko
  INSTALL drivers/net/wireless/rt2x00/rt2800lib.ko
  INSTALL drivers/net/wireless/rt2x00/rt2800usb.ko
  INSTALL drivers/net/wireless/rt2x00/rt2x00lib.ko
  INSTALL drivers/net/wireless/rt2x00/rt2x00usb.ko
  INSTALL drivers/net/wireless/rt2x00/rt73usb.ko
  INSTALL drivers/spi/spidev.ko
  INSTALL drivers/staging/wilc1000/wilc1000-sdio.ko
  INSTALL drivers/staging/wilc1000/wilc1000.ko
  INSTALL drivers/usb/gadget/function/u_serial.ko
  INSTALL drivers/usb/gadget/function/usb_f_acm.ko
  INSTALL drivers/usb/gadget/function/usb_f_mass_storage.ko
  INSTALL drivers/usb/gadget/function/usb_f_obex.ko
  INSTALL drivers/usb/gadget/function/usb_f_serial.ko
  INSTALL drivers/usb/gadget/function/usb_f_ss_lb.ko
  INSTALL drivers/usb/gadget/legacy/g_mass_storage.ko
  INSTALL drivers/usb/gadget/legacy/g_serial.ko
  INSTALL drivers/usb/gadget/legacy/g_zero.ko
  INSTALL drivers/usb/gadget/libcomposite.ko
  INSTALL drivers/usb/gadget/udc/atmel_usba_udc.ko
  INSTALL lib/crc-ccitt.ko
  INSTALL lib/crc-itu-t.ko
  DEPMOD  4.4.26-linux4sam_5.5
# Installing dtc (device tree compiler) as host tool, if selected
if grep -q "CONFIG_DTC=y" /home/chyi/Atmel/buildroot/output/build/linux-linux4sam_5.5/.config; then /usr/bin/install -D -m 0755 /home/chyi/Atmel/buildroot/output/build/linux-linux4sam_5.5/scripts/dtc/dtc /home/chyi/Atmel/buildroot/output/host/usr/bin/linux-dtc ; if [ ! -e /home/chyi/Atmel/buildroot/output/host/usr/bin/dtc ]; then ln -sf linux-dtc /home/chyi/Atmel/buildroot/output/host/usr/bin/dtc ; fi fi
>>> linux linux4sam_5.5 Installing to images directory
/usr/bin/install -m 0644 -D /home/chyi/Atmel/buildroot/output/build/linux-linux4sam_5.5/arch/arm/boot/zImage /home/chyi/Atmel/buildroot/output/images/zImage
# dtbs moved from arch/<ARCH>/boot to arch/<ARCH>/boot/dts since 3.8-rc1
cp /home/chyi/Atmel/buildroot/output/build/linux-linux4sam_5.5/arch/arm/boot/dts/at91-sama5d3_xplained_pda4.dtb /home/chyi/Atmel/buildroot/output/images
==============================================================

Build 결과물(zImage, dtb file)을 /tftpboot 디렉토리로 복사하자.

chyi@earth:~/Atmel/buildroot/output/build/linux-linux4sam_5.5/arch/arm/boot$ cp zImage /tftpboot/

chyi@earth:~/Atmel/buildroot/output/build/linux-linux4sam_5.5/arch/arm/boot/dts$ cp ./at91-sama5d3_xplained_pda4.dtb /tftpboot/
==============================================================

Target board의 NAND flash에 zImage와 dtb file을 올리자.

<Target board u-boot 명령>
=> tftp 0x21000000 zImage
gmac0: PHY present at 7
gmac0: Starting autonegotiation...
gmac0: Autonegotiation complete
gmac0: link up, 100Mbps full-duplex (lpa: 0x45e1)
Using gmac0 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.50
Filename 'zImage'.
Load address: 0x21000000
Loading: ################################################################# #################################################################
################################
3 MiB/s
done
Bytes transferred = 3824160 (3a5a20 hex)
=> nand erase 0x200000 0x600000

NAND erase: device 0 offset 0x200000, size 0x600000
Erasing at 0x7e0000 -- 100% complete.
OK
=> nand write 0x21000000 0x200000 0x3a5a20

NAND write: device 0 offset 0x200000, size 0x3a5a20
 3824160 bytes written: OK
=> 
==============================================================

3. Camera 동작 시험
자, 이제 USB camera를 SAMA5D3 Xpalined board에 연결한 후, 2절에서 새로 build한 zImage로 부팅을 시도해 보자.

3.1 USB camera  정상 인식 확인
아래 내용으로 보아서는 일단 USB camera가 정상적으로 인식된 듯 보인다. 실제로 camera가 제대로 동작하는지를 확인하기 위해서 V4L2 interface를 사용하는 camera application이 하나 필요하다.

그림 3.1 USB camera 인식 내용 확인 - kernel booting message

그림 3.2 USB camera 인식 내용 확인 - sysfs 내용

3.2 camera application test
아래 site에서 간단한 camera application program을 하나 download 받자.

(*) source code를 보니, Common Display Framework을 설계한 Laurent Pinchart (laurent.pinchart@skynet.be)가 작성한 코드이다.

$ mkdir CAM8200-U
$ unzip ./CAM8200-U.zip

이 program을 돌리려면, cross-compile이 필요한데, 편의상 이전 blog에서 설명했던 buildroot 환경에서 작업을 하도록 하자.

<방법 1 - BuildRoot 외부에서 build한 후, rootfs에 binary만 포함 시키는 방법>
export PATH=/home/chyi/Atmel/buildroot/output/host/usr/bin:$PATH
  => BuildRoot의 toolchain path를 잡는다.

$ vi Makefile
  => luvc_test(camera test app)의 Makefile을 수정한다.

코드 3.1 camera application을 위한 Makefile

$ make clean
$ make
$ ls -l
-rw-rw-r-- 1 chyi chyi   238 12월 14 21:00 Makefile
-rw-rw-r-- 1 chyi chyi    65 12월 14 18:53 README.chyi
-rw-rw-r-- 1 chyi chyi   837  4월 20  2015 README.txt
-rwxrwxr-x 1 chyi chyi 18224 12월 14 21:00 luvc_test
-rw-rw-r-- 1 chyi chyi 21931  4월 20  2015 luvc_test.c

$ cp ./luvc_test /home/chyi/Atmel/buildroot/output/images/rootfs/sbin
  => luvc_test app을 rootfs 디렉토리로 복사한다.

<방법 2 - BuildRoot에 패키지 형태로 추가하기>
$ cd ~/Atmel/demo/camera/camera_app
$ ls -l
-rw-rw-r-- 1 chyi chyi   269 12월 15 12:09 Makefile
-rw-rw-r-- 1 chyi chyi   837 12월 15 12:05 README.txt
-rw-rw-r-- 1 chyi chyi 21931 12월 15 12:05 luvc_test.c
$ vi Makefile
코드 3.2 원본 Makefile for luvc_test
====================================================

$ cd ~/Atmel/buildroot/package
$ mkdir camera_app
$ cd camera_app
$ vi Config.in
코드 3.3 Config.in for camera_app

$ vi camera_app.mk
코드 3.4 camera_app.mk

$ cd ..
$ vi Config.in
  => 아래 한 줄을 추가한다.
...
menu "Miscellaneous"
    source "package/aespipe/Config.in"
    source "package/bc/Config.in"
    source "package/clamav/Config.in"
    source "package/collectd/Config.in"
    source "package/domoticz/Config.in"
    source "package/empty/Config.in"
    source "package/gnuradio/Config.in"
    source "package/googlefontdirectory/Config.in"
    source "package/gr-osmosdr/Config.in"
    source "package/gsettings-desktop-schemas/Config.in"
    source "package/haveged/Config.in"
#test code - added by chunghan.yi@gmail.com - 12/15/2016
    source "package/camera_app/Config.in"
#-- --
    source "package/mcrypt/Config.in"
    source "package/mobile-broadband-provider-info/Config.in"
    source "package/qemu/Config.in"
    source "package/qpdf/Config.in"
    source "package/shared-mime-info/Config.in"
    source "package/snowball-init/Config.in"
    source "package/taskd/Config.in"
    source "package/wine/Config.in"
    source "package/xutil_util-macros/Config.in"
endmenu

$ cd ..
$ make menuconfig
  => camera_app을 선택한다.

그림 3.3 camera_app package 메뉴 선택 화면

$ make

$ cd ~/Atmel/buildroot/output/build/camera_app-0.0.1$ ls -l
합계 48
-rw-r--r-- 1 chyi chyi   269 12월 15 12:09 Makefile
-rw-r--r-- 1 chyi chyi   837 12월 15 12:05 README.txt
-rwxr-xr-x 1 chyi chyi 15644 12월 15 12:15 luvc_test
-rw-r--r-- 1 chyi chyi 21931 12월 15 12:05 luvc_test.c
====================================================

이상의 두가지 방법 중, 하나를 이용하여 생성한 luvc_test를 가지고, NFS booting을 시도한 후, 아래 명령을 실행해 보자.

$ /sbin/luvc_test
   => 명령이 실행되는 걸 보니, 제대로 cross-compile이 되었다.


그림 3.2 luvc_test 명령 실행 결과 화면

다음으로, 아래와 같은 option을 주어 사진(still shot)을 찍어 보도록 하자.

luvc_test -c -f mjpg -s 320x240 -c --skip 10 /dev/video0
  => camera가 capture한 내용이 /tmp/capture.jpg파일 형태로 저장된다.
  => 10개의 frame을 skip하고 (안정적인 상태의) cut을  찍음.
  => jpg 파일을 scp 명령으로 Host PC로 가져와 확인해 보니, 아래 그림 3.3과 같이 제대로 나온다(USB camera 동작에는 이상이 없다는 뜻).


그림 3.3 Camera로 찍은 사진 - 오늘 마신 *벅스 커피

다음으로 아래와 같은 option을 주어, camera가 capture한 내용을 LCD로 출력해 보자.

$ luvc_test -c -f mjpg -s 320x240 -S /dev/video0
  => camera로 capture한 내용을 LCD로 연속해 출력한다.

이 명령의 경우는 camera에 찍힌 내용이 실시간으로 LCD 화면에 출력되기는 한다. 하지만, 화면의 내용이 실물을 알아보기 매우 어려울 정도로 깨져보인다. 왜일까 ?


내일은 luvc_test source 및 Atmel hlcdc driver code(drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c)를 살펴 보도록 해야 겠다.

지금까지 간략하게 나마 USB camera를 SAMA5D3 Xplained board에 장착하는 과정을 blog에 담아 보았다. 역시 설명이 부족하거나, 추가 시험이 필요한 부분은 추후 좀 더 보강해 보도록 하자.


References
1. Cam8200_QGS_03132015.pdf - element14
2. CAM8200-U User Manual.pdf - Embest Technology



Slowboot

댓글 없음:

댓글 쓰기