240201

Yonggeun Park·2024년 2월 1일
0

교재 : 사물인터넷을 위한 리눅스 프로그래밍 with 라즈베리파이

Linux BSP(Board Support Package)

  1. 부트로드
  2. 커널
  3. 디바이스 드라이브
  4. 파일 시스템
BSP를 다루려면 vi 명령어에 익숙해져야한다 >> "프린트 된 것 계속 사용하면서 익숙해지기"
4개의 개념과 역할을 명확하게 알아야한다
모두 C언어를 사용한다

나만의 커널 만들기

  1. 어셈블리 코드로 LED 제어
  2. C로 부트로드에서 기능 추가
  3. 커널에서 부팅 이미지 변경 - 시스템 call 함수 이용

디바이스 드라이브 핵심 내용

인터럽트 커널타이머 등 커널에서 제공하는 API로 동작하고자 하는 형태로 만들어낸다
Qt로 디바이스 드라이브, 어플리케이션 동작

시스템 call 함수

어플리케이션으로 커널 안의 드라이브에 호출
하드웨어 제어는 저수준 입출력 함수를 봐야한다

리눅스는 네트워크 프로그램이 커널에 탑재된 상태이다

4, 5, 6장은 기본으로 공부해야한다

메모리가 버퍼에 남아있는데 그냥 라즈베리파이를 끄면 비정상적이게 된다

sudo halt

명령어로 정상 종료 해야함

라즈베리파이4 LCD 연결

랜선을 아래로 했을 때
왼쪽 위부터
1 2
3 4
5 6
... 순서인데

GND를 6번에, VCC를 2번에 결선

터치가 안먹는 오류 -> 오류가 아니라 LCD 하단부 터치 부분이 빠져있었음

GPIO(General pin input output(범용 입출력 핀)) extension 연결
p.109 참고

LED(light emitting diode)
양극은 애노우드 / 음극은 캐소우드
전류는 +에서 -로 흐른다
전류는 어디서나 같게 흐르고 / 전압은 합쳤을때 같아진다
전압이 높은 곳에서 낮은 곳으로 흐름

사람이 직접 스위치를 누르는 동작을 통해 불이 켜지고 꺼졌던 것을
mcu/cpu에게 시켜 자동(active high/low의 변화로)으로 동작하게 한다

아날로그전압신호디지털전압
3.3Vhigh1on
0Vlow0off

소스전류 : high/low
싱크전류 : 외부전력


LED의 1번 핀을 GPIO18(extension 12번째)에 연결, 10번 핀을 GND에 연결

1을 실행하면 1번이 켜지고 0을 실행하면 1번이 꺼진다

1번 핀부터 8번핀까지 각각 테스트 해 본 결과 모두 잘 켜지고 꺼진다!

LED GPIO : 6, 7, 8, 9, 10, 11, 12, 13
빨, 주, 노, 초, 파, 보, 회, 흰
Serial GPIO : 14, 15
Switch GPIO : 16, 17, 18, 19, 20, 21, 22, 23

sudo ./for_led.sh를 실행하면 하나씩 켜지고 꺼진다

for_led.sh에 vi로 들어가서
bash에서 완전한 c 문법을 하려면 for문에서 괄호를 2개 써야한다
-n : \n을 출력하지 않겠다는 뜻

high : vcc(3.3V)

for_ledkey.sh로 스위치를 확인한다

vi gpioled.c - p.121 작성한다

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>

int ledControl(int gpio)
{
        int fd;
        char buf[BUFSIZ];

        fd=open("/sys/class/gpio/export", O_WRONLY);
        sprintf(buf, "%d", gpio);
        write(fd, buf, strlen(buf));
        close(fd);

        sprintf(buf, "sys/class/gpio/gpio%d/direction", gpio);
        fd=open(buf, O_WRONLY);
        write(fd, "out", 4);
        close(fd);

        sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);
        fd=open(buf, O_WRONLY);
        write(fd, "1", 2);
        close(fd);
        getchar();

        fd=open("/sys/class/gpio/unexport", O_WRONLY);
        sprintf(buf, "%d", gpio);
        write(fd, buf, strlen(buf));
        close(fd);

        return 0;
}

int main(int argc, char **argv)
{
        int gno;

        if(argc < 2) {      // sudo 뒤에 입력을 2개 입력해야함
                printf("Usage : %s GPIO_NO\n", argv[0]);
                return -1;
        }
        gno=atoi(argv[1]);
        ledControl(gno);

        return 0;
}

echo $? 하면 리턴값을 알 수 있음
정상 종료시 0, 오류시 -1(255)
리턴은 bash가 호출해서 가지고 있다

정상적으로 닫기 전의 숫자를 리턴

c-p497 main 함수의 명령형 인수 사용(1장 반) 공부할 것
main(int argc, char* argv[](char** argv)) // 포인터 배열은 이중 포인터로 사용할 수 있다.
(argument개수, 주소안의 내용)

'6' : 1바이트 문자
"6" : 2바이트 문자열(6\0) -> %s로 표현하면 널문자가 나오기 전까지를 리턴함
널문자(\0)는 공간은 잡아먹지만 글자수에 포함하지 않는다

wiring PI 라이브러리
CPU : BCM2711

git clone https://github.com/WiringPi/WiringPi.git

./build


blink.c를 수정할 것인데

위를 참고하여 변형한다


그냥 컴파일하면 오류가 난다
옵션을 따로 넣어주는데,

-l : 라이브러리 링크 옵션

이 상태에서 ./build 하면 안되는데, 해결하려면

cd ~/gpio.d/WiringPi/wiringpi
vi wiringpi.c
768~9 주석처리

-> 오래된 내용이라 업데이트가 되지 않아 발생

profile
Dragon_muscle

0개의 댓글

관련 채용 정보