Full Color LED 디바이스 제어 2012 내장형 시스템 설계 2012. 11. 21
Table of Contents • Full Color LED디바이스 구성 • Full Color LED 디바이스 드라이버 • Full Color LED JNI 라이브러리 작성 • Full Color LED 안드로이드App 구현 • JNI 라이브러리 빌드 • 결과 화면
Full Color LED 디바이스구성 (1) • FPGA 내부의 컨트롤러에 의해 제어됨
Full Color LED 디바이스구성 (2) • 9bit로 구성된 12개의 레지스터
Full Color LED 디바이스 드라이버 (1) • 드라이버 코드위치 • “~/linux-3.0.15-s4210/drivers/hanback“ 디렉토리에 포함되어있음 • 드라이버 소스 코드 (fullcolorled.c) #include<linux/miscdevice.h> #include<linux/platform_device.h> #include<linux/fs.h> #include<linux/file.h> #include<linux/mm.h> #include<linux/list.h> #include<asm/io.h> #include<asm/uaccess.h> #include<asm/cacheflush.h> #include<linux/init.h> #include<linux/module.h> #include<linux/kernel.h> #include<linux/fs.h> #include<linux/errno.h> #include<linux/types.h> #include<linux/ioport.h> #include<linux/delay.h>
Full Color LED 디바이스 드라이버 (2) • 드라이버 소스 코드 (fullcolorled.c) #define DRIVER_AUTHOR "hanback" #define DRIVER_DESC "full color led test program" #define FULLCOLORLED_NAME "fullcolorled" #define FULLCOLORLED_MODULE_VERSION "FULL COLOR LED V0.1" #define FULLCOLORLED_ADDRESS 0x05000000 #define FULLCOLORLED_ADDRESS_RANGE 0x1000 #define FULL_LED1 9 #define FULL_LED2 8 #define FULL_LED3 7 #define FULL_LED4 6 #define ALL_LED 5 staticintfullled_usage = 0; staticintled_num=0; staticunsignedlong *fullled_ioremap; staticunsignedshort *full_led_addr[4][3];
Full Color LED 디바이스 드라이버(3) • 드라이버 소스 코드 (fullcolorled.c) intfullled_open(structinode *minode, struct file *mfile) { if(fullled_usage != 0) return -EBUSY; fullled_ioremap=ioremap(FULLCOLORLED_ADDRESS,FULLCOLORLED_ADDRESS_RANGE); if(!check_mem_region((unsignedlong)fullled_ioremap, FULLCOLORLED_ADDRESS_RANGE)) { request_mem_region((unsignedlong)fullled_ioremap, FULLCOLORLED_ADDRESS_RANGE, FULLCOLORLED_NAME); } elseprintk("driver: unable to register this!\n"); full_led_addr[0][0] =(unsignedshort *)((unsignedlong)fullled_ioremap+0xa0); full_led_addr[0][1] =(unsignedshort *)((unsignedlong)fullled_ioremap+0xa2); full_led_addr[0][2] =(unsignedshort *)((unsignedlong)fullled_ioremap+0xa4); full_led_addr[1][0] =(unsignedshort *)((unsignedlong)fullled_ioremap+0xa6); full_led_addr[1][1] =(unsignedshort *)((unsignedlong)fullled_ioremap+0xa8); full_led_addr[1][2] =(unsignedshort *)((unsignedlong)fullled_ioremap+0xaa); full_led_addr[2][0] =(unsignedshort *)((unsignedlong)fullled_ioremap+0xb0); full_led_addr[2][1] =(unsignedshort *)((unsignedlong)fullled_ioremap+0xb2); full_led_addr[2][2] =(unsignedshort *)((unsignedlong)fullled_ioremap+0xb4); full_led_addr[3][0] =(unsignedshort *)((unsignedlong)fullled_ioremap+0xb6); full_led_addr[3][1] =(unsignedshort *)((unsignedlong)fullled_ioremap+0xb8); full_led_addr[3][2] =(unsignedshort *)((unsignedlong)fullled_ioremap+0xba); fullled_usage = 1; return 0; }
Full Color LED 디바이스 드라이버(4) • 드라이버 소스 코드 (fullcolorled.c) intfullled_release(structinode *minode, struct file *mfile) { iounmap(fullled_ioremap); release_mem_region((unsignedlong)fullled_ioremap, FULLCOLORLED_ADDRESS_RANGE); fullled_usage = 0; return 0; } staticintfullled_ioctl(struct file *file, unsignedintcmd,unsignedlongarg) { switch(cmd) { caseFULL_LED1: led_num= 0; break; case FULL_LED2: led_num = 1; break; case FULL_LED3: led_num = 2; break; case FULL_LED4: led_num = 3; break; case ALL_LED: led_num = 4; break; } return 0; }
Full Color LED 디바이스 드라이버(5) • 드라이버 소스 코드 (fullcolorled.c) ssize_tfullled_write(struct file *inode, constchar *gdata, size_t length, loff_t *off_what) { intret,i=0,j=0; unsignedcharbuf[3]; ret = copy_from_user(buf,gdata,length); for(j=0;j<3;j++) { if(buf[j]%0x10 >= 0xA) buf[j]+=0x06; if(buf[j]%0x100 >= 0xA0) buf[j]+=0x60; } if(led_num != 4) { for(j=0;j<3;j++) { *full_led_addr[led_num][j] = buf[j]; } } else { for(i=0;i<4;i++) { for(j=0;j<3;j++) { *full_led_addr[i][j] = buf[j]; } } } return length; }
Full Color LED 디바이스 드라이버(6) • 드라이버 소스 코드 (fullcolorled.c) structfile_operationsfullled_fops = { .owner = THIS_MODULE, .write = fullled_write, .open = fullled_open, .release = fullled_release, .unlocked_ioctl = fullled_ioctl, }; staticstructmiscdevicefullled_driver = { .fops = &fullled_fops, .name = FULLCOLORLED_NAME, .minor = MISC_DYNAMIC_MINOR, }; intfullled_init(void) { printk("driver: %s DRIVER INIT\n",FULLCOLORLED_NAME); returnmisc_register(&fullled_driver); } voidfullled_exit(void) { misc_deregister(&fullled_driver); printk("driver: %s DRIVER EXIT\n",FULLCOLORLED_NAME); } module_init(fullled_init); module_exit(fullled_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("Dual BSD/GPL");
Full Color LED JNI 라이브러리 작성 (1) • Full Color LED 드라이버를 안드로이드앱에서 사용하기 위해서는 JNI 인터페이스 라이브러리가 필요 • 이 라이브러리는 구글의 NDK를 이용하여 빌드
Full Color LED JNI 라이브러리 작성 (2) • JNI 프로그램 소스 • fullcolorled.c #include<string.h> #include<jni.h> #include<stdio.h> #include<stdlib.h> #include<fcntl.h> #include<unistd.h> #include<termios.h> #include<sys/mman.h> #include<errno.h> jintJava_package_fullLed_FullLedActivity_FLEDControl(JNIEnv* env, jobjectthiz, jintled_num, jint val1, jint val2, jint val3) { intfd,ret; charbuf[3]; fd = open("/dev/fullcolorled",O_WRONLY); if (fd < 0) { return -errno; } ret = (int)led_num; switch(ret) { case FULL_LED1: ioctl(fd,FULL_LED1); break; case FULL_LED2: ioctl(fd,FULL_LED2); break; case FULL_LED3: ioctl(fd,FULL_LED3); break; case FULL_LED4: ioctl(fd,FULL_LED4); break; case ALL_LED: ioctl(fd,ALL_LED); break; } buf[0] = val1; buf[1] = val2; buf[2] = val3; write(fd,buf,3); close(fd); return ret; } #define FULL_LED1 9 #define FULL_LED2 8 #define FULL_LED3 7 #define FULL_LED4 6 #define ALL_LED 5 jint: 함수의 리턴 타입 package_fullLed: 안드로이드앱의package 이름 FullLedActivity: 안드로이드앱의Activity 이름 FLEDControl: 안드로이드앱에서 사용할 함수 이름
Full Color LED JNI 라이브러리 작성 (3) • 안드로이드용Makefile인Android.mk작성하기 • Android.mk (1) 컴파일의 결과물로서 생성되는라이브러리 이름이며, NDK에서는이 이름앞에 lib가 추가되고, 뒤에 .so가 붙어libfullcolorled.so라는 파일이 만들어짐 (2) 컴파일 할 소스 파일의 이름 (3) Shared Library 용으로 빌드한다는표시로서확장자.so 가붙음
Full Color LED 안드로이드App 구현 (1) • Application name • FullLed • Project Name • FullLed • Package name • {name}. fullLed • Activity name • FullLedActivity • Layout name • main
Full Color LED 안드로이드App 구현 (2) AndroidManifest.xml <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="moriya.fullLed" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="10" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".FullLedActivity" android:label="@string/title_activity_full_led" android:screenOrientation="landscape" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Full Color LED 안드로이드App 구현 (3) main.xml (1) <?xml version="1.0" encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bgimage" android:orientation="vertical" android:padding="10dip" > <RadioGroup android:id="@+id/fcl_LedGroup" android:layout_width="wrap_content" android:layout_height="wrap_content" android:checkedButton="@+id/fcl_ledbut1" android:orientation="horizontal" > <RadioButton android:id="@+id/fcl_ledbut1" android:layout_margin="3px" android:checked="true" android:gravity="right|center_vertical" android:text="LED1" android:textColor="@drawable/GRAY" /> <RadioButton android:id="@+id/fcl_ledbut2" android:layout_margin="3px" android:checked="false" android:gravity="right|center_vertical" android:text="LED2" android:textColor="@drawable/GRAY" /> • <RadioButton • android:id="@+id/fcl_ledbut3" • android:layout_margin="3px" • android:checked="false" • android:gravity="right|center_vertical" • android:text="LED3" • android:textColor="@drawable/GRAY" /> • <RadioButton • android:id="@+id/fcl_ledbut4" • android:layout_margin="3px" • android:checked="false" • android:gravity="right|center_vertical" • android:text="LED4" • android:textColor="@drawable/GRAY" /> • <RadioButton • android:id="@+id/fcl_ledbut5" • android:layout_margin="3px" • android:checked="false" • android:gravity="right|center_vertical" • android:text="All" • android:textColor="@drawable/GRAY" /> • </RadioGroup>
Full Color LED 안드로이드App 구현 (4) main.xml (2) • <RadioButton • android:id="@+id/fcl_green" • android:layout_margin="5px" • android:checked="false" • android:gravity="right|center_vertical" • android:text="Green" • android:textColor="@drawable/GREEN" /> • <RadioButton • android:id="@+id/fcl_random" • android:layout_margin="5px" • android:checked="false" • android:gravity="right|center_vertical" • android:text="Random" • android:textColor="@drawable/GRAY" /> • <RadioButton • android:id="@+id/fcl_off" • android:layout_margin="5px" • android:checked="true" • android:gravity="right|center_vertical" • android:text="Off" • android:textColor="@drawable/GRAY" /> • </RadioGroup> <RadioGroup android:id="@+id/fcl_ColorGruop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:baselineAligned="true" android:checkedButton="@+id/fcl_red" android:orientation="horizontal" > <RadioButton android:id="@+id/fcl_red" android:layout_margin="5px" android:checked="false" android:gravity="center|center_vertical" android:text="Red" android:textColor="@drawable/RED" /> <RadioButton android:id="@+id/fcl_blue" android:layout_margin="5px" android:checked="false" android:gravity="right|center_vertical" android:text="Blue" android:textColor="@drawable/BLUE" />
Full Color LED 안드로이드App 구현 (5) main.xml (3) <SeekBar android:id="@+id/fcl_seekBar_red" android:layout_width="400dip" android:layout_height="wrap_content" android:layout_marginTop="10px" android:max="100" /> <SeekBar android:id="@+id/fcl_seekBar_green" android:layout_width="400dip" android:layout_height="wrap_content" android:layout_marginTop="10px" android:max="100" /> <SeekBar android:id="@+id/fcl_seekBar_blue" android:layout_width="400dip" android:layout_height="wrap_content" android:layout_marginTop="10px" android:max="100" /> </LinearLayout>
Full Color LED 안드로이드App 구현 (6) color.xml : ‘res/values’ 에 추가 <?xml version="1.0" encoding="utf-8"?> <resources> <drawablename="RED">#ff0000</drawable> <drawablename="BLUE">#0000ff</drawable> <drawablename="GREEN">#008000</drawable> <drawablename="YELLOW">#ffff00</drawable> <drawablename="GRAY">#808080</drawable> <drawablename="screen_background_black">#ff000000</drawable> <drawablename="translucent_background">#e0000000</drawable> <drawablename="transparent_background">#00000000</drawable> <color name="solid_red">#f00</color> <color name="solid_blue">#0000ff</color> <color name="solid_green">#f0f0</color> <color name="solid_yellow">#ffffff00</color> <drawablename="BLACK">#000000</drawable> <drawablename="WHITE">#ffffffff</drawable> </resources>
Full Color LED 안드로이드 App 구현 (7) FullLedActivity.java (1) package moriya.fullLed; import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.view.View; import android.widget.RadioButton; import android.widget.SeekBar; public class FullLedActivity extends Activity { static { System.loadLibrary("fullcolorled"); } public native intFLEDControl(intled_num, int val1, int val2, int val3); static SeekBar[] sb; static int temp; int[] led_val; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); led_val = new int[4]; led_val[0] = 9; for (inti = 1; i < 4; i++) { led_val[i] = 0; }
Full Color LED 안드로이드 App 구현 (8) FullLedActivity.java (2) findViewById(R.id.fcl_ledbut1).setOnClickListener(mLedButtonListener); findViewById(R.id.fcl_ledbut2).setOnClickListener(mLedButtonListener); findViewById(R.id.fcl_ledbut3).setOnClickListener(mLedButtonListener); findViewById(R.id.fcl_ledbut4).setOnClickListener(mLedButtonListener); findViewById(R.id.fcl_ledbut5).setOnClickListener(mLedButtonListener); findViewById(R.id.fcl_red).setOnClickListener(mColorButtonListener); findViewById(R.id.fcl_green).setOnClickListener(mColorButtonListener); findViewById(R.id.fcl_blue).setOnClickListener(mColorButtonListener); findViewById(R.id.fcl_random).setOnClickListener(mColorButtonListener); findViewById(R.id.fcl_off).setOnClickListener(mColorButtonListener); // sb = new SeekBar[3]; sb[0] = (SeekBar) findViewById(R.id.fcl_seekBar_red); sb[1] = (SeekBar) findViewById(R.id.fcl_seekBar_green); sb[2] = (SeekBar) findViewById(R.id.fcl_seekBar_blue); sb[0].setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { public void onStopTrackingTouch(SeekBar arg0) { // TODO Auto-generated method stub temp = arg0.getProgress(); led_val[1] = temp; FLEDControl(led_val[0], led_val[1], led_val[2], led_val[3]); } public void onStartTrackingTouch(SeekBar arg0) { // TODO Auto-generated method stub temp = arg0.getProgress(); }
Full Color LED 안드로이드 App 구현 (9) FullLedActivity.java (3) public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) { // TODO Auto-generated method stub temp = arg0.getProgress(); led_val[1] = temp; FLEDControl(led_val[0], led_val[1], led_val[2], led_val[3]); } }); sb[1].setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { public void onStopTrackingTouch(SeekBar arg0) { // TODO Auto-generated method stub temp = arg0.getProgress(); led_val[2] = temp; FLEDControl(led_val[0], led_val[1], led_val[2], led_val[3]); } public void onStartTrackingTouch(SeekBar arg0) { // TODO Auto-generated method stub temp = arg0.getProgress(); } public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) { // TODO Auto-generated method stub temp = arg0.getProgress(); led_val[2] = temp; FLEDControl(led_val[0], led_val[1], led_val[2], led_val[3]); } });
Full Color LED 안드로이드 App 구현 (10) FullLedActivity.java (4) sb[2].setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { public void onStopTrackingTouch(SeekBar arg0) { // TODO Auto-generated method stub temp = arg0.getProgress(); led_val[3] = temp; FLEDControl(led_val[0], led_val[1], led_val[2], led_val[3]); } public void onStartTrackingTouch(SeekBar arg0) { // TODO Auto-generated method stub temp = arg0.getProgress(); } public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) { // TODO Auto-generated method stub temp = arg0.getProgress(); led_val[3] = temp; FLEDControl(led_val[0], led_val[1], led_val[2], led_val[3]); } }); } RadioButton.OnClickListenermLedButtonListener = new RadioButton.OnClickListener() { public void onClick(View v) { switch (v.getId()) { case R.id.fcl_ledbut1: led_val[0] = 9; break; case R.id.fcl_ledbut2: led_val[0] = 8; break; case R.id.fcl_ledbut3: led_val[0] = 7; break; case R.id.fcl_ledbut4: led_val[0] = 6; break; case R.id.fcl_ledbut5: led_val[0] = 5; break; }
Full Color LED 안드로이드 App 구현 (11) FullLedActivity.java (5) led_val[1] = sb[0].getProgress(); led_val[2] = sb[1].getProgress(); led_val[3] = sb[2].getProgress(); FLEDControl(led_val[0], led_val[1], led_val[2], led_val[3]); } }; RadioButton.OnClickListenermColorButtonListener = new RadioButton.OnClickListener() { public void onClick(View v) { switch (v.getId()) { case R.id.fcl_red: led_val[1] = 100; led_val[2] = 0; led_val[3] = 0; break; case R.id.fcl_green: led_val[1] = 0; led_val[2] = 0; led_val[3] = 100; break; case R.id.fcl_blue: led_val[1] = 0; led_val[2] = 100; led_val[3] = 0; break; case R.id.fcl_random: led_val[1] = (int) (Math.random() * 101); led_val[2] = (int) (Math.random() * 101); led_val[3] = (int) (Math.random() * 101); break; case R.id.fcl_off: led_val[1] = 0; led_val[2] = 0; led_val[3] = 0; break; }
Full Color LED 안드로이드 App 구현 (12) FullLedActivity.java (6) FLEDControl(led_val[0], led_val[1], led_val[2], led_val[3]); sb[0].setProgress(led_val[1]); sb[1].setProgress(led_val[2]); sb[2].setProgress(led_val[3]); } }; }
JNI 라이브러리 빌드 • 빌드 순서 • JNI 소스인fullcolorled.c와 Android.mk 파일을프로젝트의jni폴더에 추가 • “윈도키+r”을 입력하여 실행창을 오픈한 다음, “cmd”를 입력하여 커맨드 창을 오픈함 • 안드로이드App 프로젝트가 있는 폴더로 이동 • 빌드 명령을 실행 • 빌드를 위해 프로젝트 폴더에 아래와 같은 명령어를 입력 > /EmbeddedSystem/Android/ndk/ndk-build • 빌드가성공하면,libfullcolorled.so 파일이 생성된 것을 확인
결과(에뮬레이터)
결과(타겟보드)