기존 코드를 수정하여 LED 제어 시스템 콜 함수로 구현하기 (U-Boot 부트로더 LED, 버튼상태 O,X 출력 예제 응용)
*KERNEL에서 제공하는 GPIO API
우리가 사용할 API에 대해 나열하겠음.
이 함수들은 #include <linux/gpio.h>에 있음.
int gpio_request(unsigned gpio, const char *label);
void gpio_free(unsigned gpio);
int gpio_direction_input (unsigned gpio);
int gpio_direction_output (unsigned gpio, int value);
void gpio_set_value(unsigned gpio , int value );
int gpio_ get_value (unsigned gpio);
int gpio_to_irq(unsigned gpio);
void free_irq(unsigned int *irq, void* dev_id);
위치를 한 번 찾아보자면
ubuntu@ubuntu8:~/pi_bsp/kernel/linux/Documentation$ locate gpio > temp.txt
ubuntu@ubuntu8:~/pi_bsp/kernel/linux/Documentation$ vi temp.txt
ubuntu@ubuntu8:~/pi_bsp/kernel/linux/Documentation/driver-api/gpio$ grep gpio_re quest *
시스템 콜 함수부터 수정해주겠음.
ubuntu@ubuntu8:~/pi_bsp/kernel/linux/kernel$ cp test_mysyscall.c test_mysyscall.c_v0
ubuntu@ubuntu8:~/pi_bsp/kernel/linux/kernel$ vi test_mysyscall.c
테스트 용이므로 빠르게 코딩을 위해 핀번호 하드코딩 했슴다~ 좀따 최적화할게유
#include <linux/kernel.h>
#include <linux/gpio.h>
#define OFF 0
#define ON 1
asmlinkage long sys_mysyscall(long val)
{
// printk(KERN_INFO "Welcome to WCM's Embedded System!! app value=%ld\n",val);
int ret = 0; //함수들의 리턴값 저장용 변수
ret = gpio_request(6,"led0");
if(ret < 0){//리턴값이 음수라면
printk("Failed gpio_request() gpio%d error \n",6); //printk는 뒤에 반드시 \n 개행문자가 들어가야함
//fail되는 경우는 이미 사용중이거나 없는 gpio 번호이거나 둘 중 하나
return ret; //대부분의 에러코드는 양순데 커널에서는에러 발생 시 음수를 리턴하게 되어잇음.
}
ret = gpio_direction_output(6,0);//출력모드로 설정 및 초기값 0으로 부여
if(ret < 0){
printk("Failed gpio_direction_output() gpio%d error \n",6);
return ret;
}
gpio_set_value(6,val);
return 1;
}
ubuntu@ubuntu8:~/pi_bsp/kernel/linux$ ./build.sh
ubuntu@ubuntu8:~/pi_bsp/kernel/linux$ cp arch/arm/boot/zImage /srv/nfs/zImage
라즈베리파이로 넘어가서
pi@pi08:/mnt/ubuntu_nfs$ sudo cp zImage /boot/firmware/kernel7l.img
pi@pi08:/mnt/ubuntu_nfs$ sync
pi@pi08:/mnt/ubuntu_nfs$ sudo reboot
pi@pi08:/mnt/ubuntu_nfs$ ./syscall_app 1 하면 6번 led가 켜져야함
근데 여러번 하면 안켜지네?
왜냐?
gpio_free를 안해줘서 gpio resource를 잡고 있기 때문이죠?
추가해주고 다시빌드해서 다시 반복
이제는 여러번 반복해도 gpio 사용중이라는 에러는 안뜸!
이제는 깜빡거리도록 코드를 변경하고 싶음.
pi@pi08:~ $ cd systemcall_test/
pi@pi08:~/systemcall_test $ ls
syscall_app syscall_app.c
pi@pi08:~/systemcall_test $ vi syscall_app.c
pi@pi08:~/systemcall_test $ cat syscall_app.c
#include <stdio.h>
#include <unistd.h>
#include <asm-generic/unistd.h>
#pragma GCC diagnostic ignored "-Wunused-result"
int main()
{
long i;
int flag=0;
printf("input value = ");
scanf("%ld",&i);
flag = i;
do{
i = syscall(__NR_mysyscall,flag);
if(i<0)
{
perror("syscall");
return 1;
}
if(flag==0)flag = 1;
else flag=0;
sleep(1);
}while(1);
printf("mysyscall return value = %ld\n",i);
return 0;
}
pi@pi08:~/systemcall_test $ gcc syscall_app.c -o syscall_app
pi@pi08:~/systemcall_test $ ./syscall_app
input value = 1
우분투에서 컴파일 하고 싶으면
pi@pi08:~/systemcall_test $ arm-linux-gnueabihf-gcc syscall_app.c -o syscall_app
이렇게 실행시키면 1초에 한번씩 켜졌다가 꺼지는 2Hz 코드로 바뀐다.
만약 더 적은 딜레이를 주고싶다?
usleep을 주면 micro-sleep이 가능함. 계산해서 쓰시길
0.5초는 usleep(500000);
8개 다 키는 코드 짜보겠음.
자 우분투로 가서
복사본 하나 만들고 커널쪽 코드 수정 드갑시다.
ubuntu@ubuntu8:~/pi_bsp/kernel/linux/kernel$ cp test_mysyscall.c test_mysyscall.c_v1
ubuntu@ubuntu8:~/pi_bsp/kernel/linux/kernel$ vi test_mysyscall.c
#include <linux/kernel.h>
#include <linux/gpio.h>
#define OFF 0
#define ON 1
int gpioLed[] = {6,7,8,9,10,11,12,13};
asmlinkage long sys_mysyscall(long val)
{
// printk(KERN_INFO "Welcome to WCM's Embedded System!! app value=%ld\n",val);
int ret = 0; //함수들의 리턴값 저장용 변수
int i;
int gpioLedCnt;
char gpioNameBuff[10];//led0\0까지 계산해서 5갠데 여유롭게 준거임.
gpioLedCnt = sizeof(gpioLed)/sizeof(gpioLed[0]);
for(i=0;i<gpioLedCnt;i++)
{
sprintf(gpioNameBuff,"led%d",i);
ret = gpio_request(gpioLed[i],gpioNameBuff);
if(ret < 0){
printk("Failed gpio_request() gpio%d error \n",6);
return ret;
}
ret = gpio_direction_output(gpioLed[i],OFF);
if(ret < 0){
printk("Failed gpio_direction_output() gpio%d error \n",6);
return ret;
}
}
for(i=0;i<gpioLedCnt;i++)
{
gpio_set_value(gpioLed[i],(val>>i) & 0x1);//입력을 0xff처럼 받아서 1비트씩 비교해서 val를 써주면 됨
}
for(i=0;i<gpioLedCnt;i++)
{
gpio_free(gpioLed[i]);
}
return 1;
}
ubuntu@ubuntu8:~/pi_bsp/kernel/linux/kernel$ cd ..
ubuntu@ubuntu8:~/pi_bsp/kernel/linux$ ./build.sh
ubuntu@ubuntu8:~/pi_bsp/kernel/linux$ cp arch/arm/boot/zImage /srv/nfs/zImage
이제 라즈베리파이로 가서 커널 이미지 넣어주고 재부팅해서 적용시켜주시고
sudo cp zImage /boot/firmware/kernel7l.img
sync
sudo reboot
#include <stdio.h>
#include <unistd.h>
#include <asm-generic/unistd.h>
#pragma GCC diagnostic ignored "-Wunused-result"
int main()
{
long i;
int flag=0;
printf("input value = ");
scanf("%ld",&i);
flag = i;
do{
syscall(__NR_mysyscall,i);
if(i<0)
{
perror("syscall");
return 1;
}
if(flag==0)flag = 1;
else flag=0;
printf("i=%d ",i);
usleep(500000);
i= ~i & 0xff;//8bit만 보겠다는 거임. 나머진 필요없음.
}while(1);
printf("mysyscall return value = %ld\n",i);
return 0;
}
pi@pi08:~/systemcall_test$ gcc syscall_app.c -o syscall_app
pi@pi08:~/systemcall_test$ ./syscall_app
input value = 255
0.5초마다 255으로 주면 전체가 켜졌다가 꺼지고
1111 1111을 계산해보면 255니까 이렇게 준거임.
어쨋든 계산해서 10진수로 입력 넣어주면 됨.
명령행 인수로 받게 수정해보겠음.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <asm-generic/unistd.h>
#pragma GCC diagnostic ignored "-Wunused-result"
int main(int argc,char *argv[])
{
if(argc<2)
{
printf("Usage: %s ledvalue[0x00~0xff]",argv[0]);
return 1;
}
unsigned long i;
int flag=0;
// printf("input value = ");
// scanf("%ld",&i);
i=strtoul(argv[1],NULL,16);
flag = i;
do{
syscall(__NR_mysyscall,i);
if(i<0)
{
perror("syscall");
return 1;
}
if(flag==0)flag = 1;
else flag=0;
printf("i=%d ",i);
usleep(500000);
i= ~i & 0xff;//8bit만 보겠다는 거임. 나머진 필요없음.
}while(1);
printf("mysyscall return value = %ld\n",i);
return 0;
}
pi@pi08:~/systemcall_test $ gcc syscall_app.c -o syscall_app
pi@pi08:~/systemcall_test $ ./syscall_app 0xff
이렇게 해주면 바로 깜빡거림
pi@pi08:~/systemcall_test $ ps -ef |grep syscall_app
pi 2406 2242 0 13:17 pts/1 00:00:00 vi syscall_app.c
pi 2424 2327 0 13:21 pts/0 00:00:00 grep --color=auto syscall_app
pi@pi08:~/systemcall_test $ w
13:21:57 up 1:25, 5 users, load average: 0.00, 0.09, 0.11
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
pi - 11:56 1:25m 47.20s 1.13s /usr/bin/wayfir
pi tty1 - 11:56 1:25m 0.10s 0.08s -bash
pi ttyS0 - 11:56 9:08 0.17s 0.14s -bash
pi pts/0 10.10.15.58 13:15 4.00s 0.36s 0.13s w
pi pts/1 10.10.15.58 13:13 4:21 0.16s ? vi syscall_app.
pi@pi08:~/systemcall_test $ last
pi pts/0 10.10.15.58 Fri Feb 16 13:15 still logged in
pi pts/1 10.10.15.58 Fri Feb 16 13:13 still logged in
pi pts/0 10.10.15.58 Fri Feb 16 11:58 - 13:13 (01:15)
pi ttyS0 Fri Feb 16 11:56 still logged in
pi tty1 Fri Feb 16 11:56 gone - no logout
pi Fri Feb 16 11:56 gone - no logout
reboot system boot 6.1.77-v7l+ Fri Feb 16 11:56 still running
pi ttyS0 Fri Feb 16 11:46 - down (00:09)
pi tty1 Fri Feb 16 11:44 - down (00:11)
pi Fri Feb 16 11:44 - down (00:11)
reboot system boot 6.1.77-v7l+ Fri Feb 16 11:44 - 11:56 (00:11)
pi pts/0 10.10.15.58 Fri Feb 16 10:19 - 11:44 (01:25)
pi ttyS0 Fri Feb 16 09:25 - down (02:19)
pi tty1 Fri Feb 16 09:25 - down (02:19)
pi Fri Feb 16 09:24 - down (02:19)
reboot system boot 6.1.77-v7l+ Fri Feb 16 09:24 - 11:44 (02:19)
pi Fri Feb 16 09:24 - down (00:00)
pi Fri Feb 16 09:24 - down (00:00)
pi Fri Feb 16 09:24 - down (00:00)
pi Fri Feb 16 09:24 - down (00:00)
pi Fri Feb 16 09:24 - down (00:00)
pi Fri Feb 16 09:24 - down (00:00)
pi Fri Feb 16 09:24 - down (00:00)
pi Fri Feb 16 09:24 - down (00:00)
pi Fri Feb 16 09:24 - down (00:00)
pi Fri Feb 16 09:24 - down (00:00)
pi Fri Feb 16 09:24 - down (00:00)
pi Fri Feb 16 09:24 - down (00:00)
pi Fri Feb 16 09:24 - down (00:00)
pi Fri Feb 16 09:24 - down (00:00)
pi Fri Feb 16 09:24 - down (00:00)
pi Fri Feb 16 09:24 - down (00:00)
pi Fri Feb 16 09:24 - down (00:00)
pi Fri Feb 16 09:24 - down (00:00)
pi Fri Feb 16 09:23 - down (00:00)
pi Fri Feb 16 09:23 - down (00:00)
pi Fri Feb 16 09:23 - down (00:01)
pi Fri Feb 16 09:23 - down (00:01)
pi Fri Feb 16 09:23 - down (00:01)
pi Fri Feb 16 09:23 - down (00:01)
pi Fri Feb 16 09:23 - down (00:01)
pi Fri Feb 16 09:23 - down (00:01)
pi Fri Feb 16 09:23 - down (00:01)
pi Fri Feb 16 09:23 - down (00:01)
pi Fri Feb 16 09:23 - down (00:01)
pi Fri Feb 16 09:23 - down (00:01)
pi Fri Feb 16 09:23 - down (00:01)
pi Fri Feb 16 09:23 - down (00:01)
pi Fri Feb 16 09:23 - down (00:01)
pi Fri Feb 16 09:23 - down (00:01)
pi Fri Feb 16 09:23 - down (00:01)
pi Fri Feb 16 09:23 - down (00:01)
pi Fri Feb 16 09:23 - down (00:01)
pi Fri Feb 16 09:23 - down (00:01)
pi Fri Feb 16 09:22 - down (00:01)
pi Fri Feb 16 09:22 - down (00:01)
pi Fri Feb 16 09:22 - down (00:02)
pi Fri Feb 16 09:22 - down (00:02)
pi Fri Feb 16 09:22 - down (00:02)
pi Fri Feb 16 09:22 - down (00:02)
pi Fri Feb 16 09:22 - down (00:02)
pi Fri Feb 16 09:22 - down (00:02)
pi Fri Feb 16 09:22 - down (00:02)
pi Fri Feb 16 09:22 - down (00:02)
pi Fri Feb 16 09:22 - down (00:02)
pi Fri Feb 16 09:22 - down (00:02)
pi Fri Feb 16 09:22 - down (00:02)
pi Fri Feb 16 09:22 - down (00:02)
pi Fri Feb 16 09:22 - down (00:02)
pi Fri Feb 16 09:22 - down (00:02)
pi Fri Feb 16 09:22 - down (00:02)
pi Fri Feb 16 09:22 - down (00:02)
pi Fri Feb 16 09:22 - down (00:02)
pi Fri Feb 16 09:22 - down (00:02)
pi Fri Feb 16 09:21 - down (00:02)
pi Fri Feb 16 09:21 - down (00:02)
pi Fri Feb 16 09:21 - down (00:03)
pi Fri Feb 16 09:21 - down (00:03)
pi Fri Feb 16 09:21 - down (00:03)
pi Fri Feb 16 09:21 - down (00:03)
pi Fri Feb 16 09:21 - down (00:03)
pi Fri Feb 16 09:21 - down (00:03)
pi Fri Feb 16 09:21 - down (00:03)
pi Fri Feb 16 09:21 - down (00:03)
pi ttyS0 Fri Feb 16 09:21 - down (00:03)
pi Fri Feb 16 09:21 - down (00:03)
pi Fri Feb 16 09:21 - down (00:03)
pi Fri Feb 16 09:21 - down (00:03)
pi Fri Feb 16 09:21 - down (00:03)
pi Fri Feb 16 09:21 - down (00:03)
pi Fri Feb 16 09:21 - down (00:03)
pi Fri Feb 16 09:21 - down (00:03)
pi Fri Feb 16 09:21 - down (00:03)
pi Fri Feb 16 09:21 - down (00:03)
pi Fri Feb 16 09:21 - down (00:03)
pi Fri Feb 16 09:20 - down (00:03)
pi Fri Feb 16 09:20 - down (00:03)
pi Fri Feb 16 09:20 - down (00:04)
pi Fri Feb 16 09:20 - down (00:04)
pi Fri Feb 16 09:20 - down (00:04)
pi Fri Feb 16 09:20 - down (00:04)
pi Fri Feb 16 09:20 - down (00:04)
pi Fri Feb 16 09:20 - down (00:04)
pi Fri Feb 16 09:20 - down (00:04)
pi Fri Feb 16 09:20 - down (00:04)
pi Fri Feb 16 09:20 - down (00:04)
pi Fri Feb 16 09:20 - down (00:04)
pi Fri Feb 16 09:20 - down (00:04)
pi Fri Feb 16 09:20 - down (00:04)
pi Fri Feb 16 09:20 - down (00:04)
pi Fri Feb 16 09:20 - down (00:04)
pi Fri Feb 16 09:20 - down (00:04)
wtmp begins Fri Feb 16 09:20:09 2024
만약 정전이나 컴퓨터가 원치 않게 꺼졌을 경우 저 파일을 통해서 복구가 가능함
한번 비정상적으로 종료되면 swp파일이 안지워짐. :recover를 통해 복구해도 swp파일은 안지워짐
사용자가 삭제해줘야함
vim 코드 들여쓰기 하는법
ctrl+v 눌러서 블록지정 해주고 화살표로 움직여서 범위 지정하고 =을 누르면 자동으로 들여쓰기해줌 ㄷㄷ; 신세계네
pi@pi08:~/systemcall_test $ ./syscall_app
input value = 1
'RaspberryPi' 카테고리의 다른 글
[Raspberry Pi Kernel] Kernel의 시스템 콜 함수를 활용한 GPIO Button, LED 제어 (0) | 2024.02.16 |
---|---|
[Raspberry Pi Kernel] Kernel menuconfig로 GPIO enable하고 다시 LCD 켜기 (0) | 2024.02.16 |
[RaspberryPi Kernel] Ubuntu에서 Raspberry Pi Kernel system call 함수 구현 (0) | 2024.02.15 |
[RaspberryPi4 Kernel] Ubuntu에서 BCM2711 커널 빌드해서 올리기 (0) | 2024.02.15 |
[Raspberry Pi] 작업한 이미지 복제하기 (2) | 2024.02.02 |