본문 바로가기
RaspberryPi

[Raspberry Pi Kernel] Kernel의 시스템 콜 함수를 활용한 GPIO LED 제어

by TYB 2024. 2. 16.
반응형
 

[Ubuntu-RaspberryPi] C언어로 U-Boot gpio제어를 통한 led 동작 및 버튼 제어

구현 목표는 led 0xff 명령어를 치면 이름 이니셜을 띄워주면서 led 작동시키고 button을 누르면 8개의 버튼 중 해당 버튼에 맞게 O X를 출력해주고 해당 버튼에 맞는 led만 on시켜주기 + 8번 버튼 누르

program-developers-story.tistory.com

기존 코드를 수정하여 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

 

 

 

 

 

 

 

 


 

vi 로 무언가를 수정하고 있을 때 저장하지 않았더라도 실시간으로 swp파일로 저장되고 있음.

 

 

만약 정전이나 컴퓨터가 원치 않게 꺼졌을 경우 저 파일을 통해서 복구가 가능함

:recover 명령어를 주면 swp에 저장되어 있는 값이

한번 비정상적으로 종료되면 swp파일이 안지워짐. :recover를 통해 복구해도 swp파일은 안지워짐

사용자가 삭제해줘야함

 

 


 

vim 코드 들여쓰기 하는법

 

ctrl+v 눌러서 블록지정 해주고 화살표로 움직여서 범위 지정하고 =을 누르면 자동으로 들여쓰기해줌 ㄷㄷ; 신세계네

 

pi@pi08:~/systemcall_test $ ./syscall_app
input value = 1

 

 


 

 

 

 

반응형