상수 포인터: 다른 주소값을 가리키도록 바꿀 순 있으나, 그 주소에 있는 값을 바꿀 순 없음.
포인터 상수: 다른 주소값을 가리키도록 바꿀 수 없으나, 그 주소에 있는 값을 바꿀 순 있음.
포인터 선언
변수타입* 변수명; 변수타입 * 변수명; 변수타입 *변수명 = 주소값;
으로 선언할 수 있습니다. (*이 어디 붙어도 상관없습니다.)
int a = 10
int* b = &a;
연산자
& 연산자(주소 연산자)
&변수
이렇게 사용할 수 있다.
int a = 10;
print("%p", &a); // %p 는 주소값을 출력할 때 사용합니다.
이런 식으로 & 연산자를 사용하게 되면 변수 a의 주소값이 출력됩니다.
* 연산자(참조 또는 역참조 연산자)
* 연산자는 뒤에 오는 주소값에서 그 주소에 담겨있는 값에 접근하는 데 사용합니다.
*변수
예를 들어 "*&변수"를 하게 되면 변수의 주소값에서 그 주소에 담겨있는 값을 가져오게 되므로 변수의 값이 나오게 됩니다.
int a = 948;
int* b = &a;
printf("%p %d\n", &a, *&a);
printf("%p %d", b, *b);
결과는
(a의 주소값) 948
(a의 주소값) 948
이 나오게 됩니다.
포인터 연산
포인터의 덧셈과 뺄셈
포인터의 덧셈
int a = 50;
int *b = &a;
char c = 'c';
char* d = &c;
printf("%p\n", b); //0061FF14
printf("%p\n", d); //0061FF13
printf("%p\n", b + 1); //0061FF18
printf("%p", d + 1); //0061FF14
* 포인터 간의 덧셈은 안됩니다. (쓸 이유가 없음)
* 포인터에 x만큼 더하면 주소값은 (x * 자료형) 만큼 늘어납니다.
포인터의 뺄셈
int a[2] = {50, 100};
int *a1 = a;
int *a2 = a + 1;
printf("%d\n", *a);
printf("%d\n", *(a + 1));
printf("%p %d\n", a1, *a1);
printf("%p %d\n", a2, *a2);
printf("%d\n", a2 - a1);
* 배열 자체는 배열의 첫 번째 주소를 나타내므로 *a는 배열의 첫 번째 항목, *(a+1)은 배열의 두 번째 항목이 됩니다.
* a1은 배열의 첫 번째 항목의 주소, a2는 배열의 두 번째 항목의 주소이므로 a2-a1은 배열의 두 번째 항목과 첫번째 항목의 주소의 차가 됩니다.
* a2 - a도 똑같이 첫번째 항목과 두번째 항목의 주소의 차가 되고 이걸 이용하면 a2가 배열에서 위치한 위치를 알 수 있습니다.
* lowerbound나 upperbound를 사용할 때 반환값에서 배열을 빼면 검색한 항목의 위치(index)를 알 수 있습니다.
포인터의 곱셈과 나눗셈
불가능합니다.
Call By Value
#include <stdio.h>
void test(int a){
a = 10;
printf("in test function, variable a value: %d\n", a); //10
}
int main()
{
int a = 90;
printf("before invoke test function, variable a value : %d\n", a); //90
test(a);
printf("in main function, variable a value: %d", a); //90
return 0;
}
함수의 인자에 변수의 값을 복사해서 전달해준다.
함수 내에서 값을 바꿔도 원래 변수의 값이 변하지는 않는다.
Call By Reference
#include <stdio.h>
void test(int *a)
{
*a = 10;
printf("in test function, variable a value: %d\n", *a); //10
}
int main()
{
int a = 90;
printf("before invoke test function, variable a value : %d\n", a); //90
test(&a);
printf("in main function, variable a value: %d", a); //10
return 0;
}
함수의 인자에 변수의 주소값을 전달해준다.
함수에서 참조 연산자를 이용해서 값을 바꾸면 원래 변수의 값도 변한다.
다중 포인터
포인터도 변수이므로 포인터에 대한 주소값을 저장하는 포인터를 만들 수 있습니다.
이것을 다중 포인터라 부르게 됩니다. 아래 예시를 보면
int a = 10;
int *b = &a;
int **c = &b;
printf("%p %p %p\n", &a, b, *c);
printf("%d %d %d", a, *b, **c);
포인터 c는 포인터 b의 주소값을 저장하는 2중 포인터인 것을 알 수 있습니다.
포인터를 선언할 때 변수타입* 변수명; 으로 한다고 했었는데 int **c = &b;에서 (int*)가 자료형이 됩니다.
자료형*변수명=주소값;
int * *c = &b;
3중 포인터 예시를 보면
int a = 10;
int *b = &a;
int **c = &b;
int ***d = &c;
printf("%p %p %p %p\n", &a, b, *c, **d);
printf("%d %d %d %d", a, *b, **c, ***d);
1. GENERAL DESCRIPTIONS The W25Q32JV (32M-bit) Serial Flash memory provides a storage solution for systems with limited space, pins and power. The 25Q series offers flexibility and performance well beyond ordinary Serial Flash devices. They are ideal for code shadowing to RAM, executing code directly from Dual/Quad SPI (XIP) and storing voice, text and data. The device operates on 2.7V to 3.6V power supply with current consumption as low as 1µA for power-down. The W25Q32JV array is organized into 16,384 programmable pages of 256-bytes each. Up to 256 bytes can be programmed at a time. Pages can be erased in groups of 16 (4KB sector erase), groups of 128 (32KB block erase), groups of 256 (64KB block erase) or the entire chip (chip erase). The W25Q32JV has 1,024 erasable sectors and 64 erasable blocks respectively. The small 4KB sectors allow for greater flexibility in applications that require data and parameter storage. (See Figure 2.) The W25Q32JV supports the standard Serial Peripheral Interface (SPI), and a high performance Dual/Quad output as well as Dual/Quad I/O SPI: Serial Clock, Chip Select, Serial Data I/O0 (DI), I/O1 (DO), I/O2, and I/O3. SPI clock frequencies of up to 133MHz are supported allowing equivalent clock rates of 266MHz (133MHz x 2) for Dual I/O and 532MHz (133MHz x 4) for Quad I/O when using the Fast Read Dual/Quad I/O instruction
32M-bit => 4MB 크기의 플래시 메모리이며 SPI 인터페이스를 사용하는 것을 알 수 있었습니다.
컴퓨터(또는 MCU)의 전원이 켜질 때 일반적으로 램(RAM)에 운영 체제가 없습니다. 그래서컴퓨터는 적은 양의 필요한 데이터와 함께 롬(ROM)에저장된 작은 프로그램을 실행하여 운영체제를 보조 기억 장치에서 RAM에 로드합니다.
이 작업을 하는 작은 프로그램을부트 로더라고합니다.
기능
1. 직렬 통신, 인터럽트, 타이머, 콘솔, 메모리, 각종 입출력 장치 등을 점검하여 실행 가능 상태로 만들어 줍니다.
2. 화면에 내용을 출력해서 사용자 인터페이스 기능을 합니다.
3. 커널을 메모리(RAM)에 로드시켜서 사용자 명령 처리를 준비하는 역할을 합니다.
부트로더의 종류
U-Boot(Universal Bootloader)
PPCBoot와 ARMBoot 프로젝트 기반
LILO(Linux Loader)
GRUB(Grand Unfied Bootloader)
Loadlin
EtherBoot
Blob
ARM용 부트로더
PMON(PROM Monitor)
MIPS 보드용
RedBoot
RedHat에서 개발 및 배포
eCos 기반
커널
운영체제의 핵심으로 하드웨어와 응용프로그램 사이에서 보안, 자원관리, 추상화를 해줍니다.
파일 시스템
운영체제에서 파일이나 자료를 쉽게 접근할 수 있도록 보관 또는 조직하는 체계
아이노드(inode): UFS와 같은 유닉스 계통 파일 시스템에서 사용하는자료구조이며, 정규파일,디렉터리등파일 시스템에 관한 정보를 가지고 있습니다.
파일 시스템 내에서 파일이나 디렉토리는 고유한 inode 를 가지고 있으며, inode 번호를 통해 구분이 가능합니다.
컴퓨터에서 파일을 저장할 때 하드디스크에 연속적으로 저장하는것이 아닌 파일들을 조각으로 나눠서 저장하게 되는데, 그 파일들이 어디있는지를 기록해 둬야 합니다.
파일 시스템 종류
FAT(File Allocation Table)
볼륨의 맨 위에 FAT 이라는 테이블이 있고 그 테이블에 파일의 할당 정보를 저장합니다.
파일을 섹터 단위로 나누면 파일이 너무 작게 나눠지기 때문에 적당히 작게 나누기 위해서 클러스터를 사용합니다.
FAT 뒤에 숫자는 클러스터 ID를 저장하는데 사용하는 비트 수 입니다. 그래서 최대 표현 가능한 클러스터 수와 연관이 되어 있습니다.
NTFS(New Technology File System)
윈도우 NT부터 기본적으로 사용되는 파일 시스템으로, 클러스터 ID를 저장하는데 64비트를 사용합니다.
FAT과 달리 테이블을 사용하지 않고 B+ tree를 사용하여 탐색 속도가 빨라졌습니다.
그리고 아래에 나오는 저널링 파일 시스템을 사용하여 안정성이 높아졌습니다.
파일을 압축하여 보관하거나, 접근 권한을 제어하는 등 여러가지 기능이 생겼습니다.
하지만 윈도우만 생각하고 만들어서 호환성이 좋진 않습니다.
exFAT(EXtended File Allocation Table)
NTFS의 호환성 문제를 해결하기 위해서 만들어진 파일 시스템입니다.
FAT 에서 클러스터 ID를 저장하는데 사용하는 비트 수가 64비트로 바뀌었습니다.
EXT(EXTended file system)
리눅스 운영 체제를 위해서 만들어진 파일 시스템입니다.
Extended File System을 줄여 extfs 또는 ext로 씁니다.
부트섹터와 여러개의 블록 그룹으로 이루어져 있습니다.
부트섹터에는 부팅에 필요한 정보들이 담겨있고, 블록은 클러스터와 비슷한 역할을 수행합니다.
블록 그룹은 Super Block, Group Descript Table(GDT), Block Bitmap, Inode Bitmap, Inode Table, Data의 구조로 구성되어 있습니다.
EXT2,정식 이름은 Second Extended File System입니다. 이 파일 시스템은 ext의 문제를 해결하기 위해 나온 파일 시스템입니다.
ext2 파일 시스템은 255자까지의 긴 파일 이름을 지원합니다. ext2 파일 시스템은 세 타임스탬프를 지원하며, 확장이 쉽습니다. 그리고 ext에 있었던 여러 단점(분리 접근, 아이노트 수정 등 지원 안 함)도 개선되었습니다. 파일 시스템의 최대 크기는 블록 사이즈에 따라 2 TiB ~ 32 TiB이며, 서브 디렉터리 개수 제한은 32768개입니다.
EXT3는 ext2에 저널링 파일 시스템, 큰 디렉터리를 위한 HTree인덱싱 등의 기능이 추가되었습니다. ext3는 ext2를 바탕으로 만들었기 때문에, ext2 파일 시스템을 자료 손실 없이 ext3 파일 시스템으로 바꿀 수 있습니다.
EXT4
64비트 기억 공간 제한을 없애고 ext3의 성능을 향상하며, 하위 호환성이 있는 확장 버전으로서, 많은 부분이 본래, 러스터파일 시스템을 위해 클러스터 파일 시스템스사에서 개발되었습니다. 여러가지 장점이 있지만 너무 길기 때문에 작성하지 않겠습니다.
JFFS(Journalling Flash File System)
파일 시스템에 반영될 변경 사항을 주기적으로 로그로 남겨 비정상 종료가 발생하면 저널은 저장되지 않은 정보를 복구하기 위한 검사 지점으로 사용되어 파일 시스템 메타자료 손상을 막아줍니다.
즉, 일정부분을 기록을 위해 남겨두고, 그 부분에 기록을 남겨 백업 및 복구 능력이 있는 파일 시스템을 말하며,
시스템 충돌 후에 파일시스템 복구에 드는 시간이 획기적으로 줄어듭니다.
JFFS2
이름부터 JFFS2 인 만큼 JFFS에서 여러가지 새로운 점이 추가가 되었습니다.
1. NAND 플래시 지원
2. zlib, rubin, rtime 이 세 종류 압축 알고리즘 지원
3. 성능 향상
YAFFS(Yet Another Flash File System)
NAND플래시를 위해서 설계된 파일시스템 입니다.
JFFS가 모든 페이지에 대해서 데이터를 읽어야 한다는 초기화 알고리즘의 단점을 극복하기 위해 파일의 메타데이터인 아이노드를 한 페이지에 저장하는 방법을 사용하고 있습니다.