혹시 망고210보드 사용해서 센서를 이용해본 사람 있다면 답글부탁...
![125498424F2B8456117067]()
작년에 ATmeaga128로 외부 adc, 모터, 가속도 센서등 다뤄봤구..
현재 네이버에 임베디드 크레이지 보이즈라는 카페에서 망고210 보드를 구매해서 공부하고 있는 학생인데..
부트로더 커널 및 진저브레드 포팅까지 하구 디바이스 드라이버 만들고 JNI 이용해서 안드로이드 어플상에서 레지스터 값을 조절해서
LED깜빡이는것 까지 성공을 했어. 그래서 이제 AVR처럼 레지스터 세팅을 하고 간단한 Zigbee 모듈을 UART로 테스팅 해보려구 하는데
근데.. AVR같은경우는 이미 많은 책이 있어서 어떤 레지스터를 건드려야 어떻게 세팅이 되고 하는걸 금방 알수 있는데 이건 뭐.... ㅡㅡ
LED 킬때만 해도 센서 금방 하겠다 싶었는데 막상 해보니 관련 자료도 없고 이미 짜놓은 UART 디바이스 드라이버 소스를 보니 되게 막막하네.
혹시 간단한 센서를 S5PV210 칩에서 구동시켜본 사람 있으면 조언좀 부탁할게..
요약 1. 커널 및 파일시스템 포팅 완료.
2. 이제 디바이스 드라이버를 작성하고 안드로이드 어플리케이션에서 구동시키기 위해 JNI소스 짜고 테스팅 완료.
3. BUT 실제 센서를 이용해보려구 하니 다시 또 막막.... 답답한 마음에 일단 글을 올려봄.. 잘 아는분이 있다면 헬프
P.S 디시는 처음와보는데 나처럼 임베디드에 관심있는 학생이 많더라구...
혹시 망고보드를 처음 해보는 학생이 있다면 도움이 되라고 밑에 관련 소스를 올릴게
전체적인 시나리오
1. 어플리케이션에서 JNI library호출
2. JNI library 소스를 참고해보면 저수준 입출력 파일 호출 사용 (커널 시스템 콜)
3. /dev/mango210_led_device 에서 사용할 디바이스 드라이버의 MAJOR_NUMBER, MINOR_NUMBER를 읽어들임.
4. device driver 소스 실행 => 하드웨어 작동
빌드 방법
1. mango210LED.c파일은 Make해준다. (Makefile이 없을경우 Makefile을 만들어야 된다.)
2. 안드로이드 project폴더에서 jni 폴더를 만든뒤 JNI소스와 Android.mk파일을 넣은뒤 ndk-build수행. (Android.mk파일 소스)
1. 어플리케이션에서 JNI library호출
2. JNI library 소스를 참고해보면 저수준 입출력 파일 호출 사용 (커널 시스템 콜)
3. /dev/mango210_led_device 에서 사용할 디바이스 드라이버의 MAJOR_NUMBER, MINOR_NUMBER를 읽어들임.
4. device driver 소스 실행 => 하드웨어 작동
빌드 방법
1. mango210LED.c파일은 Make해준다. (Makefile이 없을경우 Makefile을 만들어야 된다.)
obj-m := mango210LED.o
KDIR := //커널의 주소
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mango210LedApp
LOCAL_SRC_FILES := mango210LedApp.c
include $(BUILD_SHARED_LIBRARY)
3. project 폴더에 ..../libs/armeabi 폴더가 생성되고 lib파일명.so파일이 생성되었음을 확인한다.
4. 이클립스 상에서 새로고침을 누르고 .so파일이 인식되었는지 확인을 하고 아래 소스를 작성후 Ctrl+F11 빌드 및 실행을 한다.
5. 가상머신에서 정상적으로 동작이 되면 망고보드로 .apk파일과 .so파일을 각각 /system/app, /system/lib폴더로 옮겨준다. (옮기기 전에 chmod로 권한 변경을 해주자)
6. nfs부팅후 insmod 명령으로 디바이스 드라이버 모듈은 삽입하고 mknod /dev/mango210_led_device c 240 2를 실행해준다. chmod 777 /dev/mango210_led_device
7. 앱을 실행한뒤 동작을 확인한다.
4. 이클립스 상에서 새로고침을 누르고 .so파일이 인식되었는지 확인을 하고 아래 소스를 작성후 Ctrl+F11 빌드 및 실행을 한다.
5. 가상머신에서 정상적으로 동작이 되면 망고보드로 .apk파일과 .so파일을 각각 /system/app, /system/lib폴더로 옮겨준다. (옮기기 전에 chmod로 권한 변경을 해주자)
6. nfs부팅후 insmod 명령으로 디바이스 드라이버 모듈은 삽입하고 mknod /dev/mango210_led_device c 240 2를 실행해준다. chmod 777 /dev/mango210_led_device
7. 앱을 실행한뒤 동작을 확인한다.
/*
* mango210LED.c 디바이스 드라이버 소스
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/gpio.h>
#include <plat/gpio-cfg.h>
MODULE_LICENSE("Dual BSD/GPL");
#define MANGO210_LED_MAJOR_NUMBER 240
#define MANGO210_LED_DEVICE_NAME "mango210_led_device"
// int (*open) (struct inode *, struct file *);
int mango210_led_open(struct inode * inode_p, struct file * file_p)
{
printk("[DEV] mango210_led_open() major:%d, minor:%d\n",
MAJOR(inode_p->i_rdev), MINOR(inode_p->i_rdev));
return 0;
}
// int (*release) (struct inode *, struct file *);
int mango210_led_release(struct inode * inode_p, struct file * file_p)
{
printk("[DEV] mango210_led_release()\n");
return 0;
}
static void led_1_on(void)
{
gpio_set_value(S5PV210_GPJ4(0), 0);
}
static void led_1_off(void)
{
gpio_set_value(S5PV210_GPJ4(0), 1);
}
// int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
int mango210_led_ioctl(struct inode * inode_p, struct file * file_p,
unsigned int command, unsigned long argument)
{
printk("[DEV] mango210_led_ioctl() command:%x, argument:%x\n", command, (int)argument);
switch(command)
{
case 1:
if(0 == argument)
{
printk("[DEV] IND LED 1 Control, Off\n");
led_1_off();
}
else if(1 == argument)
{
printk("[DEV] IND LED 1 Control, On\n");
led_1_on();
}
else
{
printk("[DEV] Invalid IOCTL Argument: %x\n", (int)argument);
return -1;
}
break;
default:
printk("[DEV] Invalid IOCTL Command: %x\n", command);
return -1;
break;
}
return 0;
}
struct file_operations mango210_led_file_oper =
{
.owner = THIS_MODULE,
.open = mango210_led_open,
.ioctl = mango210_led_ioctl,
.release = mango210_led_release,
};
int mango210_led_init(void)
{
int retVal,err,num=0,num1;
printk("[DEV] mango210_led_init() is called.\n");
err = gpio_request(S5PV210_GPJ4(num), "GPJ4");//GPG1 request
if (err) {
printk(KERN_INFO "GPJ4(%d) request error : %d\n",num, err);
} else {
s3c_gpio_setpull(S5PV210_GPJ4(num), S3C_GPIO_PULL_NONE);
gpio_direction_output(S5PV210_GPJ4(num), S3C_GPIO_OUTPUT);
}
led_1_on();
retVal = register_chrdev(MANGO210_LED_MAJOR_NUMBER, MANGO210_LED_DEVICE_NAME, &mango210_led_file_oper);
printk("[DEV] return value: %d\n", retVal);
gpio_free(S5PV210_GPJ4(num));
gpio_free(S5PV210_GPH1(2));
UART는 커널에 붙어있거나 이미 디바이스 드라이버 있을테니 또 짤 필요없고 /dev/ttyS2 라던지 해서 시리얼 포트 사용하듯이 그냥 열어서 쓰면 된다 어떤 디바이스노드가 해당 UART에 연결되어있는지는 문서 찾아보면 설명되어있을겨
글고 전체적인 시나리오 라고 적어놓은걸 보니 아직 리눅스 시스템에 대한 이해도가 부족한게 아닌가 싶은데 디바이스 드라이버 책 좀 다시 봐야할 것 같다
표준장비인데 뭘 고민함? 써서 작동하면 옳은 것
음.. 고마워 형들 좀더 기본적인 공부를 더 해야겠네
표준장비 드라이버는 내가 만드네 누가 만드네 고민고민하지마 걸~
근데 표준장비 드라이버를 arm보드에서 이용할때 예를들어 i2c,adc,uart /dev폴더에 있는 device파일을 이용해서 이미 만들어진 디바이스 드라이버를 열고 저수준 입출력 함수를 이용해서 다루는 것은 이해를 하겠는데 사용하기 전에 레지스터 세팅이 필요하잖아? AVR같은경우는 이제 많은 책에 세팅방법이 잘 설명이 되어있는데 이거는 그런 자료를 찾기가 힘드네
그래서 이제 kernel 폴더에 /device/serial 관련 파일을 참조해서 사용해보려구 했는데 쉽게 감이 안와서 질문글을 올렸어 우선 리눅스 디바이스 드라이버 책이랑 데이터 시트를 좀더 살펴본후에 다시 시도해봐야 겠다 형들 말을 들어보니
답글 고마워 형들
그러니까 그 레지스터 설정을 하는 부분이 이미 디바이스 드라이버에 다 짜져있을테니까 그냥 쓰면 된대두
ㄴ 아 레지스터 설정도 디바이스 드라이버에 다 되어 있구나.. ㅡㅡ 소스 확인해바야겠다