안드로이드 플랫폼에서 labtool 을 개발하는 방법에 대해 기술했다.
준비 운동하기
안드로이드 상에서 실행되는 바이너리를 빌드하기 위해서는 기본적으로 안드로이드 개발환경을 구축해야 한다. 방법은 다른 문서를 참조해도 된다.
하지만 여기서는 안드로이드 및 툴체인의 버전을 맞추기 위해 기존에 사용하던 환경을 그대로 가져와서 사용할 것이다.
환경 구축하기
먼저 아래의 패키지를 설치한다.
#apt-get install gcc #apt-get install git-core gnupg flex bison gperf build-essential \ zip curl libc6-dev libncurses5-dev:i386 x11proto-core-dev \ libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-glx:i386 \ libgl1-mesa-dev g++-multilib mingw32 openjdk-6-jdk tofrodos \ python-markdown libxml2-utils xsltproc zlib1g-dev:i386 #ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so
JDK 를 설치해야 한다. http://www.oracle.com/technetwork/java/javase/downloads 에서 JDK 를 다운로드한다. 이때, “Linux x64 (64bit)” jdk6u3X-linux-x64.bin 를 다운받도록 한다.
#chmod 777 jdk-6u41-linux-x64.bin #mv jdk-6u41-linux-x64.bin /root/ #cd #./jdk-6u41-linux-x64.bin
.bashrc 파일에 다음을 추가한다.
export JAVA_HOME=~/jdk1.6.0_41 export ANDROID_JAVA_HOME=$JAVA_HOME export PATH=$JAVA_HOME/bin/:$PATH
\\10.22.130.219\_share\_code\Android_BSPs 에 접속하여 PXA1L88_clean.zip 파일을 복사해온다.
압축을 풀고, 환경 스크립트 파일을 실행한다.
#cd PXA1L88 #. build/envsetup.sh #lunch // 5번(pxa1L88dkb_def-eng) 선택할 것 #cd kernel #make kernel #make modules #cd .. #make -j4
에러없이 빌드되었다면, 이제 labtool 빌드를 위한 사전 준비는 완료된 것이다.
labtool 빌드하기
\\10.22.130.219\_repo\labtool_8787 경로에서 최신버전의 labtool 코드를 받는다. 파일 이름으로 구분이 최신 코드의 가능하다.
압축을 풀고, 빌드를 위해 아래와 같이 소스코드 위치를 변경한다.
#7z x labtool_8787_bk140425_v20.7z #cp -arf labtool_8787 PXA1L88/vendor/marvell #cd PXA1L88/vendor/marvell/labtool_8787/Host #mm -B // 기존의 바이너리를 삭제하고 재빌드
에러없이 빌드가 되었다면, labtool, libwlm_8787.a 파일이 생성된다. 이들 파일의 경로는 다음과 같다.
파일명 | 경로 |
labtool | out/target/product/pxa1L88dkb/system/bin |
libwlm_8787.a | out/target/product/pxa1L88dkb/obj/STATIC_LIBRARIES/libwlm_8787_intermediates |
생성된 라이브러리 파일(libwlm_8787.a)을 SS 에 전달한다.
개발하기
SS 공정에서 사용하는 장비가 바뀐다던지, 또는 테스트 순서가 바뀌는 경우 기존의 labtool 상에서 에러가 발생할 수 있다. 따라서 코드 수정이 불가피하다.
코드를 수정하는 절차에 대해 설명한다. 코드가 수정되는 부분은 거의 'Host/MRVLDut/MRVL_RF_API.cpp' 파일이다.
labtool 코드받기
labtool 코드의 경우, 별도의 svn 과 같은 버전관리 프로그램을 사용하지 않는다. 따라서 \\10.22.130.219\_repo 에서 해당하는 칩셋의 labtool 코드를 받아야 한다. 이때 반드시 최신버전을 받아야 한다.
코드 수정하기
코드 수정 후, 이에 대한 내용을 주석으로 추가해야 한다. Host/MRVLDut/MRVL_RF_API.cpp 파일을 아래와 같이 수정한다.
... int labtool_ver_info = 0x01; int labtool_ver_temp = 0x22; // 수정사항이 있을 때마다 버전을 1씩 올린다. 현재 버전은 1.22 이다 /******************************************************************************** 0x21 2014/5/21 reason : 11b - CMD25, Other(11g/a/n) - CMD35 0x22 2014/5/22 reason : rollback code(regard LDPC routine, change comment) *********************************************************************************/ ...
확인하기
앞에서 수정한 내용이 제대로 동작하는지에 대한 확인이 반드시 필요하다. 이에 대한 방법으로 몇 가지가 있다.
labtool 을 직접 실행하는 방법
첫번째 방법의 경우, 앞서 생성한 라이브러리 파일(libwlm_8787.a)을 이용하여 새로 빌드한 후, 생성된 이미지를 타겟에 올려 확인해보는 것이다.
더욱 확실하게 확인하는 방법은 그 상태에서 측정 장비를 연결하여 실제 제대로 신호가 나오는지 확인하는 것이다.
tester program 이용하는 방법
두번째 방법은 테스트 프로그램을 사용하는 것인데, \\10.22.130.219\_repo\libwlm_tester 에서 파일을 받아, labtool 을 빌드하는 방법으로 컴파일한다.
컴파일 되면, out/target/product/pxa1L88dkb/obj/EXECUTABLES/libwlm_tester_intermediates 아래에 'libwlm_tester' 라는 실행파일이 생긴다. 이 파일을 타겟에 넣고 실행한다.
이 프로그램은 앞서 Host/MRVLDut/MRVL_RF_API.cpp 파일에서 정의한 함수를 호출하는 역할을 한다. 새롭게 생성하거나 수정한 함수가 있다면, 이 프로그램을 이용하여 호출하여 확인할 수 있다.
동작 시퀀스 분석
실행 로그를 참조하여 호출되는 시퀀스를 아래와 같이 trace 했다.
MRVL_RFT_OpenDUT()
항목 | 설명 | 비고 |
Description | Initialize all variable for DUT test MFG F/W | |
Syntax | int MRVL_RFT_OpenDUT(void) | |
Parameters | None | |
Return Value | 0 : Socket 이 제대로 생성되고, ioctl 명령어(hostcmd)를 get 했을 경우 리턴 | |
Return Value | -1 : Socket 생성에 실패하거나, ioctl 명령어(hostcmd)를 get 하지 못했을 경우 리턴 | |
Remarks | AT command 통신을 하기 전에, 사전에 가장 먼저 호출되어야 한다 |
Soket 을 생성하고, 기본적인 ioctl 통신을 정상 유무를 확인한다. 또한 앞으로 사용할 변수들을 초기화 한다(init_PcktPifsSettings).
MRVL_RFT_SetBandAG()
항목 | 설명 | 비고 |
Description | band(2.4G/5G)를 설정한다 | |
Syntax | int MRVL_RFT_SetBandAG(int mBand) | |
Parameters | mBand(IN) - band type | 1(=2.4G), 2(=5G) |
Return Value | 0 : 정상적으로 ioctl 명령이 수행되었을 때 리턴 | |
Return Value | 0 이외의 값 : 수행 도중 에러가 발생했을 때 리턴 | |
Remarks | 2.4G 또는 5G, 둘 중 하나만 설정이 가능하다. 인자값이 1 이면 DutIf_SetBandAG(0), 2 이면 DutIf_SetBandAG(1) 호출 |
band 를 설정하며, 보통 MRVL_RFT_OpenDUT() 함수 이후에 호출된다.
MRVL_RFT_Channel()
항목 | 설명 | 비고 |
Description | TX Channel 을 설정한다 | |
Syntax | int MRVL_RFT_Channel(int ChannelNo) | |
Parameters | ChannelNo(IN) - number of channel | |
Return Value | 0 : 정상적으로 ioctl 명령이 수행되었을 때 리턴 | |
Return Value | 0 이외의 값 : 수행 도중 에러가 발생했을 때 리턴 | |
Remarks | 함수가 호출되기 전에 gBandWidth 값이 설정 되어야만 의미가 있다 |
Channel 번호를 인자로 받아 설정한다. Bandwidth 의 값에 따라서 Channel 이 설정 되는데, 이 함수가 호출되기 전에 gBandWidth 값이 설정되어야 한다.
현재 AT command 의 순서에 따르면, 이 함수가 불릴 때는 gBandWidth 값이 설정되지 않는다. 따라서 DutIf_SetRfChannel_new 함수 호출이 의미가 없다.
MRVL_RFT_TxDataRate()
항목 | 설명 | 비고 |
Description | TX data rate 를 설정한다 | |
Syntax | int MRVL_RFT_TxDataRate(DWORD TxDataRate) | |
Parameters | TxDataRate(IN) - number of data rate | |
Return Value | 0 : 정상적으로 ioctl 명령이 수행되었을 때 리턴 | |
Return Value | 0 이외의 값 : 수행 도중 에러가 발생했을 때 리턴 | |
Remarks | 변수에만 data rate 를 설정할 뿐 실제 ioctl 명령을 내리지는 않는다 |
TX data rate 를 설정할 때 호출하는 함수로서 인자로 data rate 값을 받는다. 변수 값만 설정할 뿐 실제로 ioctl 명령어가 수행되지는 않는다.
MRVL_RFT_SetPreamble()
항목 | 설명 | 비고 |
Description | TX Preamble 을 설정한다 | |
Syntax | int MRVL_RFT_SetPreamble(int PreambleType) | |
Parameters | PreambleType(IN) - type of preamble | default : short preable(mPcktPifsSettings.ShortPreamble = 1), long preamble = 0) |
Return Value | 항상 0 을 리턴 | |
Remarks | 변수에만 설정할 뿐 실제 ioctl 명령을 내리지는 않는다 |
인자로 0 이 들어오면, ShortPreamble = 1 로 설정하고, 0 이외의 값이 들어오면, ShortPreamble = 0 으로 설정한다.
MRVL_RFT_SetChannelBw()
항목 | 설명 | 비고 | |
Description | Channel Band width 를 설정한다 | ||
Syntax | int MRVL_RFT_SetChannelBw(int mBandWidth) | ||
Parameters | mBandWidth(IN) - type of band width | 3 : 80MHz, 4 : 20Mhz, 5 : 40MHz | |
Return Value | 0 : 정상적으로 ioctl 명령이 수행되었을 때 리턴 | ||
Return Value | 0 이외의 값 : 수행 도중 에러가 발생했을 때 리턴 | ||
Remarks | 입력받은 인자에 따라 Channel band width 가 설정된다 |
함수가 호출되는 순서에 유의한다.
MRVL_RFT_TxStart()
항목 | 설명 | 비고 |
Description | 앞서 설정한 값들을 바탕으로 TX 신호를 내보낸다 | |
Syntax | int MRVL_RFT_TxStart(void) | |
Parameters | None | |
Return Value | 0 : 정상적으로 ioctl 명령이 수행되었을 때 리턴 | |
Return Value | 0 이외의 값 : 수행 도중 에러가 발생했을 때 리턴 | |
Remarks | 25번 또는 35번 명령어를 사용한다 |
8897 의 경우, 25번 명령어를 8887 의 경우, 35번 명령어를 사용한다.
MRVL_RFT_TxGain_set()
항목 | 설명 | 비고 |
Description | TX Power gain 값을 설정한다 | |
Syntax | int MRVL_RFT_TxGain_set(int Pwr4Pa) | |
Parameters | int Pwr4Pa(IN) - value of power gain | |
Return Value | 0 : 정상적으로 ioctl 명령이 수행되었을 때 리턴 | |
Return Value | 0 이외의 값 : 수행 도중 에러가 발생했을 때 리턴 | |
Remarks | 독립적으로 호출되지는 않고, MRVL_RFT_TxGain() 함수에서 호출 |
MRVL_RFT_TxStart_35()
항목 | 설명 | 비고 |
Description | 앞서 설정한 값들을 바탕으로 TX 신호를 내보낸다 | |
Syntax | int MRVL_RFT_TxStart(void) | |
Parameters | None | |
Return Value | 0 : 정상적으로 ioctl 명령이 수행되었을 때 리턴 | |
Return Value | 0 이외의 값 : 수행 도중 에러가 발생했을 때 리턴 | |
Remarks | 25번 또는 35번 명령어를 사용한다 |
MRVL_RFT_TxGain()
항목 | 설명 | 비고 |
Description | TX Gain 값을 설정한다 | |
Syntax | int MRVL_RFT_TxGain(int Pwr4Pa) | |
Parameters | int Pwr4Pa(IN) - value of power gain | |
Return Value | 0 : 정상적으로 ioctl 명령이 수행되었을 때 리턴 | |
Return Value | 0 이외의 값 : 수행 도중 에러가 발생했을 때 리턴 | |
Remarks |
MRVL_RFT_TxStop()
항목 | 설명 | 비고 |
Description | TX 시그널을 중지한다 | |
Syntax | int MRVL_RFT_TxStop(void) | |
Parameters | None | |
Return Value | 0 : 정상적으로 ioctl 명령이 수행되었을 때 리턴 | |
Return Value | 0 이외의 값 : 수행 도중 에러가 발생했을 때 리턴 | |
Remarks | 앞서 TxStart 함수에서 CMD 35번을 사용했다면, 여기서도 CMD 35번을 사용한다 |