- Autoconf Manual
글 혹은 그림의 출처가 문제있다면 수정 및 삭제하겠습니다. 우측의 Tags 와 검색기능을 이용하여 편하게 찾을 수 있습니다.
Please check buttons on the right like Tags and language options if can't read this blog (*mobile not support)
2/28/2016
autoconf automake aclocal, autoheader,
최근들어 Autoconf와 Automake 및 관련사항을 잘 다루지 않으며, 거의 사실 사용할 일이 없어, 아래와 같이 Link만 연결한다.
2/27/2016
Linux RC Script 와 /etc/network/interfaces 분석
Linux Init Script로 배포하는 곳마다 다르며, 지속적으로 변화 중인 것 같아 간단히 기록한다.
아래와 같이 간단히 동작부분을 확인만 하자
http://dietpc.org/downloads/source/common/diet-pc/initscript/etc/rc
아래와 같이 간단히 동작부분을 확인만 하자
#! /bin/sh ## # DIET-PC master initialisation script # Copyright (C) 2002-2013 Paul A Whittaker# This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA [ -f /etc/profile ] && . /etc/profile export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin umask 022 notify () { # To aid degugging, you might wish to uncomment the sleep command, to give # you a chance to press the key and see errors before they scroll # off. #busybox sleep 3 echo -e "${HL_ON}$*${HL_OFF}" case "$HAVE_SPLASH" in TRUE) ## 숫자변수를 1씩 증가 NOTIFY_COUNT=$(($NOTIFY_COUNT + 1)) echo "show $((65535 * $NOTIFY_COUNT / $NOTIFY_TOTAL))" >>/proc/splash ;; esac } busybox mount /proc # If the console is a VT, we can use ANSI escapes to do highlighting. "tty" # doesn't work until /dev is mounted, so use console=xxx in /proc/cmdline to # determine this. case "`busybox sed -e 's/^.*\ ' /etc/rc /etc/rc.d/* /usr/etc/rc.d/* /usr/local/etc/rc.d/* | busybox wc -l`-1)) else HAVE_SPLASH= fi notify 'Mounting core filesystems' ROOTDEV=`busybox sed -e 's/^.*\ '; then # If root is read-only and it is not prohibited by a "no_root_union" # kernel parameter, try to mount a new root as a union of the original # (read-only) root filesystem and a tmpfs (read-write) filesystem. busybox mkdir -m 0755 /tmp/.overlay busybox modprobe -q unionfs busybox grep -qv '\ ' /proc/cmdline && busybox mount \ -t unionfs -o dirs=/tmp/.overlay=rw:/=ro none /mnt ## if [ $? -eq 0 ]; then cd /mnt busybox pivot_root . ./oldroot busybox umount /oldroot/proc 2>/dev/null busybox mount /proc else # If not mounted already (via a kernel feature), mount a writable # tmpfs /dev. busybox awk 'BEGIN {n=0} $2 == "/dev" {n=1} END {exit n}' \ /proc/mounts && busybox mount -t tmpfs -o \ nr_blocks=256,nr_inodes=1024,mode=0755 none /dev # If the root filesystem is still read-only, try to remount it # read-write. Remounts don't seem to work reliably when using the # Busybox mount applet, so only use it as a last resort. mount -o remount,rw / 2>/dev/null || busybox mount -o remount,rw / if [ $? -ne 0 ]; then # If still no-go, there is no point in continuing - let the # operator try to fix it and then reboot. echo 'Root filesystem is not writable, please fix!' [ "$LOCKDOWN" ] && busybox sleep 10 || busybox sulogin exec reboot -ifd fi fi fi fi busybox mount /sys 2>/dev/null busybox mkdir -p /dev/pts busybox mount /dev/pts 2>/dev/null busybox mkdir -p /dev/shm busybox mount /dev/shm 2>/dev/null notify 'Initializing busybox' busybox --install -s # Remove any residual junk from /var/run. rm -f /var/run/* 2>/dev/null notify 'Initializing /dev' ln -sf "$ROOTDEV" /dev/root 2>/dev/null ln -snf /proc/self/fd /dev/fd ln -sf /proc/self/fd/0 /dev/stdin ln -sf /proc/self/fd/1 /dev/stdout ln -sf /proc/self/fd/2 /dev/stderr ln -sf /proc/kcore /dev/core echo '/sbin/mdev' >/proc/sys/kernel/hotplug mdev -s if [ "$LOCKDOWN" ]; then # Remove root's password hash, thereby preventing root login and su to root. sed -i -e 's/^root:[^:]\+:/root:*:/' /etc/shadow # Turn off console login. sed -i -e '/^logn:/d' /etc/inittab kill -HUP 1 # Set TCP wrappers to deny by default. echo 'ALL: ALL' >/etc/hosts.deny # Remove the setuid bit from busybox, to prevent use of setuid-root applets. chmod u-s /bin/busybox # Prevent unprivileged users from running an X11 terminal emulator. XTERM=`which xterm` [ "$XTERM" ] && chmod 700 "$XTERM" fi notify 'Initializing modules' mkdir -p /lib/modules/`uname -r` depmod -a # If an eth0 hint has been provided via the boot loader or via # /etc/modprobe.conf, use it now, in case there are multiple PCI NICs. [ "$eth0" ] && modprobe -q `echo $eth0 | tr , ' '` modprobe -q eth0 # Forceload some difficult modules that will otherwise neither coldplug nor # hotplug. modprobe -q parport modprobe -q ppp modprobe -q tun modprobe -q floppy modprobe -q loop # Coldplug all platform, PCI, PCMCIA and USB devices initially found (in that # order). for BUS in platform pci pcmcia usb; do if [ -d /sys/bus/$BUS/devices ]; then notify "Initializing $BUS devices" cat /sys/bus/$BUS/devices/*/modalias 2>/dev/null | while read MODULE; \ do modprobe -q $MODULE done fi done # Some last resorts, needed only in the event that bus coldplugging has not # initialised the necessary device. modprobe -q ide-generic modprobe -q scsi_hostadapter modprobe -q sound-slot-0 # Attempt to mount the legacy usb device filesystem if a USB host controller is # now online. mount /proc/bus/usb 2>/dev/null # Set a provisional hostname. if [ "`hostname`" = '(none)' ]; then # First try the contents of /etc/hostname, then the name of the special # non-localhost loopback address. HN=`cat /etc/hostname 2>/dev/null` || HN=`checkhostname -n 127.0.1.1` # Failing that, check all local MAC addresses against /etc/ethers. If # there is a match, set the hostname from the hostname field of the first # matching entry. if [ $? -ne 0 -a -f /etc/ethers ]; then HN=`/sbin/ifconfig -a | awk 'BEGIN {printf "{IGNORECASE=1}\n"} \ /HWaddr/ {printf "$1 == \"%s\" {print $2; exit}\n", $NF}' | \ awk -f - /etc/ethers` fi # As a last resort, derive a hostname from the MAC address of a local # network interface. [ "$HN" ] || HN=`ifconfig -a | awk '/HWaddr/ {printf "X%s\n", $NF; exit}' \ | tr -d :` # Use what we have. [ "$HN" ] && hostname "$HN" fi #### ## 아래의 Shell script는 /etc/network를 자동으로 proc를 정보기반으로 생성해준다. ## /etc/network 와 /etc/network/if-up.d 비롯하여 관련 directory 생성 ## /proc/net/dev 정보를 바탕으로 IFACE (e.g eth0) 를 얻어 IFMETHOD 값을 설정 ## notify 'Initializing network' mkdir -p /etc/network (cd /etc/network; mkdir -p if-up.d if-down.d if-pre-up.d if-post-down.d) if [ ! -f /etc/network/interfaces ]; then notify 'Network not configured - using DHCP' tail -n +3 /proc/net/dev | cut -f1 -d: | while read IFACE; do case "$IFACE" in lo) IFMETHOD='loopback' ;; sit*) IFMETHOD='manual' ;; *) IFMETHOD='dhcp' ;; esac echo "auto $IFACE" >>/etc/network/interfaces echo "iface $IFACE inet $IFMETHOD" >>/etc/network/interfaces done fi ifup -a if [ -x /bin/ifplugd -a -x /etc/ifplugd/ifplugd.action ]; then for IFACE in `netstat -r | awk '/^[0-9]/ {print $NF}'`; do ifplugd -i "$IFACE" -p -q done fi if [ ! -s /etc/hosts.allow ]; then # In the absence of an explicit configuration, set TCP wrappers to grant # access to clients on any local subnet or with the same DNS domain name # suffix. ifconfig | grep '\ >/etc/hosts.allow NETWORK= eval `ipcalc -n $ADDR 2>/dev/null` [ "$NETWORK" ] && echo "ALL: $NETWORK/$MASK" >>/etc/hosts.allow done fi # Check reverse lookups on all active non-loopback interfaces (now that we # (possibly) have DNS). HN= for IPADDR in `ifconfig | grep 'inet addr:[0-9.]\+' | sed -e \ 's/^.*inet addr:\([0-9.]\+\).*$/\1/' | grep -v '^127\.'`; do HN=`checkhostname -n "$IPADDR" | cut -f1 -d.` [ "$HN" ] && break done if [ "$HN" ]; then # Any hostname found via reverse lookup will be considered more # authoritative than the provisional hostname (N.B. a hostname set by # /sbin/udhcpc-helper from DHCP results is provisional). If you don't # want this behaviour, comment out everything except the "else" clause of # this "if" statement (including if, else, and fi lines). hostname "$HN" else # If there is no better hostname, endorse the provisional one by adding # an /etc/hosts entry for it using a local IP address. sed -i -e '/\<'"`hostname`"\$/d /etc/hosts echo -e "${IPADDR:-127.0.1.1}\t`hostname`" >>/etc/hosts fi # If possible, set the system clock at this point. Fsck needs this for # scheduled checks, and loggers need it for meaningful timestamps. Change -u # to -l if you want your system clock to keep local time rather than UTC time. # NTP synchronisation might be slow, but we can't background this, as it might # be our last hope of getting a plausible clock setting (before fsck etc). if [ -c /dev/rtc ]; then notify 'Setting time from hardware clock' if [ "`hwclock -u -r | egrep -w '(1970|2000)'`" ]; then notify 'Sanity check failed - ignoring data from hardware clock' else hwclock -u -s fi if checkhostname -q ${timeserver:-timeserver}; then notify 'Synchronising clock with network time server' ntpd -n -q -p ${timeserver:-timeserver} hwclock -u -w ntpd -p ${timeserver:-timeserver} fi fi notify 'Mounting all filesystems' # We might have portmap (IPV4 only) or rpcbind (IPV4+IPV6) or neither. portmap 2>/dev/null || rpcbind 2>/dev/null || true # If you reference a network block device (/dev/nbd0 etc al) in /etc/fstab, # you must prepare it for use here, e.g. #nbd-client myserver 2000 /dev/nbd0 -persist >/dev/null 2>&1 # Scan for RAID arrays and try to assemble all that are found. Only start # fully intact arrays. if [ "`which mdadm`" ]; then if [ ! -e /etc/mdadm.conf ]; then echo 'MAILADDR root' >/etc/mdadm.conf mdadm --examine --brief --scan --config=partitions >>/etc/mdadm.conf fi mdadm --assemble --scan --no-degraded --auto=yes mdadm --monitor --scan --daemonise --pid-file=/var/run/mdmonitor.pid fi # Scan for LVM volume groups and activate all that are found. if [ "`which lvm`" ]; then rm -f /etc/lvm/cache/.cache lvm pvscan lvm vgscan lvm vgchange -ay fi fsck -aCRAT case $? in 0|1) ;; 2|3) exec reboot -ifd ;; *) echo 'Fsck failed ... need help!' [ "$LOCKDOWN" ] && sleep 10 || sulogin exec reboot -ifd ;; esac mount -a 2>/dev/null if [ $? -ne 0 ]; then # The kernel might have been too slow to load the necessary modules during # the first attempt, so wait a moment and then retry. sleep 2 mount -a 2>/dev/null fi swapon -a 2>/dev/null # Logging chews up a little memory but is a valuable debugging aid. notify 'Starting loggers' if checkhostname -q ${logserver:-logserver}; then syslogd -m 0 -R ${logserver:-logserver} else syslogd -m 0 -C fi klogd # Start crond (if available). if [ -x /sbin/crond ]; then notify 'Starting cron' mkdir -p /var/spool/cron/crontabs chmod 1733 /var/spool/cron/crontabs crond fi notify 'Starting power management' # If CPU frequency scaling is available, install a demand-driven governor # to reduce power consumption and heat output when high CPU performance is not # needed. for CPU in /sys/devices/system/cpu/cpu*; do if [ -f $CPU/cpufreq/scaling_governor ]; then echo 'conservative' >$CPU/cpufreq/scaling_governor 2>/dev/null if [ "`cat $CPU/cpufreq/scaling_governor`" != 'conservative' ]; then echo 'ondemand' >$CPU/cpufreq/scaling_governor 2>/dev/null fi fi done # Set a 30 minute idle spin-down on all hard disks. for DISK in /dev/hd? /dev/sd?; do [ "$DISK" = 'hd?' -o "$DISK" = 'sd?' ] && continue hdparm -S 241 $DISK >/dev/null 2>&1 done if [ -f /etc/sysctl.conf ]; then notify 'Adjusting kernel parameters' sysctl -e -p fi # If you want to force canonicalization of files in /usr/etc or /usr/local/etc, # uncomment the following "if". This will delete everything in /etc that # previously got copied from /usr/etc and /usr/local/etc, and thereby force # them to be copied again. This is the only way to ensure that package removal # doesn't leave config file remnants, but may prove very confusing to users, # who will most likely expect the /etc copies to be authoritative and # persistent. #if [ -s /etc/shadowfiles ]; then # ( # cd /etc # sed -e "s/'/'\"'\"'/g" -e "s/^/rm -f '/" -e "s/\$/'/" shadowfiles | sh # ) #fi # Since packages installed in /usr and /usr/local can't directly own files in # /etc, we will non-destructively merge /usr/etc and /usr/local/etc into /etc. # If the root filesystem is persistent or has a persistent layer, pre-existing # copies in /etc will supercede the installation defaults in /usr[/etc]. # Otherwise, changes will be lost when the system is rebooted, and permanent # changes can only occur by modifiying the /usr/[local/]etc master copies. for PKG_ROOT in /usr /usr/local; do if [ -d $PKG_ROOT/etc ]; then ( cd $PKG_ROOT/etc find . -type f -print find . -print | cpio -d -p /etc 2>/dev/null ) fi done > /etc/shadowfiles # Initialise optional packages. # # Rather than executing rc.d files (which would have significant fork and exec # overheads), we source them and run the functions and/or aliases they define. # This is fast, but also fragile, because a syntax error in any rc.d file will # kill this script. On a persistent root filesystem, we have no way of knowing # whether or not configure actions have already occurred, so the rc.d scripts # must be "replay-safe" and should avoid unnecessary reconfiguration. ls /etc/rc.d | while read SVC; do . /etc/rc.d/$SVC eval ${SVC}_configure logger -t 'rc' -p daemon.info "$SVC configured" eval ${SVC}_start logger -t 'rc' -p daemon.info "$SVC started" done # Display an active interface summary just before the login prompt appears, so # that the IP address(es) in use remain visible on the console as long as # possible. ifconfig | awk 'BEGIN {i=""} $0 !~ /^[[:blank:]]/ && $0 != "" {i=$1} $2 ~ /^addr:/ {print i; print $0}' [ "$HAVE_SPLASH" ] && echo 'show 65535' >>/proc/splash
http://dietpc.org/downloads/source/common/diet-pc/initscript/etc/rc
2/26/2016
Audio-ALSA Playback & Capture Flow
1. ALSA의 기본 API
DM368은 TI에서 제공하는 Audio Guide는 없지만 구조는 거의 동일하다.
TI 제공하는 Audio는 기본 구조는 동일하지만, CPU에따라 EVM에 따라 조금씩 다르다.
하지만, OMAP인 경우 기본구조와 다르게 Audio 구조가 복잡하지만, 요즘은 거의 다 ALSA로 기반으로 하므로 아래와 같이 ALSA의 API들을 알아두록하자.
관련내용출처
DM368은 TI에서 제공하는 Audio Guide는 없지만 구조는 거의 동일하다.
TI 제공하는 Audio는 기본 구조는 동일하지만, CPU에따라 EVM에 따라 조금씩 다르다.
하지만, OMAP인 경우 기본구조와 다르게 Audio 구조가 복잡하지만, 요즘은 거의 다 ALSA로 기반으로 하므로 아래와 같이 ALSA의 API들을 알아두록하자.
- Audio 관련 부분 전체 Index
TI에서 제공해주는 Audio 관련 ALSA Guide로 현재 AM38xxx 와 DM84xx 를 위해서 변경사항이 있는지 확인만 하자
- ALSA Common API
관련 세부내용들은 생략하도록 하겠다.
ALSA를 이용하여 기본적으로 Playback하는 flow로 그리 어렵지 않으며 거의 다른 일반 Linux System Call과 거의 유사하다.
Name | Description |
---|---|
snd_pcm_open | Opens a PCM stream |
snd_pcm_close | Closes a previously opened PCM stream |
snd_pcm_hw_params_any | Fill params with a full configuration space for a PCM |
snd_pcm_hw_params_test_ < | Test the availability of important parameters like number of channels, sample rate etc. For e.g. snd_pcm_hw_params_test_format, snd_pcm_hw_params_test_rate etc. |
snd_pcm_hw_params_set_ < | Set the different configuration parameters. For e.g. snd_pcm_hw_params_set_format, snd_pcm_hw_params_set_rate etc. |
snd_pcm_hw_params | Install one PCM hardware configuration chosen from a configuration space |
snd_pcm_writei | Write interleaved frames to a PCM |
snd_pcm_readi | Read interleaved frames from a PCM |
snd_pcm_prepare | Prepare PCM for use |
snd_pcm_drop | Stop a PCM dropping pending frames |
snd_pcm_drain | Stop a PCM preserving pending frames |
아래의 ALSA의 Playback or Capture도 간단하게 짜기 싫다면, ALSA Tool을 간단하게 이용하도록하자.
1.1 ALSA의 PLAYBACK FLOW
- Playback Mode로 Open
- hw parameter 관련설정 (format/acess type/ sample rate/ channel )
- write로 재생시작
1.2 ALSA 의 CAPTURE FLOW
상위와 동일
- Capture Mode로 Open
- hw parameter 관련설정 (format/acess type/ sample rate/ channel )
- read로 녹음시작
관련내용출처
2/25/2016
Linux Network 설정
1. Linux Network 설정
이부분의 동작방식은 다시 boot script 부분을 보면 동작하는 방식을 이해가능
http://dis.um.es/~lopezquesada/documentos/IES_1213/SAD/curso/UT8/interfaces.pdf
http://www.cyberciti.biz/faq/setting-up-an-network-interfaces-file/
이부분의 동작방식은 다시 boot script 부분을 보면 동작하는 방식을 이해가능
- /etc/network/interfaces 설정의 예제
http://dis.um.es/~lopezquesada/documentos/IES_1213/SAD/curso/UT8/interfaces.pdf
http://www.cyberciti.biz/faq/setting-up-an-network-interfaces-file/
- 나의 Network 설정 (/etc/network/interfaces)
# Wired or wireless interfaces auto eth0 iface eth0 inet dhcp pre-up /bin/grep -v -e "ip=[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+" /proc/cmdline > /dev/null
$ cat /etc/network/interfaces # /etc/network/interfaces -- configuration file for ifup(8), ifdown(8) # The loopback interface auto lo iface lo inet loopback # Wireless interfaces # # Example of an unencrypted (no WEP or WPA) wireless connection # that connects to any available access point: # iface wlan0 inet dhcp wireless_mode managed wireless_essid any # # # Same as above but locked to a specific access point: # #iface wlan0 inet dhcp # wireless_mode managed # wireless-essid some-essid # # A WEP encrypted connection locked to a specific access point: # #iface wlan0 inet dhcp # wireless-essid some-essid # wireless-key s:My-PlainText-Password # wireless-mode managed # # A WPA1 or WPA2 encrypted connection locked to a specific access point. # This is the best option for non-roaming, single-network usage. # Note that your card may require a firmware update to use WPA. # Some distributions install a temporary volatile firmware update on ifup. # #iface wlan0 inet dhcp # wpa-essid some-essid # wpa-psk My-PlainText-Password # # A WPA1 or WPA2 encrypted connection using an external configuration file # for wpa-supplicant. This is the way to go if you need to configure multiple # networks with different keys and / or WPA settings and roaming support. # # iface wlan0 inet dhcp # wpa-conf /etc/wpa_supplicant.conf # wpa-driver hostap iface atml0 inet dhcp # Wired or wireless interfaces auto eth0 iface eth0 inet static pre-up /bin/grep -v -e "ip=[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+" /proc/cmdline > /dev/null iface eth1 inet dhcp # Ethernet/RNDIS gadget (g_ether) # ... or on host side, usbnet and random hwaddr iface usb0 inet static address 192.168.0.202 netmask 255.255.255.0 network 192.168.0.0 gateway 192.168.0.200 # Zaurus 2.4 Lineo net_fd; obsolete iface usbd0 inet static address 192.168.129.201 netmask 255.255.255.0 network 192.168.129.0 gateway 192.168.129.200 # iPAQ 2.4 mach-sa1100/usb-eth # (192.168.0.202 is the iPAQ's IP, 192.168.0.200 is the host's IP) iface usbf inet static address 192.168.0.202 netmask 255.255.255.0 network 192.168.0.0 gateway 192.168.0.200 # Bluetooth networking iface bnep0 inet dhcp
2/22/2016
Audio-ALSA SOC Framework (Kernel)
1. ALSA KERNEL Driver 전체구성
아래는 DM368 IPNC의 기준으로 보겠으며 다른 SoC로 가면 전체구조가 변경이 될 수도 있겠지만,
아래는 DM368 IPNC의 기준으로 보겠으며 다른 SoC로 가면 전체구조가 변경이 될 수도 있겠지만,
거의 근본적으로 구성은 AP/SoC의 관련 Driver 만들어서 ALSA Interface에 맞게 연결하여 동작하는 구조가 비슷하므로, 관련부분을 알아보도록하자.
http://processors.wiki.ti.com/index.php/Processor_SDK_Linux_Audio
2. ALSA의 SOC 기본 Driver 구조
DM368의 SOC를 세부적으로 본다며, 아래와 같으며, 각 설명 Driver의 구성은 다음과 같다.
2.1 Machine Driver
TI-SOC의 구성 , 아래와 같이 Machine Driver가 기본설정하고 , Platform과 Codec을 연결을 해준다.
정확히 cpu_dai와 codec_dai를 mapping을 하여 동작한다.
2.2 Platform Driver
TI에서 제공하는 Audio Driver McBSP or McASP 이며 이는 EDMA와 연결하여 동작한다.
그리고, 아래와 같이 PCM Driver와 연동이 되어 동작이 된다.
APP에서 PCM을 OPEN할 경우부터 기본설정되는 부분이 아래에 다 들어가 있다.
McBSP가 HW Codec과 연결되어 실질적인 역할하며, Interface는 I2S이지만, 다른 것으로 변경가능하다 (DSP Mode)
2.3 HW Codec Driver
Codec Driver는 구조가 거의 비슷하며, I2C Driver로 Codec을 Control 하게되어 각 설정을 변경하고, 등록을 하는 것이다.
이는 soc_dai를 등록하여 동작하게 한다.
Codec를 동작하게 하기위해서는 미리 I2C Device를 등록을 해야 동작이 가능하다.
(Audio-ALSA SOC Codec Driver 참조)
http://processors.wiki.ti.com/index.php/AM335x_Audio_Driver's_Guide
http://processors.wiki.ti.com/index.php/DM81xx_AM38xx_Audio_Driver_User_Guide
3. ALSA Card 등록 및 확인
DM368인 경우, TLVAIC3x 코덱을 사용을 하면, 2개의 McBSP Driver의 충돌로 인하여 제대로 등록이 되지 않는다.
이중 davinci-i2s.c 선택하여 사용함
User에서는 ALSA만 보면 되니 복잡하지 않지만, Driver 개발자에서는 제법 복잡한 구조이다.
OSS 와 ALSA 전체구조 및 ALSA 설명
TI ALSA Codec Driver 세부구성파악
- 각 디렉토리 구성
sound sound/core/ sound/soc/codecs sound/soc/davinci sound/soc
- 각 디렉토리의 사용되어지는 파일구성
./sound/core/pcm_lib.o ./sound/core/snd-pcm.o ./sound/core/init.o ./sound/core/memory.o ./sound/core/jack.o ./sound/core/sound.o ./sound/core/timer.o ./sound/core/pcm.o ./sound/core/pcm_timer.o ./sound/core/device.o ./sound/core/control.o ./sound/core/pcm_memory.o ./sound/core/misc.o ./sound/core/snd-page-alloc.o ./sound/core/info.o ./sound/core/snd-timer.o ./sound/core/pcm_misc.o ./sound/core/snd.o ./sound/core/memalloc.o ./sound/core/pcm_native.o ./sound/soc/soc-dapm.o ./sound/soc/soc-utils.o ./sound/soc/codecs/tlv320aic3x.o ./sound/soc/codecs/snd-soc-tlv320aic3x.o ./sound/soc/davinci/snd-soc-davinci.o ./sound/soc/davinci/davinci-evm.o ./sound/soc/davinci/davinci-i2s.o ./sound/soc/davinci/davinci-pcm.o ./sound/soc/davinci/snd-soc-davinci-i2s.o ./sound/soc/davinci/snd-soc-evm.o ./sound/soc/soc-core.o ./sound/soc/snd-soc-core.o ./sound/soc/soc-cache.o ./sound/soc/soc-jack.o ./sound/soundcore.o ./sound/sound_core.o ./sound/last.o
- TI에서 제공하는 Audio 관련 부분 설명
http://processors.wiki.ti.com/index.php/Processor_SDK_Linux_Audio
2. ALSA의 SOC 기본 Driver 구조
DM368의 SOC를 세부적으로 본다며, 아래와 같으며, 각 설명 Driver의 구성은 다음과 같다.
- Codec Driver : sound/soc/codecs/tlv320aic3x.c
- Platform Driver: sound/soc/davinci/davinci-i2s.c
- Machine Driver: sound/soc/davinci/davinci-evm.c
- SOC의 기본구조 설명
2.1 Machine Driver
TI-SOC의 구성 , 아래와 같이 Machine Driver가 기본설정하고 , Platform과 Codec을 연결을 해준다.
정확히 cpu_dai와 codec_dai를 mapping을 하여 동작한다.
$ vi sound/soc/davinci/davinci-evm.c #define AUDIO_FORMAT ( SND_SOC_DAIFMT_DSP_A | \ SND_SOC_DAIFMT_CBM_CFM | \ SND_SOC_DAIFMT_IB_NF) static struct snd_soc_dai_link dm365_evm_dai = { #ifdef CONFIG_SND_DM365_AIC3X_CODEC .name = "TLV320AIC3X", .stream_name = "AIC3X", .cpu_dai_name = "davinci-mcbsp", // CPU에서 사용하는 Audio Driver name , sound/soc/davinci/davinci-i2s.c .codec_dai_name = "tlv320aic3x-hifi", // CODEC에서 등록한 SOC DAI 이름 sound/soc/codecs/tlv320aic3x.c .init = evm_aic3x_init, .codec_name = "tlv320aic3x-codec.1-0018", .ops = &evm_ops, #elif defined(CONFIG_SND_DM365_VOICE_CODEC) .name = "Voice Codec - CQ93VC", .stream_name = "CQ93", .cpu_dai_name = "davinci-vcif", .codec_dai_name = "cq93vc-hifi", .codec_name = "cq93vc-codec", #endif .platform_name = "davinci-pcm-audio", // sound/soc/davinci/davinci-pcm.c ( platform driver ) }; /* davinci dm365 evm audio machine driver */ static struct snd_soc_card dm365_snd_soc_card_evm = { // SOC Card 등록 .name = "DaVinci DM365 EVM", .dai_link = &dm365_evm_dai, .num_links = 1, }; static int __init evm_init(void) { ....... } else if (machine_is_davinci_dm365_evm() || machine_is_davinci_dm365_ipnc() || machine_is_davinci_dm368_ipnc()) { evm_snd_dev_data = &dm365_snd_soc_card_evm; index = 0; } evm_snd_device = platform_device_alloc("soc-audio", index); ///sound/soc/soc-core.c 와 연결 if (!evm_snd_device) return -ENOMEM; platform_set_drvdata(evm_snd_device, evm_snd_dev_data); ret = platform_device_add(evm_snd_device); if (ret) platform_device_put(evm_snd_device); .... } module_init(evm_init); // module init 하게 되면 아래 순서 soc_probe -> snd_soc_register_card -> snd_soc_instantiate_cards -> snd_soc_instantiate_card(struct snd_soc_card *card)
- 아래에서 Kernel Log에서 확인 가능
ALSA device list: #0: DaVinci DM365 EVM
2.2 Platform Driver
TI에서 제공하는 Audio Driver McBSP or McASP 이며 이는 EDMA와 연결하여 동작한다.
그리고, 아래와 같이 PCM Driver와 연동이 되어 동작이 된다.
- PCM Driver
APP에서 PCM을 OPEN할 경우부터 기본설정되는 부분이 아래에 다 들어가 있다.
$ vi ./sound/soc/davinci/davinci-pcm.c // PCM Driver로 File 정보를 여기서 처리 그리고, EDMA 처리 등을 담당. static struct snd_pcm_hardware pcm_hardware_playback = { // ALSA의 기본 Playback 관련설정 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), .formats = (SNDRV_PCM_FMTBIT_S16_LE), .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), .formats = (SNDRV_PCM_FMTBIT_S16_LE), .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_KNOT), .rate_min = 8000, .rate_max = 96000, .channels_min = 2, .channels_max = 2, .buffer_bytes_max = 128 * 1024, .period_bytes_min = 32, .period_bytes_max = 8 * 1024, .periods_min = 16, .periods_max = 255, .fifo_size = 0, }; static struct snd_pcm_hardware pcm_hardware_capture = { // ALSA의 기본 Capture 관련설정 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE), .formats = (SNDRV_PCM_FMTBIT_S16_LE), .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_KNOT), .rate_min = 8000, .rate_max = 96000, .channels_min = 2, .channels_max = 2, .buffer_bytes_max = 128 * 1024, .period_bytes_min = 32, .period_bytes_max = 8 * 1024, .periods_min = 16, .periods_max = 255, .fifo_size = 0, }; /* PCM 기본 동작 Driver , PCM OPEN시, HW_PARAM 정보, TRIGGER, 이는 곳 EDMA와 연결을 시킨다. */ static struct snd_pcm_ops davinci_pcm_ops = { .open = davinci_pcm_open, .close = davinci_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = davinci_pcm_hw_params, //HW_PARAM 설정 , ALSA APP에 호출될 때 호출 . .hw_free = davinci_pcm_hw_free, .prepare = davinci_pcm_prepare, // TI EDMA 준비 .trigger = davinci_pcm_trigger, // TI EDMA Control .pointer = davinci_pcm_pointer, .mmap = davinci_pcm_mmap, // DMA 관련 MMAP }; static struct snd_soc_platform_driver davinci_soc_platform = { .ops = &davinci_pcm_ops, .pcm_new = davinci_pcm_new, .pcm_free = davinci_pcm_free, }; static int __devinit davinci_soc_platform_probe(struct platform_device *pdev) { return snd_soc_register_platform(&pdev->dev, &davinci_soc_platform); } static struct platform_driver davinci_pcm_driver = { .driver = { .name = "davinci-pcm-audio", .owner = THIS_MODULE, }, .probe = davinci_soc_platform_probe, .remove = __devexit_p(davinci_soc_platform_remove), };
- CPU AUDIO Driver
McBSP가 HW Codec과 연결되어 실질적인 역할하며, Interface는 I2S이지만, 다른 것으로 변경가능하다 (DSP Mode)
$ vi ./sound/soc/davinci/davinci-i2s.c //MCBSP의 Main Controller 로, 실제 CPU Dai에 연결된다. static struct snd_soc_dai_ops davinci_i2s_dai_ops = { .startup = davinci_i2s_startup, .shutdown = davinci_i2s_shutdown, .prepare = davinci_i2s_prepare, .trigger = davinci_i2s_trigger, .hw_params = davinci_i2s_hw_params, // HW_PARAM 설정 .set_fmt = davinci_i2s_set_dai_fmt, .set_clkdiv = davinci_i2s_dai_set_clkdiv, }; static struct snd_soc_dai_driver davinci_i2s_dai = { // Capture/Playback I2S Interface의 동작범위 와 Format 정의 .playback = { .channels_min = 2, .channels_max = 2, .rates = DAVINCI_I2S_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, .capture = { .channels_min = 2, .channels_max = 2, .rates = DAVINCI_I2S_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, .ops = &davinci_i2s_dai_ops, }; static int davinci_i2s_probe(struct platform_device *pdev) { ..... EDMA 관련 초기화 ret = snd_soc_register_dai(&pdev->dev, &davinci_i2s_dai); if (ret != 0) goto err_free_mem; } static struct platform_driver davinci_mcbsp_driver = { .probe = davinci_i2s_probe, .remove = davinci_i2s_remove, .driver = { .name = "davinci-mcbsp", .owner = THIS_MODULE, }, }; static int __init davinci_i2s_init(void) { return platform_driver_register(&davinci_mcbsp_driver); } module_init(davinci_i2s_init);
2.3 HW Codec Driver
Codec Driver는 구조가 거의 비슷하며, I2C Driver로 Codec을 Control 하게되어 각 설정을 변경하고, 등록을 하는 것이다.
이는 soc_dai를 등록하여 동작하게 한다.
Codec를 동작하게 하기위해서는 미리 I2C Device를 등록을 해야 동작이 가능하다.
(Audio-ALSA SOC Codec Driver 참조)
$ vi ./sound/soc/codecs/tlv320aic3x.c // Codec Driver 현재 AIC3100으로 변경 중. 서로 호환이 되지 않음
static struct snd_soc_dai_driver aic3x_dai = {
.name = "tlv320aic3x-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
.channels_max = 2,
.rates = AIC3X_RATES,
.formats = AIC3X_FORMATS,},
.capture = {
.stream_name = "Capture",
.channels_min = 1,
.channels_max = 2,
.rates = AIC3X_RATES,
.formats = AIC3X_FORMATS,},
.ops = &aic3x_dai_ops,
};
static int aic3x_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
......
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_aic3x, &aic3x_dai, 1);
}
static struct i2c_driver aic3x_i2c_driver = {
.driver = {
.name = "tlv320aic3x-codec",
.owner = THIS_MODULE,
},
.probe = aic3x_i2c_probe,
.remove = aic3x_i2c_remove,
.id_table = aic3x_i2c_id,
};
static inline void aic3x_i2c_init(void)
{
int ret;
ret = i2c_add_driver(&aic3x_i2c_driver);
if (ret) printk(KERN_ERR "%s: error regsitering i2c driver, %d\n", __func__, ret);
}
static int __init aic3x_modinit(void)
{
int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&aic3x_i2c_driver);
if (ret != 0) {
printk(KERN_ERR "Failed to register TLV320AIC3x I2C driver: %d\n",
ret);
}
#endif
return ret;
}
module_init(aic3x_modinit);
- AM335x 와 DM81xx Driver Guide
http://processors.wiki.ti.com/index.php/AM335x_Audio_Driver's_Guide
http://processors.wiki.ti.com/index.php/DM81xx_AM38xx_Audio_Driver_User_Guide
3. ALSA Card 등록 및 확인
- Kernel Log 확인
DM368인 경우, TLVAIC3x 코덱을 사용을 하면, 2개의 McBSP Driver의 충돌로 인하여 제대로 등록이 되지 않는다.
ALSA device list: #0: DaVinci DM365 EVM
- ALSA Card 등록확인
$ vi sound/soc/davinci/davinci-evm.c /* davinci dm365 evm audio machine driver */ static struct snd_soc_card dm365_snd_soc_card_evm = { .name = "DaVinci DM365 EVM", .dai_link = &dm365_evm_dai, .num_links = 1, }; static int __init evm_init(void) { ......... } else if (machine_is_davinci_dm365_evm() || machine_is_davinci_dm365_ipnc() || machine_is_davinci_dm368_ipnc()) { evm_snd_dev_data = &dm365_snd_soc_card_evm; index = 0; } evm_snd_device = platform_device_alloc("soc-audio", index); if (!evm_snd_device) return -ENOMEM; platform_set_drvdata(evm_snd_device, evm_snd_dev_data); ret = platform_device_add(evm_snd_device); if (ret) platform_device_put(evm_snd_device); ........ } module_init(evm_init); module_exit(evm_exit);
- ALSA AUDIO Driver 등록 확인
이중 davinci-i2s.c 선택하여 사용함
- ./sound/soc/davinci/davinci-i2s.c // 이 McBSP는 일반 Codec 사용
- ./arch/arm/mach-davinci/mcbsp.c // 이 McBSP는 Voice Codec을 사용시 사용
$ vi ./arch/arm/mach-davinci/board-dm368-ipnc.c
static struct snd_platform_data dm365_evm_snd_data = {
.asp_chan_q = EVENTQ_3,
};
$ vi ./arch/arm/mach-davinci/dm365.c
static struct resource dm365_asp_resources[] = {
{
.start = DAVINCI_DM365_ASP0_BASE,
.end = DAVINCI_DM365_ASP0_BASE + SZ_8K - 1,
.flags = IORESOURCE_MEM,
},
{
.start = DAVINCI_DMA_ASP0_TX,
.end = DAVINCI_DMA_ASP0_TX,
.flags = IORESOURCE_DMA,
},
{
.start = DAVINCI_DMA_ASP0_RX,
.end = DAVINCI_DMA_ASP0_RX,
.flags = IORESOURCE_DMA,
},
};
static struct platform_device dm365_asp_device = {
.name = "davinci-mcbsp", // 현재 충돌 중. McBSP Driver 가 두 개
.id = -1,
.num_resources = ARRAY_SIZE(dm365_asp_resources),
.resource = dm365_asp_resources,
};
platform_device_register(&dm365_asp_device);
2/21/2016
Eclipse Neon (C/C++) CDT 설치 (개발환경구성-2)
1. Eclipse Neon CDT for Window 설치
이제 최신 Version인 Eclipse Neon을 Window에 설치를 해보자.
Eclipse를 설치 후 본인의 Window의 Program 제거에 등록이 되지는 않는다.
그러므로 관련 PATH를 알아두고 추후 삭제할일 존재한다면 이 PATH를 제거하자
현재 Java로 개발을 진행하지 않기 때문에 Eclipse C/C++ Version 만 설치하기로 결정.
Neon은 Eclipse의 Android 처럼 Version 과 같이 이름이 변경되는 Project 명이라 생각하면되겠다.
https://www.eclipse.org/downloads/
https://eclipse.org/cdt/
1.1 Eclipse Neon 설치시, Java JDK 설치
WIN 64bit : jdk-7u79-windows-x64.exe Download 및 설치
저의문제는 JDK Version 문제 였으나, 아래와 같이 RAM Size 문제일 가능성도 있을 것 같다
-Xms256m
-Xmx1024m
http://dkatlf900.tistory.com/93
1.2 Eclipse CDT 설치 후 화면확인
크로스 컴파일러를 설치가 되어 있어야 제대로된 동작이 가능한 것 같다.
추가설치를 원한다면, Help->Eclipse Market place 에서 설치가능
2. Eclipse 확장
Help->Eclipse Marketplace 로 가면 추가적인 패키지들을 설치를 할수 있다.
이 부분은 자주 확인을 해야하며, 수시로 적용되는 패키지를 확인하자
CCS의 Eclipse 확장
https://ahyuo79.blogspot.com/search/label/IDE-CCSv6
https://ahyuo79.blogspot.com/search/label/IDE-Eclipse-CDT
요즘 내가 Python을 사용하다보니, 관련부분 기능 적어놓는다.
Python을 위해 추가 설치
PyDev - Python IDE for Eclipse
http://kaizen8501.tistory.com/16
http://egloos.zum.com/anster/v/2170490
3. Linux용 Eclipse Neon CDT 설치
설치만 해보고 이를 이용하여 빌드를 하지 않았으며, 큰 문제가 없던 걸로 기억한다.
이 방법으로 잘 설정한다면, 모든 작업을 Eclipse에서 가능하겠지만, Window에서 Virtual Box 안에서 Eclipse를 다시 실행하는 것이 싫다.
http://lky1001.tistory.com/71
http://lky1001.tistory.com/68?category=525478
http://janaxelson.com/eclipse5.htm
이제 최신 Version인 Eclipse Neon을 Window에 설치를 해보자.
Eclipse를 설치 후 본인의 Window의 Program 제거에 등록이 되지는 않는다.
그러므로 관련 PATH를 알아두고 추후 삭제할일 존재한다면 이 PATH를 제거하자
현재 Java로 개발을 진행하지 않기 때문에 Eclipse C/C++ Version 만 설치하기로 결정.
Neon은 Eclipse의 Android 처럼 Version 과 같이 이름이 변경되는 Project 명이라 생각하면되겠다.
- Eclipse Neon Dowload
https://www.eclipse.org/downloads/
- Eclipse CDT Download
https://eclipse.org/cdt/
- 관련설치
1.1 Eclipse Neon 설치시, Java JDK 설치
WIN 64bit : jdk-7u79-windows-x64.exe Download 및 설치
- 설치후 문제사항
- 수정사항
저의문제는 JDK Version 문제 였으나, 아래와 같이 RAM Size 문제일 가능성도 있을 것 같다
-Xms256m
-Xmx1024m
http://dkatlf900.tistory.com/93
1.2 Eclipse CDT 설치 후 화면확인
크로스 컴파일러를 설치가 되어 있어야 제대로된 동작이 가능한 것 같다.
- Eclipse 설치 후 확장기능
추가설치를 원한다면, Help->Eclipse Market place 에서 설치가능
2. Eclipse 확장
Help->Eclipse Marketplace 로 가면 추가적인 패키지들을 설치를 할수 있다.
이 부분은 자주 확인을 해야하며, 수시로 적용되는 패키지를 확인하자
CCS의 Eclipse 확장
https://ahyuo79.blogspot.com/search/label/IDE-CCSv6
https://ahyuo79.blogspot.com/search/label/IDE-Eclipse-CDT
2.1 Eclipse Neon 추가 설치 (Python)
요즘 내가 Python을 사용하다보니, 관련부분 기능 적어놓는다.
Python을 위해 추가 설치
PyDev - Python IDE for Eclipse
http://kaizen8501.tistory.com/16
http://egloos.zum.com/anster/v/2170490
3. Linux용 Eclipse Neon CDT 설치
설치만 해보고 이를 이용하여 빌드를 하지 않았으며, 큰 문제가 없던 걸로 기억한다.
이 방법으로 잘 설정한다면, 모든 작업을 Eclipse에서 가능하겠지만, Window에서 Virtual Box 안에서 Eclipse를 다시 실행하는 것이 싫다.
http://lky1001.tistory.com/71
http://lky1001.tistory.com/68?category=525478
http://janaxelson.com/eclipse5.htm
2/20/2016
Cygwin 설치 및 Eclipse 을 위한 설정 (개발환경구성-1)
1. Window 용 Linux Package(Cygwin) 설치
Cygwin에 크로스 컴파일러로 Cygwin와 MinGW 존재하며, 이를 설치를 하여 이곳에 설치를 해도 무방하다
윈도우에서 다양한 Linux Tool Package를 사용이 가능하며, 크로스 컴파일러로도 사용하기때문에 이를 설치한다.
현재 나의 경우는 ssh를 이용하여 이클립스와 연동하여 사용하는 것이 주 목적이다.
상위 Cygwin에 MingGW도 포함
http://rinovation.tistory.com/2
https://www.eclipse.org/forums/index.php/t/1073505/
2. Cygwin 설치 및 재설치
Cygwin은 윈도우의 제어판에서 프로그램 제거를 할 수가 없다.
설치시 이부분을 정확하게 인지하고 있어야한다.
setup-x86_64.exe 을 다시 실행하여 필요한 Package를 추가하여 재설치가 가능하다
상위 그림에서 패키지를 제공해주는 사이트는 많으므로, 사이트를 아무거나 선택하자
상위 상단 좌측의 View를 Category로 변경 후
Devel에서 필요한 것들이 있다면 설치 Cross Compiler (Cygwin or Mingw64)
Net->openssh 및 ssh library 설치 ( 소스는 제외)
설치된 Package를 실행
2.1 Cygwin 제거방법
위에서 설명했듯이 Cygwin은 제어판의 프로그램에 나오지 않아서 직접삭제를 해야한다.
그리고, Cygwin에서 사용하고 있는 파일과 데몬이 있다고 중지를 하고 삭제를 진행을 해야한다.
regedit를 이용하여 레지스트리를 편집을 하고, 가능하면 편집의 찾기를 이용하여 찾자
Cygwin or Cygnus Solutions
아래의 Cygnus Solutions에서 Cygwin으로 삭제
http://infoarts.tistory.com/25
3. Cygwin 명령어와 Window 공유 (Eclipse 와 공유)
https://www.howtogeek.com/howto/41382/how-to-use-linux-commands-in-windows-with-cygwin/
4. Cygwin 설치 후 SSH Client 설정 (중요)
외부에 Linux or Unix SSH Server가 존재하며 이는 Build Server 로 동작할 것이다.
Window에서는 상위에서 Cygwin을 이용하여 Openssh가 설치된 상태이며, Cygwin Terminal or CMD 명령으로 ssh를 실행이 가능하도록 설정한다.
Window에서 SSH Server에 매번 Password 입력없이 동작하게 하려고 목적이다.
http://marobiana.tistory.com/53
https://m.blog.naver.com/PostView.nhn?blogId=ccm&logNo=60185667224&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F
http://www.skybert.net/windows/creating-an-ssh-key-on-windows/
Cygwin에 크로스 컴파일러로 Cygwin와 MinGW 존재하며, 이를 설치를 하여 이곳에 설치를 해도 무방하다
윈도우에서 다양한 Linux Tool Package를 사용이 가능하며, 크로스 컴파일러로도 사용하기때문에 이를 설치한다.
현재 나의 경우는 ssh를 이용하여 이클립스와 연동하여 사용하는 것이 주 목적이다.
- Download (Cygwin)설치
상위 Cygwin에 MingGW도 포함
- MingGW 참고
http://rinovation.tistory.com/2
https://www.eclipse.org/forums/index.php/t/1073505/
2. Cygwin 설치 및 재설치
Cygwin은 윈도우의 제어판에서 프로그램 제거를 할 수가 없다.
설치시 이부분을 정확하게 인지하고 있어야한다.
setup-x86_64.exe 을 다시 실행하여 필요한 Package를 추가하여 재설치가 가능하다
- Cygwin 설치방법 및 재설치
상위 그림에서 패키지를 제공해주는 사이트는 많으므로, 사이트를 아무거나 선택하자
상위 상단 좌측의 View를 Category로 변경 후
Devel에서 필요한 것들이 있다면 설치 Cross Compiler (Cygwin or Mingw64)
Net->openssh 및 ssh library 설치 ( 소스는 제외)
- Cygwin 설치후 SSH 동작확인
설치된 Package를 실행
2.1 Cygwin 제거방법
위에서 설명했듯이 Cygwin은 제어판의 프로그램에 나오지 않아서 직접삭제를 해야한다.
그리고, Cygwin에서 사용하고 있는 파일과 데몬이 있다고 중지를 하고 삭제를 진행을 해야한다.
regedit를 이용하여 레지스트리를 편집을 하고, 가능하면 편집의 찾기를 이용하여 찾자
Cygwin or Cygnus Solutions
아래의 Cygnus Solutions에서 Cygwin으로 삭제
- HKEY_LOCAL_MACHINE\SOFTWARE\Cygwin
- HKEY_CURRENT_USER\Software\Cygwin
- HKEY_USERS\.Default\Software\Cygwin (현재 없음)
http://infoarts.tistory.com/25
3. Cygwin 명령어와 Window 공유 (Eclipse 와 공유)
- Window Key + Pause/Break
- 고급시스템 설정 선택 (좌측메뉴)
- 시스템속성창 의 고급->환경변수 선택 (맨아래에 위치)
- 환경변수창이 아래의 시스템변수 PATH 선택
- PATH 에 ;C:\cygwin64\bin 추가
https://www.howtogeek.com/howto/41382/how-to-use-linux-commands-in-windows-with-cygwin/
4. Cygwin 설치 후 SSH Client 설정 (중요)
외부에 Linux or Unix SSH Server가 존재하며 이는 Build Server 로 동작할 것이다.
Window에서는 상위에서 Cygwin을 이용하여 Openssh가 설치된 상태이며, Cygwin Terminal or CMD 명령으로 ssh를 실행이 가능하도록 설정한다.
Window에서 SSH Server에 매번 Password 입력없이 동작하게 하려고 목적이다.
- SSH의 Key 생성
$ ssh-keygen -t rsa // 함께 엔터 id_rsa 생성 $ ls .ssh // id_rsa 생성확인
- Target Server 에 생성된 Key 복사
$ ssh-copy-id jhlee@192.168.1.100 // SSH Server (ID: jhlee )
- ID입력만으로 Password 없이 로그인 가능
$ ssh jhlee@192.168.1.100 // 이제 암호 없이 SSH Server 접속가능 $ ls .ssh id_rsa id_rsa.pub known_hosts
http://marobiana.tistory.com/53
https://m.blog.naver.com/PostView.nhn?blogId=ccm&logNo=60185667224&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F
http://www.skybert.net/windows/creating-an-ssh-key-on-windows/
2/19/2016
Eclipse Neon CDT (C/C++) 기본사용 및 원격 빌드
1. Project 생성 전 확인사항
Project 생성은 기존 소스가 존재하여도 이를 Project를 생성하여 각 기존소스 or New Source를 위해 관련 설정 및
소스분석을 위한 Index를 생성을 한다.
현재 Linux Build Server와 같이 구성할 것이므로, 아래의 참조내용을 이해하고 사용하자.
상위구성이 되었다면, Build Server와 Window와 연결 Interface를 Network Driver를 만들어주어 쉽게 접근하도록 하자.
https://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.ptp.rdt.doc.user%2Fhtml%2Fgettingstarted%2Fcreating_a_remote_project.html
1.1 Project 기본생성 및 제거
생성과 동시에 우측 하단에 Refreshing Working Space라고 하며 진행이 되며 보통 Index도 함께 생성이 된다.
2. Eclipse의 설정
Eclipse의 설정들은 아래와 같이 구성이 되며, Project Properties의 경우는 세부 설정이며 Project 마다 변경이 될 수 있다.
하지만 Window->Preference의 경우는 전체 설정이라고 생각하면 될 것이다.
2.1 Project의 Properties
이제 생성된 Project의 세부설정을 변경하고 싶다면 아래와 같이 둘 중 하나만 하면된다.
Window의 Eclipse에서 SSH를 통하여 Linux Build Server에서 Source를 Build를 하기위해서 다음과 같은 설정필요
3.1 Make Target 생성
SSH 원격빌드를 하기 위해서 Make Target를 생성한다.
Window->Show View->Other 에서 Make Target 선택
or
아래 그림과 같이 Project Explorer 에서 Make Target 선택->Create or Build
상위에서 Make Target->Create or Build 선택
Make Targets->Add or Edit 선택 후 Modify Make Target 창 설정
Build Setting : 현재 Stop on first build error만 설정했지만 (원격이므로 설정의미가 없음)
Make Target을 이용하여 Eclipse에서 Console로 쉽게 빌드 확인 (SSH 원격빌드)
에러시 한글문제 깨지는 문제발생 (UTF8로 설정하는 방법없음)
https://m.blog.naver.com/PostView.nhn?blogId=ccm&logNo=60185667224&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F
https://help.eclipse.org/mars/index.jsp?topic=%2Forg.eclipse.cdt.doc.user%2Ftasks%2Fcdt_t_cbuild_pref.htm
3.2 Build Server의 설정 및 Shell Script
Window에서 SSH Server로 접속하여 Build를 한번에 해야 하기 때문에 기존에 있는 Makefile or Shell script를 이용하여 쉽게 동작하도록 작성하자.
아래의 예는 간단히 설정파일과 Makefile관련부분을 정리
4. Eciplse Neon의 편이성 설정
아래기능을 이용하여 창 분할 기능 및 Remote System 및 편의기능 설정
이것을 사용하는 목적은 순전히 ctags 기능때문이지만 이용할수 없다고 하니 별다른 도움이 되지 않을 것 같다.
http://zoningout.tistory.com/entry/eclipse%EC%97%90%EC%84%9C-vi-mode%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0-1
4.1 Remote System 이용
Eclipse에서 Build Server의 부분을 이용하는 것을 말하며 Remote System에서는 기본적으로 SSH Client가 제공이 된다.
위의 3가지 기능을 사용하면, Virtualbox의 Server와 편하게 SSH를 접속할 수 있을 뿐만 아니라,
SFTP를 이용하여 윈도우의 탐색기 기능처럼 사용이 가능하지만 기능이 제한적이다.
그래서, 가급적이면 SFTP하려고 한다.
참으로 좋은 개발 Tool이며 편한 것 같다.
현재 XShell을 사용을 하고 있지만, Eclipse도 꽤 괜찮은 것 같다고 생각이 들지만, XShell 보다 좀 불편해서 그냥 Xshell을 별도 사용중이다.
XShell 역시 위 두 기능을 제공하고 있다. (SSH 와 SFTP 기능 )
vi 편집기를 이용하는데, ssh를 이용하여 편하게 eclipse에서 편집이 가능하다.
다만 설정을 UTF-8로 변경을 해줘야 한다.
출처:
http://forum.falinux.com/zbxe/index.php?document_srl=791415&mid=lecture_tip
Project 생성은 기존 소스가 존재하여도 이를 Project를 생성하여 각 기존소스 or New Source를 위해 관련 설정 및
소스분석을 위한 Index를 생성을 한다.
현재 Linux Build Server와 같이 구성할 것이므로, 아래의 참조내용을 이해하고 사용하자.
- 빌드서버와 Eclipse 기본환경구성이해
- Eclipse CDT 설치 및 확장
- Window에 Linux Tool 설치
상위구성이 되었다면, Build Server와 Window와 연결 Interface를 Network Driver를 만들어주어 쉽게 접근하도록 하자.
https://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.ptp.rdt.doc.user%2Fhtml%2Fgettingstarted%2Fcreating_a_remote_project.html
- Project Explorer 창설정
- Window->Show View->Other 선택
- General->Project Explorer 설정
1.1 Project 기본생성 및 제거
- 프로젝트 생성 및 C/C++ Indexer 생성
기존 Linux Code를 찾아 이곳에 등록을 하고 Project를 새로 생성을 하자
- File->New->Project
- Makefile Project with Existing Code 선택
- None or Cross GCC 선택
생성과 동시에 우측 하단에 Refreshing Working Space라고 하며 진행이 되며 보통 Index도 함께 생성이 된다.
- 프로젝트 제거
2. Eclipse의 설정
Eclipse의 설정들은 아래와 같이 구성이 되며, Project Properties의 경우는 세부 설정이며 Project 마다 변경이 될 수 있다.
하지만 Window->Preference의 경우는 전체 설정이라고 생각하면 될 것이다.
- Window->Preferences
- Project의 Properties
2.1 Project의 Properties
이제 생성된 Project의 세부설정을 변경하고 싶다면 아래와 같이 둘 중 하나만 하면된다.
- Project->Properties 선택
- Project Explorer 창에서 Project 선택 후 우측 클릭 Properties 선택
만약 활성화가 되지 않았다면, 왼쪽 Project Explorer에서 Project를 선택을 하면 활성화가 된다.
UTF-8 / MS949
MS949가 없다면 Window->Preferences의 General 의 Workspace 부분을 한번살펴보자
다른부분은 한번 살펴보자
3. 원격 Build 설정 (Project Target) 설정- Resource 확인사항
UTF-8 / MS949
MS949가 없다면 Window->Preferences의 General 의 Workspace 부분을 한번살펴보자
다른부분은 한번 살펴보자
Window의 Eclipse에서 SSH를 통하여 Linux Build Server에서 Source를 Build를 하기위해서 다음과 같은 설정필요
- cygwin의 openssh 설치필요
- cygwin의 ssh 설정 필요 ( SSH 암호 없이 로그인이 가능하도록 설정)
- Window에 Linux Tool (Cygwin의 SSH기능 설치)
3.1 Make Target 생성
SSH 원격빌드를 하기 위해서 Make Target를 생성한다.
Window->Show View->Other 에서 Make Target 선택
or
아래 그림과 같이 Project Explorer 에서 Make Target 선택->Create or Build
상위에서 Make Target->Create or Build 선택
Make Targets->Add or Edit 선택 후 Modify Make Target 창 설정
- Modify Make Target 창 설정 (상위 좌측의 그림설정)
- Target Name: 이클립스에서 보기위한 Target Name (e.g uboot)
- Make Target: 실제 Makefile의 Target Name (Window의 Makefile을 아니므로, 사용안함)
- Build Command: SSH를 이용하여 원격빌드를 설정 (아래 참조)
ssh jhlee@192.168.1.100 'source ~/am335x/setAM335x; make -C ~/am335x/ti-processor-sdk-linux-am335x-evm-03.00.00.04 u-boot'
Build Setting : 현재 Stop on first build error만 설정했지만 (원격이므로 설정의미가 없음)
- Make Target 창 -> Build (원격빌드)
Make Target을 이용하여 Eclipse에서 Console로 쉽게 빌드 확인 (SSH 원격빌드)
에러시 한글문제 깨지는 문제발생 (UTF8로 설정하는 방법없음)
https://m.blog.naver.com/PostView.nhn?blogId=ccm&logNo=60185667224&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F
- Eclipse Console 관련설정
https://help.eclipse.org/mars/index.jsp?topic=%2Forg.eclipse.cdt.doc.user%2Ftasks%2Fcdt_t_cbuild_pref.htm
3.2 Build Server의 설정 및 Shell Script
Window에서 SSH Server로 접속하여 Build를 한번에 해야 하기 때문에 기존에 있는 Makefile or Shell script를 이용하여 쉽게 동작하도록 작성하자.
아래의 예는 간단히 설정파일과 Makefile관련부분을 정리
$ cat ~/am335x/setAM335x export ARCH=armv7-a export TI_SDK_PATH=/home/jhlee/am335x/ti-processor-sdk-linux-am335x-evm-03.00.00.05 export LINUX_DEVKIT_PATH=${TI_SDK_PATH}/linux-devkit export CROSS_COMPILE=${LINUX_DEVKIT_PATH}/sysroots/x86_64-arago-linux/usr/bin/arm-linux-gnueabihf- $ cd ~/am335x/ti-processor-sdk-linux-am335x-evm-03.00.00.04 $ vi Makefile linux: linux-dtbs @echo ================================= @echo Building the Linux Kernel @echo ================================= $(MAKE) -C $(LINUXKERNEL_INSTALL_DIR) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) $(DEFCONFIG) $(MAKE) -j $(MAKE_JOBS) -C $(LINUXKERNEL_INSTALL_DIR) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) zImage $(MAKE) -j $(MAKE_JOBS) -C $(LINUXKERNEL_INSTALL_DIR) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) modules ...... u-boot: linux-dtbs @echo =================================== @echo Building U-boot @echo =================================== $(MAKE) -j $(MAKE_JOBS) -C $(TI_SDK_PATH)/board-support/u-boot-* CROSS_COMPILE=$(CROSS_COMPILE) $(UBOOT_MACHINE) $(MAKE) -j $(MAKE_JOBS) -C $(TI_SDK_PATH)/board-support/u-boot-* CROSS_COMPILE=$(CROSS_COMPILE) DTC=$(LINUXKERNEL_INSTALL_DIR)/scripts/dtc/dtc
4. Eciplse Neon의 편이성 설정
아래기능을 이용하여 창 분할 기능 및 Remote System 및 편의기능 설정
- Window->Editor->Toggle Split Editor ( 화면분할)
- Window->Show View->Remote System
- Window->Preference ( 기타 모든 설정)
- VI관련 기능
이것을 사용하는 목적은 순전히 ctags 기능때문이지만 이용할수 없다고 하니 별다른 도움이 되지 않을 것 같다.
- Help->Install New Software
- http://vrapper.sourceforge.net/update-site/stable/
http://zoningout.tistory.com/entry/eclipse%EC%97%90%EC%84%9C-vi-mode%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0-1
4.1 Remote System 이용
Eclipse에서 Build Server의 부분을 이용하는 것을 말하며 Remote System에서는 기본적으로 SSH Client가 제공이 된다.
- SSH Client 기능
- SFTP Client 기능 (윈도우 탐색기 처럼 사용가능하나 불편함 )
- Local Files->Drivers 이용 (Samba로 Window에서 Network Driver로 연결)
위의 3가지 기능을 사용하면, Virtualbox의 Server와 편하게 SSH를 접속할 수 있을 뿐만 아니라,
SFTP를 이용하여 윈도우의 탐색기 기능처럼 사용이 가능하지만 기능이 제한적이다.
그래서, 가급적이면 SFTP하려고 한다.
참으로 좋은 개발 Tool이며 편한 것 같다.
현재 XShell을 사용을 하고 있지만, Eclipse도 꽤 괜찮은 것 같다고 생각이 들지만, XShell 보다 좀 불편해서 그냥 Xshell을 별도 사용중이다.
XShell 역시 위 두 기능을 제공하고 있다. (SSH 와 SFTP 기능 )
- Remote System 설정방법
- Window->Perspective->Open Perspective-> Others -> Remote Systems Explorer 선택
- 생성된 Remote System의 좌측의 맨위 아이콘 (Define a connection to remote system) or 마우스 우측 클릭 후, new->connection를 선택
- SSH Only 선택 후 본인의 SSH Server 관련 설정
- Remote System에서 new->connection 선택 ( 상위 1번동일 )
- SSH Only 설정 및 관련 설정 (상위 2번 동일)
- SSH를 설정하면, 자동으로 SFTP도 설정이 됨 (상위 3번 동일)
vi 편집기를 이용하는데, ssh를 이용하여 편하게 eclipse에서 편집이 가능하다.
다만 설정을 UTF-8로 변경을 해줘야 한다.
- SSH에서 한글깨짐문제
- Window>Preferences 선택
- General>Workspace 선택
- 아래메뉴의 OTHER를 선택하고 UTF-8과 UNIX 설정
http://forum.falinux.com/zbxe/index.php?document_srl=791415&mid=lecture_tip
2/17/2016
Kernel 과 Uboot Booting 문제
매번 느끼지는 것지만, 처음 Uboot와 Kernel이 Booting이 안되는 첫번째 에러는
MACHINE_TYPE에러인것 같다.
다양한 설정 방법이 존재한다.
MACHINE_TYPE에러인것 같다.
$ vi .config # # DaVinci Board Type # # CONFIG_MACH_DAVINCI_DM365_EVM is not set # CONFIG_MACH_DAVINCI_DM365_IPNC is not set CONFIG_MACH_DAVINCI_DM368_IPNC=y $ vi ./include/generated/mach-types.h #ifdef CONFIG_MACH_DAVINCI_DM368_IPNC # ifdef machine_arch_type # undef machine_arch_type # define machine_arch_type __machine_arch_type # else # define machine_arch_type MACH_TYPE_DAVINCI_DM368_IPNC # endif # define machine_is_davinci_dm368_ipnc() (machine_arch_type == MACH_TYPE_DAVINCI_DM368_IPNC) #else # define machine_is_davinci_dm368_ipnc() (0) #endif $ vi ./arch/arm/mach-davinci/board-dm368-ipnc.c MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM36x IPNC") .boot_params = (0x80000100), .map_io = dm365_evm_map_io, .init_irq = davinci_irq_init, .timer = &davinci_timer, .init_machine = dm368_evm_init, MACHINE_END
- Kernel 설정
다양한 설정 방법이 존재한다.
make menuconfig // 일반 설정 make xconfig (gconf tool 사용) , QT (KDE) based GUI Kernel config make gconfig (gkc tools ) GTK , GNOMEhttps://www.halolinux.us/fedora-7-reference/kernel-configuration-tools.html
2/16/2016
Audio-ALSA SOC Framework-Codec Driver ( Kernel)
1. Hardware 기본구성 및 설정
위 구성을 보면 AIC3x CODEC은 BCLK과 WCLK(Frame sync)를 제공하며, Data는 이 Frame Sync의 Timing에 맞추어 전송하고 받는다.
기본적인 통신은 Synchronous이며 설정에 따라 Interface의 방식은 변경되어 진다..
http://processors.wiki.ti.com/index.php/Sitara_Linux_Audio_Hardware_Overview
아래의 설정은 ALSA에서 설정하는 SOC 설정모드이며, Codec 입장에서 기술된다.
CODEC는 위와 같이 CLOCK과 Frame Sync(WCLK)을 제공을 한다.
그러므로, CODEC이 BCLK Master Frame Sync Master이므로, SND_SOC_DAIFMT_CBM_CFM 이다.
가장 일반적인게 I2S이며, DSP Mode A/B 혹은 AC97인데, Codec Chip이 지원되는 거에 따라 변경해서 사용하자.
Offset은 McBSP의 Data Delay에 같이 설정해야하며
Offset을 주느냐에 따라 DSP_B모드가 되며,NB_NF의 선택 BCLK과 WCLK의 극성선택이다.
2. I2C driver 기본확인사항
HW Codec의 I2C Driver는 거의 동일하며, 실제적인 Codec의 관련설정을 하는 것이므로, 사용시 반드시 Codec Datasheet와 함께 봐야한다.
2.1 Audio Codec 등록 확인
아래와 같이 기본 board에서 등록이 되어있는지 확인하고, Kernel config에서지원되는 것을 확인을 하자.
만약 지원이 되지 않는다면, 이제 Audio Codec Driver를 가져와서, 이를 Porting하자 .
아래와 같이 등록을 해야, 실제 Audio Codec Driver에서 발견가능하다.
보통 Codec Driver 들은 여러종류의 칩의 지원을 하므로, 아래와 같이 board에서 이름을 정확히 정해줘야한다.
현재 DM368에, AIC3100을 올려서 수정하고 있다.
A. DM368
B. DM355
아래와 같이, plaform_data에 argument를 넣어 전달이 가능하다.
그러면, i2c_probe할 때, struct i2c_client *i2c 에서 i2c->dev.platform_data 전달 받을 수 있다.
2.2 Audio Codec Driver 기본동작
AIC3x Driver 즉 HW Codec Driver 예제이며 구조는 다음과 같다.
3. Codec Porting 시 체크사항
- TI McASP 와 AIC3x HW Codec 의 연결사항
- BCLK (BIT CLOCK) : Codec Clock 제공 (Master)
- WCLK (WORD CLOCK) : Codec Frame Sync 제공 (Master)
- RX Data : RX Data (Encoding Data)
- TX Data : TX Data (Decoding Data )
위 구성을 보면 AIC3x CODEC은 BCLK과 WCLK(Frame sync)를 제공하며, Data는 이 Frame Sync의 Timing에 맞추어 전송하고 받는다.
기본적인 통신은 Synchronous이며 설정에 따라 Interface의 방식은 변경되어 진다..
http://processors.wiki.ti.com/index.php/Sitara_Linux_Audio_Hardware_Overview
1.1 ALSA SOC-DAIFMT 설정
아래의 설정은 ALSA에서 설정하는 SOC 설정모드이며, Codec 입장에서 기술된다.
- CBM: Codec Clock Master: Codec Chip Clock 제공
- CFM: Codec Frame Sync Master: Codec Chip Frame Sync 제공
CODEC는 위와 같이 CLOCK과 Frame Sync(WCLK)을 제공을 한다.
그러므로, CODEC이 BCLK Master Frame Sync Master이므로, SND_SOC_DAIFMT_CBM_CFM 이다.
- 둘 사이의 Master/Slave 관련결정
$ vi include/sound/soc-dai.h #define SND_SOC_DAIFMT_CBM_CFM (0 << 12) /* codec clk & FRM master */ #define SND_SOC_DAIFMT_CBS_CFM (1 << 12) /* codec clk slave & FRM master */ #define SND_SOC_DAIFMT_CBM_CFS (2 << 12) /* codec clk master & frame slave */ #define SND_SOC_DAIFMT_CBS_CFS (3 << 12) /* codec clk & FRM slave */
- 둘 사이의 실제적인 Interface 결정 과 Clock
$ vi include/sound/soc-dai.h #define SND_SOC_DAIFMT_I2S 0 /* I2S mode */ #define SND_SOC_DAIFMT_RIGHT_J 1 /* Right Justified mode */ #define SND_SOC_DAIFMT_LEFT_J 2 /* Left Justified mode */ #define SND_SOC_DAIFMT_DSP_A 3 /* L data MSB after FRM LRC */ #define SND_SOC_DAIFMT_DSP_B 4 /* L data MSB during FRM LRC */ #define SND_SOC_DAIFMT_AC97 5 /* AC97 */ #define SND_SOC_DAIFMT_NB_NF (0 << 8) /* normal bit clock + frame */ #define SND_SOC_DAIFMT_NB_IF (1 << 8) /* normal BCLK + inv FRM */ #define SND_SOC_DAIFMT_IB_NF (2 << 8) /* invert BCLK + nor FRM */ #define SND_SOC_DAIFMT_IB_IF (3 << 8) /* invert BCLK + FRM */
- DM368의 최종결정
$ vi ./sound/soc/davinci/davinci-evm.c // 현재 DM368 설정
#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF)
- AIC3100 의 지원되는 I2S와 DSP Mode
Offset은 McBSP의 Data Delay에 같이 설정해야하며
Offset을 주느냐에 따라 DSP_B모드가 되며,NB_NF의 선택 BCLK과 WCLK의 극성선택이다.
2. I2C driver 기본확인사항
HW Codec의 I2C Driver는 거의 동일하며, 실제적인 Codec의 관련설정을 하는 것이므로, 사용시 반드시 Codec Datasheet와 함께 봐야한다.
2.1 Audio Codec 등록 확인
아래와 같이 기본 board에서 등록이 되어있는지 확인하고, Kernel config에서지원되는 것을 확인을 하자.
만약 지원이 되지 않는다면, 이제 Audio Codec Driver를 가져와서, 이를 Porting하자 .
아래와 같이 등록을 해야, 실제 Audio Codec Driver에서 발견가능하다.
보통 Codec Driver 들은 여러종류의 칩의 지원을 하므로, 아래와 같이 board에서 이름을 정확히 정해줘야한다.
현재 DM368에, AIC3100을 올려서 수정하고 있다.
A. DM368
$ vi arch/arm/mach-davinci/board-dm368-ipnc.c
static struct i2c_board_info i2c_info[] = {
{
I2C_BOARD_INFO("tlv320aic3x", 0x18), // AIC3100의 7bit Address는 0x18 설정
},
};
static void __init evm_init_i2c(void)
{
davinci_init_i2c(&i2c_pdata);
i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
}
B. DM355
아래와 같이, plaform_data에 argument를 넣어 전달이 가능하다.
그러면, i2c_probe할 때, struct i2c_client *i2c 에서 i2c->dev.platform_data 전달 받을 수 있다.
$ vi arch/arm/mach-davinci/board-dm355-evm.c static struct i2c_board_info dm355evm_i2c_info[] = { { I2C_BOARD_INFO("dm355evm_msp", 0x25), .platform_data = dm355evm_mmcsd_gpios, }, /* { plus irq }, */ { I2C_BOARD_INFO("tlv320aic33", 0x1b), }, }; static void __init evm_init_i2c(void) { davinci_init_i2c(&i2c_pdata); gpio_request(5, "dm355evm_msp"); gpio_direction_input(5); dm355evm_i2c_info[0].irq = gpio_to_irq(5); i2c_register_board_info(1, dm355evm_i2c_info, ARRAY_SIZE(dm355evm_i2c_info)); }
2.2 Audio Codec Driver 기본동작
AIC3x Driver 즉 HW Codec Driver 예제이며 구조는 다음과 같다.
- module init 이 호출되면서, i2c_add_driver 호출하여, i2c driver 를 등록
- 이미 등록된 I2C device가 있으면, 이를 찾아 probe를 호출 (platform_driver 구조와 동일)
- aic3x_i2c_probe 는 snd_soc_register_codec 사용하여 Codec Driver를 등록한다.
- aic3x_dai를 snd_soc_dai를 등록하여 이는 codec_dai 와 cpu_dai와 mapping 동작함
$ vi sound/soc/codecs/tlv320aic3x.c static const struct i2c_device_id aic3x_i2c_id[] = { [AIC3X_MODEL_3X] = { "tlv320aic3x", 0 }, [AIC3X_MODEL_33] = { "tlv320aic33", 0 }, [AIC3X_MODEL_3007] = { "tlv320aic3007", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id); /* machine i2c codec control layer */ static struct i2c_driver aic3x_i2c_driver = { .driver = { .name = "tlv320aic3x-codec", .owner = THIS_MODULE, }, .probe = aic3x_i2c_probe, // 이미 i2c_register_board_info 했을 경우, probe를 실행 .remove = aic3x_i2c_remove, .id_table = aic3x_i2c_id, }; static inline void aic3x_i2c_init(void) { int ret; ret = i2c_add_driver(&aic3x_i2c_driver); if (ret) printk(KERN_ERR "%s: error regsitering i2c driver, %d\n", __func__, ret); } static inline void aic3x_i2c_exit(void) { i2c_del_driver(&aic3x_i2c_driver); } static struct snd_soc_codec_driver soc_codec_dev_aic3x = { .set_bias_level = aic3x_set_bias_level, // Reset , 초기화 Codec의 상태별로 설정 .reg_cache_size = ARRAY_SIZE(aic3x_reg), // Cache Size .reg_word_size = sizeof(u8), .reg_cache_default = aic3x_reg, // Codec Default Setting. .probe = aic3x_probe, // aic3x_probe** .remove = aic3x_remove, .suspend = aic3x_suspend, .resume = aic3x_resume, }; #define AIC3X_RATES SNDRV_PCM_RATE_8000_96000 #define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) static struct snd_soc_dai_ops aic3x_dai_ops = { .hw_params = aic3x_hw_params, // CODEC 관련 설정 .digital_mute = aic3x_mute, // .set_sysclk = aic3x_set_dai_sysclk, // CLOCK 관련 설정 .set_fmt = aic3x_set_dai_fmt, // Interface 설정 (format 설정) }; static struct snd_soc_dai_driver aic3x_dai = { .name = "tlv320aic3x-hifi", .playback = { .stream_name = "Playback", .channels_min = 1, .channels_max = 2, .rates = AIC3X_RATES, .formats = AIC3X_FORMATS,}, .capture = { .stream_name = "Capture", .channels_min = 1, .channels_max = 2, .rates = AIC3X_RATES, .formats = AIC3X_FORMATS,}, .ops = &aic3x_dai_ops, }; static int aic3x_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) // Codec Driver 등록 { ....... ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_aic3x, &aic3x_dai, 1); //snd_soc_dai_driver 등록 이는 추후 SOC와 Mappping ...... }
3. Codec Porting 시 체크사항
현재 AIC3100을 사용해야하는데, AIC3x와 정확히 호환되지 않는다.
그리고, AIC3100 Driver (AM3xxx 계열지원) 지원이 되지만 DM368 Kernel ALSA Version과 다르다.
커널 간에 ALSA의 아래사항을 확인해보자.
3.1 ALSA Framework 확인
Kernel의 ALSA 기본 Framework 부분을 확인하자.
A. ALSA 기본 header 체크사항
include/sound/soc.h
include/sound/soc-dapm.h
B. Codec 에 의존된 header 체크
현재 TI TLV Series 사용하므로, 아래의 header를 체크하자. (AIC3100 사용)
만약 Wolfson사의 WM Series를 사용한다면, 다른 header를 체크하자.
include/sound/tlv.h
3.2 I2C Mapping 확인
Code driver 는 요즘 거의 Cache에 Mapping 시켜서 사용하는 것 같다.
기본적으로 사용하고 싶은 register size 만큼 cache에 등록하고,
별도의 kernel/drivers/base/regmap/regmap-i2c.ko 필요한 것 같은데, 불행히도 DM368은 지원하지 않는다.
그래서 그냥 아래와 같이 직접 I2C에 연결해서 사용했다.
Kernel config에 포함이 되어있지 않다면, 아래와 같이 직접 연결하여 사용해야한다.
3.3 CODEC 과 CPU 의 Interface 설정
TI Audio Driver는 현재 아래와 같은 구조로 동작하며, 다른 Driver 일 경우 변경 될 수 있다.
모든 것이 hw_param 의해 설정이 되며, 아래와 같이 개별적으로 Driver 마다 존재한다.
ALSA에서 hw_param가 호출이 되면, EVM 및 개별 machine, codec, cpu, platform driver의 hw_param이 호출이 된다.
ALSA는 간단하지만 내부 Driver구조들은 제법 많이 복잡하다 관련내용은 추후 다시 설명
그리고, AIC3100 Driver (AM3xxx 계열지원) 지원이 되지만 DM368 Kernel ALSA Version과 다르다.
커널 간에 ALSA의 아래사항을 확인해보자.
3.1 ALSA Framework 확인
Kernel의 ALSA 기본 Framework 부분을 확인하자.
A. ALSA 기본 header 체크사항
include/sound/soc.h
include/sound/soc-dapm.h
B. Codec 에 의존된 header 체크
현재 TI TLV Series 사용하므로, 아래의 header를 체크하자. (AIC3100 사용)
만약 Wolfson사의 WM Series를 사용한다면, 다른 header를 체크하자.
include/sound/tlv.h
3.2 I2C Mapping 확인
Code driver 는 요즘 거의 Cache에 Mapping 시켜서 사용하는 것 같다.
기본적으로 사용하고 싶은 register size 만큼 cache에 등록하고,
별도의 kernel/drivers/base/regmap/regmap-i2c.ko 필요한 것 같은데, 불행히도 DM368은 지원하지 않는다.
그래서 그냥 아래와 같이 직접 I2C에 연결해서 사용했다.
Kernel config에 포함이 되어있지 않다면, 아래와 같이 직접 연결하여 사용해야한다.
static int aic3100_read(struct snd_soc_codec *codec, unsigned int reg) { struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); int ret=0; reg = (reg & 0xff); ret = i2c_smbus_read_byte_data(aic3x->control_data, reg); if (ret < 0) printk("%s error addr=%x \n",__func__,reg); return ret; } static int aic3100_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); int ret=0; reg = (reg & 0xff); value = (value & 0xff); ret = i2c_smbus_write_byte_data(aic3x->control_data, reg, value); if (ret < 0) printk("%s error addr=%x val=%x \n",__func__,reg,value); return ret; }
3.3 CODEC 과 CPU 의 Interface 설정
TI Audio Driver는 현재 아래와 같은 구조로 동작하며, 다른 Driver 일 경우 변경 될 수 있다.
모든 것이 hw_param 의해 설정이 되며, 아래와 같이 개별적으로 Driver 마다 존재한다.
ALSA에서 hw_param가 호출이 되면, EVM 및 개별 machine, codec, cpu, platform driver의 hw_param이 호출이 된다.
ALSA는 간단하지만 내부 Driver구조들은 제법 많이 복잡하다 관련내용은 추후 다시 설명
- evm_hw_param 인 경우
$ vi ./sound/soc/soc-core.c soc_pcm_hw_params // 개별가 존재하면, hw_params 호출 machine ,codec, cpu, plaftform, $ vi ./sound/soc/davinci/davinci-evm.c #define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \ SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF) static int evm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { ..... /* set codec DAI configuration */ ret = snd_soc_dai_set_fmt(codec_dai, AUDIO_FORMAT); // CODEC Driver 에 set_fmt 함수 호출, if (ret < 0) return ret; /* set cpu DAI configuration */ ret = snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT); // McBSP Driver 에 format 적용 if (ret < 0) return ret; /* set the codec system clock */ ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_OUT); // Codec Driver 의 set_sysclk 호출 if (ret < 0) return ret; ... }
2/15/2016
Audio-ALSA Framework
1. ALSA의 기본구조
ALSA(Advanced Linux Sound Architecture)로 요즘 거의 AP/SoC들은 ALSA의 기반에 맞추어 각 Driver들을 만들어 이곳에 등록하여 동작하도록 구성한다.
ALSA(Advanced Linux Sound Architecture)로 요즘 거의 AP/SoC들은 ALSA의 기반에 맞추어 각 Driver들을 만들어 이곳에 등록하여 동작하도록 구성한다.
그래서 ALSA Format? 이 존재하고 각 AP/SoC 업체들은 각 자신들의 BSP Driver를 이 Format에 맞추어 동작가능하도록 하고 호환성을 높인다.
1.1 OSS와 ALSA
OSS (Open Sound System) 약어로 Linux 2.4에서 공식적으로 사용을 했다고 한다.이때도 Audio Driver 수정했지만, 모르고 수정했다.
사실 Audio 관련 Driver는 Kernel 2.4 때 주로 많이 직접 Audio Driver를 만들었지만, 그때는 OSS라는 이름을 잘 못들은 것 같다.
OSS 관련내용
https://en.wikipedia.org/wiki/Open_Sound_System
http://www.opensound.com/pguide/oss.pdf
1.2 TI 사의 ALSA 전체구조
ALSA의 기본 전체구조는 아래와 같으며, 다른 SOC 플랫폼도 유사하다.
아래 구조는 TI사의 Sitara의 구조에서 가져왔다.
자세한 내용은 아래의 페이지 참조
TI사의 ALSA 전체구조
http://alsa.opensrc.org/Alsa-utils
ftp://ftp.alsa-project.org/pub/utils/
1.1 OSS와 ALSA
ALSA(Advanced Linux Sound Architecture)로 Linux에서만 사용이 되며, Kernel version 2.5에서 부터 추가가 되었다고 한다.
ALSA라는 이름 부각되는 것은 Linux Kernel 이 2.4 -> 2.5로 변경되면서 Driver 전체구조자체가 Platform 구조로 변경되었기 때문인 것 같다.
사실 Audio 관련 Driver는 Kernel 2.4 때 주로 많이 직접 Audio Driver를 만들었지만, 그때는 OSS라는 이름을 잘 못들은 것 같다.
Kernel 2.4 Audio Driver 의 경우는 좀 제 각각인데다가, 필요에따라 확장하고 그랬다.
또한 각 Audio Chip Vendor에 따라 구조역시 조금씩 다르다.
OSS 관련내용
https://en.wikipedia.org/wiki/Open_Sound_System
http://www.opensound.com/pguide/oss.pdf
1.2 TI 사의 ALSA 전체구조
ALSA의 기본 전체구조는 아래와 같으며, 다른 SOC 플랫폼도 유사하다.
아래 구조는 TI사의 Sitara의 구조에서 가져왔다.
자세한 내용은 아래의 페이지 참조
TI사의 ALSA 전체구조
https://en.wikipedia.org/wiki/Advanced_Linux_Sound_Architecture
http://processors.wiki.ti.com/index.php/Sitara_Linux_Audio_Driver_Overview
Linux의 Audio Driver의 기본구조는 ALSA Framework이며, 이에 관련된 Project는 다음과 같으며, 위와 같다.
http://processors.wiki.ti.com/index.php/Sitara_Linux_Audio_Driver_Overview
Linux의 Audio Driver의 기본구조는 ALSA Framework이며, 이에 관련된 Project는 다음과 같으며, 위와 같다.
ALSA 관련문서
http://www.alsa-project.org/main/index.php/Documentation
http://www.alsa-project.org/main/index.php/Download
2. ALSA의 전체구조
ALSA의 구조를 간단히 2단계로 나누면 간단하다, KERNEL과 APP이다.
하지만 세부화로 나누게되면, KERNEL도 COMMON한 부분이 있고, 포팅을 해야하는 부분이 있기에 이를 또 나누게 된다.
그리고, 이를 USER에게 기능을 제공을 하면, Alsa User Lib가 이를 가지고 사용을 한다.
2.1 ALSA SOC CORE (KERNEL)
Embeded Linux에서는 해당 Chip마다 각 ALSA Soc Driver를 제공하며,Framework이 SOC마다 약간 상이하며, Version에 따라 다를 수 있다.
http://www.alsa-project.org/main/index.php/Documentation
http://www.alsa-project.org/main/index.php/Download
2. ALSA의 전체구조
ALSA의 구조를 간단히 2단계로 나누면 간단하다, KERNEL과 APP이다.
하지만 세부화로 나누게되면, KERNEL도 COMMON한 부분이 있고, 포팅을 해야하는 부분이 있기에 이를 또 나누게 된다.
그리고, 이를 USER에게 기능을 제공을 하면, Alsa User Lib가 이를 가지고 사용을 한다.
2.1 ALSA SOC CORE (KERNEL)
- Codec Driver : AIC31x, AIC3100 Audio Codec Driver를 말하며, I2C로 Driver이다.
- Platform Driver: TI인 경우 주로 McBSP or McASP Audio Driver이며, DMA기능을 포함한다.
- Machine Driver: Codec과 Platform Driver를 연결시켜주는 Driver이며, Machine에 대한 설정 담당한다.
Embeded Linux에서는 해당 Chip마다 각 ALSA Soc Driver를 제공하며,Framework이 SOC마다 약간 상이하며, Version에 따라 다를 수 있다.
ALSA Library와 직접적으로 통신을 하며, 기능을 제공을 한다.
http://www.alsa-project.org/main/index.php/ASoC
2.2 ALSA Library (USER)
http://www.alsa-project.org/alsa-doc/alsa-lib/
http://www.alsa-project.org/main/index.php/ALSA_Library_API
2.3 ALSA Application (USER)
http://www.alsa-project.org/main/index.php/Applications
Android로 가면, Hal이 될수도 있다.
http://www.alsa-project.org/main/index.php/ASoC
2.2 ALSA Library (USER)
- ALSA PCM 기본설명
http://www.alsa-project.org/alsa-doc/alsa-lib/
http://www.alsa-project.org/main/index.php/ALSA_Library_API
2.3 ALSA Application (USER)
- ALSA를 이용한 다양한 Application Program들
http://www.alsa-project.org/main/index.php/Applications
Android로 가면, Hal이 될수도 있다.
- ALSA Test (alsa-utils)
http://alsa.opensrc.org/Alsa-utils
ftp://ftp.alsa-project.org/pub/utils/
피드 구독하기:
글
(
Atom
)