이전 글에서 사용한 p106_ledkey 폴더 복사해서 진행합니다.
ubuntu@ubuntu8:~/pi_bsp/drivers/p122_ledkey_modparam$ vi ledkey_modparam.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#define OFF 0
#define ON 1
#define GPIOLEDCNT 8
#define GPIOKEYCNT 8
static int onevalue = 1;
static char * twostring = NULL;
module_param(onevalue, int , 0);
module_param(twostring, charp, 0);
static int gpioLed[GPIOLEDCNT] = {6,7,8,9,10,11,12,13};
static int gpioKey[GPIOKEYCNT] = {16,17,18,19,20,21,22,23};
static int gpioLedInit(void);
static void gpioLedSet(long);
static void gpioLedFree(void);
static int gpioKeyInit(void);
static int gpioKeyGet(void);
static void gpioKeyFree(void);
static int gpioLedInit(void)
{
int i;
int ret=0;
char gpioName[10];
for(i=0;i<GPIOLEDCNT;i++)
{
sprintf(gpioName,"led%d",i);
ret = gpio_request(gpioLed[i],gpioName);
if(ret < 0) {
printk("Failed gpio_request() gpio%d error \n",i);
return ret;
}
ret = gpio_direction_output(gpioLed[i],OFF);
if(ret < 0) {
printk("Failed gpio_direction_output() gpio%d error \n",i);
return ret;
}
}
return ret;
}
static void gpioLedSet(long val)
{
int i;
for(i=0;i<GPIOLEDCNT;i++)
{
gpio_set_value(gpioLed[i],(val>>i) & 0x1);
}
}
static void gpioLedFree(void)
{
int i;
for(i=0;i<GPIOLEDCNT;i++)
{
gpio_free(gpioLed[i]);
}
}
static int gpioKeyInit(void)
{
int i;
int ret=0;
char gpioName[10];
for(i=0;i<GPIOKEYCNT;i++)
{
sprintf(gpioName,"key%d",gpioKey[i]);
ret = gpio_request(gpioKey[i], gpioName);
if(ret < 0) {
printk("Failed Request gpio%d error\n", 6);
return ret;
}
}
for(i=0;i<GPIOKEYCNT;i++)
{
ret = gpio_direction_input(gpioKey[i]);
if(ret < 0) {
printk("Failed direction_output gpio%d error\n", 6);
return ret;
}
}
return ret;
}
static int gpioKeyGet(void)
{
int i;
int ret;
int keyData=0;
for(i=0;i<GPIOKEYCNT;i++)
{
// ret=gpio_get_value(gpioKey[i]) << i;
// keyData |= ret;
ret=gpio_get_value(gpioKey[i]);
keyData = keyData | ( ret << i );
}
return keyData;
}
static void gpioKeyFree(void)
{
int i;
for(i=0;i<GPIOKEYCNT;i++)
{
gpio_free(gpioKey[i]);
}
}
static int hello_init(void)
{
int ret,i;
int key_data;
char ledStatus[16]="0:0:0:0:0:0:0:0";
printk("Hello, world onevalue:%d, twostring:%s \n",onevalue, twostring);
ret=gpioLedInit();
if(ret < 0)
return ret;
gpioLedSet(onevalue);
ret=gpioKeyInit();
if(ret < 0)
return ret;
key_data = gpioKeyGet();
if(key_data)
{
gpioLedSet(key_data);
printk("0:1:2:3:4:5:6:7\n");
for(i=0;i<8;i++)
{
if((key_data >> i) & 0x01)
ledStatus[i*2] = 'O';
else
ledStatus[i*2] = 'X';
}
printk("%s\n\n",ledStatus);
}
return 0;
}
static void hello_exit(void)
{
printk("Goodbye, world \n");
gpioLedSet(0x00);
// printk("led all off \n");
gpioLedFree();
gpioKeyFree();
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("KCCI-AIOT");
MODULE_DESCRIPTION("led key test module");
MODULE_LICENSE("Dual BSD/GPL");
make하고
pi@pi08:/mnt/ubuntu_nfs $ sudo insmod ledkey_modparam.ko onevalue=0xff twostring =\"hi hello\"
아무것도 매개변수를 주지않고 insmod를 하면 0x01이 출력될거임.
dmesg를 쳐보면 onevalue에 1이 default로 들어가기 때문
[15960.486236] onevalue:1 twostring: (null)
pi@pi08:/mnt/ubuntu_nfs $ sudo insmod ledkey_modparam.ko
버튼을 누른채 insmod를 하면 해당되는 led만 켜지고 dmesg에 버튼이 눌렸다고 출력된다.
pi@pi08:/mnt/ubuntu_nfs $ sudo insmod ledkey_modparam.ko
pi@pi08:/mnt/ubuntu_nfs $ sudo insmod ledkey_modparam.ko onevalue=0xff
이라믄 다 켜짐.
pi@pi08:/mnt/ubuntu_nfs $ sudo insmod ledkey_modparam.ko onevalue=0xff twostring=\"hi hello\"
이라믄 일단 led 다 켜지고
그냥 "hi hello"만 하면 hi에서 짤려서 출력됨.
hi hello를 그대로 넣기 위해 \" \"를 써서 문자열로 인식하지말라고 저장해준다.
여기서 끝내면 아쉬우니까 디버깅 메시지 띄울 때 규칙을 알아보자
120 printk(KERN_DEBUG "Hello, world onevalue:%d, twostring:%s \n",onevalue, twostring);
코드 수정하고 make한 후
pi에서 insmod 한 후 dmesg 출력해보면 커널 메시지 시간 앞에 디버깅 메시지가 나온다. 의미는 위의 표를 보고 해석하면 되겠다.
<7> [17922.957866] Hello, world onevalue:1, twostring:(null)
'Linux BSP' 카테고리의 다른 글
[Raspberry Pi Device Driver] 디바이스 드라이버(app과 dev)를 통한 device 제어 (0) | 2024.02.22 |
---|---|
[Device Driver] 변수의 데이터형과 바이트 순서와 volatile 변수 (0) | 2024.02.22 |
Makefile은 왜 사용하며, 어떻게 사용하는가 (2) | 2024.02.22 |
[RaspberryPi DeviceDriver] 디바이스 드라이버 코드 수정해서 커널에 포함시키기 (0) | 2024.02.21 |
[RaspberryPi DeviceDriver] Yocto Project 설정 초기화 및 디바이스 파일 만들어보기 (0) | 2024.02.21 |