1. 정수형

%d : 부호 있는 10진수 (signed형의 정수형 변수, 상수)

%u : 부호 없는 10진수 (unsigned형의 정수형 변수, 상수)

%o : 부호 없는 8진수 (signed, unsigned 구분 없이 정수형 데이터를 각 진법에 맞게 출력)

%x : 부호 없는 16진수 (signed, unsigned 구분 없이 정수형 데이터를 각 진법에 맞게 출력)


2. 실수형

%lf : 부호 있는 소수점 형태(실수형 변수, 상수)

%le : 부호 있는 지수 형태(실수형 변수, 상수)


3. 문자형

%c : 하나의 문자(char형 변수, 문자상수)


4. 문자열

%s : 문자열 (char형 배열의 이름, 문자열 상수)

int val;
int *ip = &val;    //포인터를 포인터변수에 저장한다
변수 val의 값 : **&ip

& : 주소연산자
val : int형 변수

&val : 포인터
ip : 포인터변수(int *)
&ip : 이중포인터
**&ip : 이중 포인터를 사용하여 변수의 값 참조
* : 참조연산자

이중포인터가 가리키는 것은 포인터변수이므로 참조 연산자를 사용하여 포인터변수에 저장된 포인터 값을 구함

이중포인터 변수
  : 이중 포인터가 가리키는 자료형을 파악한 후에 같은 자료형을 가리키는 포인터변수를 선언하면 됨

이중포인터 &ip는 (int *)형 변수의 포인터이므로 결국 이중포인터가 가리키는 자료형은 (int *)형이 될 것. 따라서 (int *)형을 가리키는 이중포인터변수 선언 가능

예)   
int **ipp;    //int*(가리키는 자료형), *(ipp는 포인터 변수임), ipp(변수의 이름)
int val = 10;    //int형 변수의 선언과 초기화
int *ip;              //포인터변수 선언
int **ipp;         //이중포인터변수 선언
ip = &val;         //int형 변수의 포인터를 포인터변수에 저장
ipp = &ip;         //포인터변수의 포인터를 이중포인터변수에 저장
printf("변수 val의 값 : %d\n", **ipp);    //참조연산자를 두 번 사용하여 참조한다.


1. 배열명을 사용한 배열 표현

   : aa[0];


2. 배열명을 사용한 포인터 표현

   : *(aa+0);


3. 배열명을 저장한 포인터 변수를 사용한 포인터 표현

   : int *ap = aa;     

     ap+0;


4. 배열명을 저장한 포인터 변수를 사용한 배열 표현

   : int *ap = aa;     

     ap[0];


* 배열요소는 참조하는 기본 방식이 포인터 계산에 의한 것이므로 계산 결과가 같다면 표현 형태는 얼마든지 바뀔 수 있음


예) *(ary) == *ary == *(ary+0)

     ary[1] == *(ary+1) == *(1+ary) == 1[ary]

 
#include <stdio.h>

void trot(int trots[], int n);

void main()
{
    int aa[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
    int size = sizeof(aa) / sizeof(*aa); // 전체크기 / 원소크기 = 원소개수

    printf("size of %d\n", size);
    trot(aa, size);
}

void trot(int trots[], int n)
{
    int i;

    for(i = 0; i < n; i++)
        printf("%d\n", trots[i]);
}
 
inline 함수는 프로그램의 실행 속도를 높이기 위해서 c++에 추가된 기능이며 쉽게 이해하기 위해 매크로 함수와 비교해 보면 좋다.


예를 들어 아래와 같이 SQUARE라는 매크로를 만들어 사용할 경우,


 
#define SQUARE(x) ((X)*(X))

int main(void)
{
	 std::cout << SQUARE(5) << std::endl;
	 return 0;
}
 


실제 프로그램 실행 시 main 함수의 SQUARE를 사용하게 될 경우 define된 주소로 점프 하여 실행 후 다시 원래로 돌아온다.


하지만 인라인 함수의 경우 전처리이기 아래와 같이 사용 하게 되면, 컴파일 시 인라인 함수가 코드 안에 삽입 되기 때문에 실제 main함수에서 SQUARE를 사용 시 삽인된 코드가 바로 실행 되기 때문에 속도도 빠르고 효율적이다.


 
inline int SQUARE(int x)
{
	 return x*x;
}

int main(void)
{
	 std::cout << SQUARE(5) << std::endl;
	 return 0;
}
 

1. 문자형을 숫자형으로

atoi​,atol,atof는 문자열을 숫자로 바꾸어 주는 함수이다.

사용하기 위해서 stdlib.h 이 헤더를 호출해야 한다.


 
include <stdlib.h>
 


 -. atoi는 ascii to integer --> 문자열을 int형

 -. atol은 ascii to long --> 문자열을 long형

 -. atof는 ascii to float --> 문자열을 double형으로 바꾸어 준다.


​앞에 -가 올 경우도 그대로 출력해 주고 문자나 띄어쓰기를 만나면 그 전까지의 숫자를 모두 바꾸어 준다.

또 시작하자마자 문자를 만날 경우 0을 반환한다.


간단한 예제를 살펴보자!


 
#include 
int main()
{
   char buf1[10], buf2[10];
   int num1, num2;
   
   memset(buf1, 0x00, sizeof(buf1));
   memset(buf2, 0x00, sizeof(buf2));
   
   sprintf(buf1, "20");
   sprintf(buf2, "30");
   num1 = atoi(buf1);
   num2 = atoi(buf2);
   
   printf("num1 + num2 = %d \n", num1+num2);
   
   return 0;
} 
 



2. 숫자형을 문자형으로

 -. itoa : integer 값을 2진, 8진, 10진, 16진 문자열로 변환합니다.

 -. ltoa : long 값을 2진, 8진, 10진, 16진 문자열로 변환합니다.

 -. ultoa : unsigned long 값을 2진, 8진, 10진, 16진 문자열로 변환합니다.

 -. fcvt : 실수(고정 소수점:float) 값을 문자열로 변환합니다.

 -. ecvt : 실수(부동 소수점:double) 값을 문자열로 변환합니다.

 -. gcvt : 실수 값을 부호와 소수점을 포함하여 문자열로 변환합니다.

1. 카메라 동작확인
  -. PiCAM 구입 후 파란색이 USB, 은색이 hdmi쪽을 향하게 모듈을 삽입한다.
  -. sudo raspi-config 명령어에서 5번 메뉴 camera를 enable시킨다.
     (안되면 sudo apt-get update, sudo ap-get upgrade 선행)
  -. 메뉴를 빠져나오면서 재부팅을 한다.
  -. raspistill -o image.jpg 라고 입력하여 이미지가 잘 생성되는지 확인한다.

2. 먼저 필요한 라이브러리를 설치
   $ sudo apt-get install libjpeg8-dev imagemagick libv4l-dev

3. build시 필요한 파일을 include해 두기
   $ sudo ln -s /usr/include/linux/videodev2.h /usr/include/linux/videodev.h

4. mjpg-streamer 소스를 받는다
  -. Git에서 받아도 되고 검색해서 일반 사이트에서 받아도 된다.

5. 빌드
   $ cd mjpg-streamer-code-182/mjpg-sreamer
   $ make mjpg_streamer input_file.so output_http.so (Makefile에서 필요한거 주석 풀어준다)
  (위에가 귀찮으면 make clean all)

6. 주요 library root로 복사
   $ sudo cp mjpg_streamer /usr/local/bin
   $ sudo cp outpu_http.so input_file.so /usr/local/lib/
   $ sudo cp -R www /usr/local/www

7. stream이 될 jpg파일이 저장될 폴더 생성
   $ mkdir /tmp/stream

8. 실행
   $ raspistill --noreview -w 640 -h 480 -q 5 -o /tmp/stream/pic.jpg -tl 100 -t 9999999 -th 0:0:0 & (임시 저장 폴더에 이미지를 반복하여 저장)
   $ LD_LIBRARY_PATH=/usr/local/lib mjpg_streamer -i "input_file.so -f /tmp/stream -n pic.jpg" -o "output_http.so -w /usr/local/www"

9. 포트 변경
기본 포트는 8080으로 mjpeg stream 서버가 열리는데 이를 바꿔 주기 위해서는 -p 옵션을 사용한다.
   $ LD_LIBRARY_PATH=/usr/local/lib mjpg_streamer -i "input_file.so -f /tmp/stream -n pic.jpg" -o "output_http.so -p 8888 -w /usr/local/www"

*동작원리는 mjpeg용 서버를 열어서 실제 웹페이지에서는 해당 서버의 스트리밍을 받아서 사용.(포트가 겹치지 않도록 주의)


참고 사이트 :

http://jskorl.blog.me/220379225762


1. 툴체인 받기
   $ git clone https://github.com/raspberrypi/tools raspi_toolchain

2. 툴체인 환경 변수에 추가
   $ cd raspi_toolchain
   $ cp -av  arm-bcm2708/ /opt/toolchains/
   $ vi ~/.bashrc
   
* 추가 내용
export PATH="$PATH:/opt/toolchains/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian:/opt/toolchains/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin"
추가 후 저장 종료

   $ source ~/.bashrc
   $ echo $PATH   <-- 잘 적용 됬는지 확인

3. 소스 받기
   $ git clone --depth=1 https://github.com/raspberrypi/linux raspi_kernel

4. 소스 빌드
   $ cd raspi_kernel

   $ KERNEL=kernel7
   $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig
   $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs(-j n옵션으로 빠르게 빌드 가능)


Target board에서 Kernel build!!

1. Source 받기
   $ git clone --depth=1 https://github.com/raspberrypi/linux

2. bc라는 패키지 설치(근데 이게 먼지 찾아봐도 모르겠음..)
   $ sudo apt-get install bc

3. Build configuration 설정
 -. 라즈베리파이 1은...
   $ cd linux
   $ KERNEL=kernel
   $ make bcmrpi_defconfig

-. 라즈베리파이 2는...
   $ cd linux
   $ KERNEL=kernel7
   $ make bcm2709_defconfig

4. build 하기
   $ make zImage modules dtbs

5. 모듈도 build 하기
   $ sudo make modules_install

6. 빌드한거 적용하기
   $ sudo cp arch/arm/boot/dts/*.dtb /boot/
   $ sudo cp arch/arm/boot/dts/overlays/*.dtb* /boot/overlays/
   $ sudo cp arch/arm/boot/dts/overlays/README /boot/overlays/
   $ sudo scripts/mkknlimg arch/arm/boot/zImage /boot/$KERNEL.img

* 라즈베리파이 2는 kernel7.img 로 복사한다.


라즈베리 파이의 부팅 순서는 다음과 같다.


1. 보드에 전원이 들어오고 GPU가 활성화된다.

2. SoC 내 ROM에 있는 첫번째 부트로더(Firmware)를 읽어들인다.

3. 첫번째 부트로더가 SD카드에 있는 두번째 부트로더(bootcode.bin)을 호출한다.

4. 두번째 부트로더가 SD카드에 있는 config.txt를 읽고 실행한다.

4. 두번째 부트로더가 세번째 부트로더(start.elf)를 호출 및 실행하여, ARM Core를 활성화한다.

6. ARM Core가 활성화되면 네번째 부트로더(kernel.img)를 호출, 실행한다.

+ Recent posts