들어가며
내가 이번에 C언어 중간점검을 우리 반 내에서 1등을 했다고 한다. 오호라!! (대충 신나서 엉덩이 춤추는 농담곰 이모티콘 GIF) 나 되게 틀린 문제가 많은데 (만점 44점 중에서 28점 … 100점 만점에 68점) 꽤나 좋은 점수를 받아서 내심 기분이 좋았다. 그래도 주말간 정리했던 것처럼 C에서 아직 내가 구석구석 모르는 부분들이 많이 등장하는 것 같아서 C 기초를 열심히 다져놔야겠다는 생각이 계속 든다.
ㅤ
강사님이랑 이번에 내 백그라운드를 얘기하면서 어떤 부분에 집중하면 좋을지에 대해서 질문을 남겼는데, 생각보다 자존감이 좀 올라가는 답변을 들었다. 기존에 내가 앱개발을 했었기 때문에 OS 위의 내용들이 나의 강점이라고 생각하는데, 그렇다면 OS 위에서 돌아가는 APP 계층의 C++로 작성되는 계층에 집중하는게 좋을지? 아니면 로우 레벨로 내려가서 개발을 할 때에도 이런 고수준의 객체지향적인 설계를 한 경험이 충분히 어필이 될지에 대해서 질문을 드렸다. (하고싶은건 HW에 가까운 개발인데, 앱개발 경험이 이런 분야에 비벼보는데에 도움이 될 지 불안해서 물어봤다 ㅋㅋ)
ㅤ
그런데 강사님께서는 오히려 고수준까지 다뤄봤고 저수준을 준비한다면 SW에서 할 수 있는 모든 영역을 다 경험해본 거라고 볼 수 있어서 굉장히 좋은 경험을 한 거라고 볼 수 있을 것 같다 말씀해주셨다. (듣고보니 그러네, 열심히 살았는데 박성민?) 그리고 최종 프로젝트에서 결국에 로우레벨에서 처리한 것을 사용자에게 유의미하게 전달하려면 고수준의 UI라거나 프로그램을 작성해야 할텐데, 이런 곳에서 C++ 같은 역량을 충분히 발휘하고 어필할 수 있을 것 같다고 말씀해주셨다.
ㅤ
이 말을 듣고나니깐 고수준의 SW를 작성해본 적 있다는 나의 백그라운드가 정말 여기 클래스 내에서는 경쟁력 있는 챠-밍 포인트가 될 수 있겠다는 생각이 들어서 조금 더 열심히 해야겠다는 뽐뿌가 오고 있다. 어쩌면 내가 정말 폭넓은 지식과 경험을 두루 갖춘 능력자일지도…?!
- 컴퓨터공학 전공 → SW 개발에 대한 지식 갖춤
- 회로에 대한 공부 → 전자공학 지식을 갖춤
- 앱개발 경험 → 고수준 서비스에 대한 개발 경험 가지고 있음
- ARM 아키텍처 공부 → 완전 저수준의 HW와 OS의 동작에 대해 파악하고 있음
ㅤ
인생 열심히 살아오기 잘했다. 더 열심히 살아내보자!!
ㅤ
오늘의 키워드
AP : Application Processor
MPU : Memory Protection Unit
MMU : Memory Management Unit (MPU 확장판)
ㅤ
C언어를 만든 이유
- 하드웨어를 직접 제어할 수 있으면서도, 어셈블리어보다는 추상화 수준이 높은 언어가 필요
- 메모리 주소를 직접 다루고, 비트 연산을 수행하며, 인터럽트를 처리할 수 있는 언어가 필요
- 운영체제를 만들기 위해서 만들어진 언어. 그래서 C를 이용하면 대부분 할 수 있다.
ㅤ
임베디드, 항공, 자동차 같은 분야에서는 시스템의 안정성이 중요함.
fetch-decode-execute를 정상적으로 수행할 수 없는 시점이 Exception 이다.
신호 또는 명령어를 fetch, decode 할 때 노이즈가 포함되어 있으면 이를 exception으로 잘 처리하는 것이 중요하다. (Exception Handling)
ㅤ
음수의 표현
음수를 표현하기 위한 방법이 3가지 있다! (2가지 아니였냐고)
- 1’s complement
- 음수를 bit 뒤집기로 표현
- 일부 머신에서 여전히 사용 (사장된 방식 아님)
- 2’s complement
- 음수를 양수와 더하면 0이 되는 값으로 표현 (뒤집고 +1)
- 정수의 부호 표현을 위해서 대부분 사용하는 방식.
- signed-magnitude
- MSB에 signed / 뒤에 크기
- 실수의 부호 표현을 위해서 대부분 사용하는 방식.
- 실수는 magnitude의 연산이 복잡하니깐 FPU를 co-processor로 사용
ㅤ
char의 특징
char 는 환경에 따라서 signed / unsigned 가 될 수 있다. 이건 ASCII가 7bit로 표현 가능한 문자이기 때문임. (signed, unsigned 라도 어차피 MSB는 버리기 때문에 문제 없음). 이게 char의 구현이 Implemented-Defined Behaviour 이기 때문에 환경마다 다르게 구현해도 되는 내용임 … Behaviour에 관련된 내용은 여기)
ㅤ
혹시 char를 값으로 사용할거라면 signed, unsigned를 명확하게 표시하고 사용해주어야 함.
이게
int8_t,uint8_t를 사용하려는 좋은 예시라 생각된다!
ㅤ
다시 한 번 소프트웨어 계층

미들웨어의 종류
- 멀티미디어 미들웨어
- 파일시스템 미들웨어
- Device Driver 인터페이스
- Communication 미들웨어
ㅤ
C언어에서의 변수가 담기는 메모리 영역
이건 보고도 자꾸 까먹는 것 같다. 아무래도 반복 학습이 안되어서 그런 것 같다. 그치만, 여전히 중요한 내용이라는건 변함없다.
초기화된 전역변수 RW data
초기화 안된 전역변수 (0) BSS (RW Data)
const 변수 RO data
함수 내에 선언된 Static 변수 BSS (RW Data)
함수 내에 선언된 지역변수 Stack
동적 할당된 변수 Heap
ㅤ
예전에 정리했던 BSS를 다시 들고왔다. 왜냐면? 이 키워드가 기억이 안났었거든.
BSS가 뭐냐
BSS (Block Started By Symbol)
- 초기화 안된 전역변수, static 변수가 저장되는 영역
- 메모리를 효율적으로 사용하기 위해 사용 / 0으로 초기화할 변수들을 위한 별도의 공간
- BSS에는 어차피 처음에는 0으로 채워지니깐, 크기 정보만 담고있으면 됨.
- 만약 이걸 stack에 넣는다고 하면, 실행파일에 배열에 대한 정보가 포함되어야함
⇒ 배열의 크기가 4MB라고하면, 실행파일의 크기가 4MB가 넘어가야함. 그런데, bss 영역에 넣어주면 이걸 os가 알아서 할당하고 초기화해주기 때문에 런타임 할당을 실행파일의 책임이 아닌 OS의 책임으로 넘길 수 있음 + 실행파일의 크기를 그만큼 줄일 수 있음. (임베디드 저장 공간 아끼기) - (딱히 속도 측면에서 중요해서 사용하는건 아님)
높은 주소
┌─────────────┐
│ 스택 │ ← 지역변수, 함수 매개변수
├─────────────┤
│ ↓ │
│ │
│ ↑ │
├─────────────┤
│ 힙 │ ← 동적 할당 메모리
├─────────────┤
│ BSS │ ← 초기화되지 않은 전역/정적 변수
├─────────────┤
│ 데이터 │ ← 초기화된 전역/정적 변수
├─────────────┤
│ 텍스트 │ ← 실행 코드
└─────────────┘
낮은 주소
ㅤ
MCU에서의 메인 메모리는 SRAM이다.
이번에 ARM Processor Architecture 를 공부하려고 다시 PDF를 펼쳐서 클로드와 티키타카를 하면서 문서를 읽어보고 있었는데, 메인 메모리에 대한 이야기가 나오는 것을 읽고 있었다. 그런데, 메인 메모리가 CPU (정확히는 MCU 칩) 내부에 있다고 해서 + MCU 보드의 구조에 RAM 이라는 키워드가 없어서, 약간 의아한 상태로 열심히 검색을 해봤다. 그러고 몇 가지 충격적인 것들을 발견했다. 약간 “내 세상이 무너졌어” 모먼트라서 기록으로 남기고 있다. 아마 조만간 ARM Architecture 포스팅 시리즈의 첫번째 글에서 만날 수 있을 내용들이다.
ㅤ
일단 내가 기존에 알고있던 DRAM과 SRAM
- DRAM은 작고 저렴하지만 데이터가 소멸할 수 있어서 주기적으로 Refresh가 필요함. 엑세스 시간이 비교적 느리지만 많이 쌓을 수 있어서(집적하기 좋음) 주로 메인 메모리로 사용.
- SRAM은 크고 비싸지만 따로 데이터 유지를 위한 처리가 필요하지 않음. 엑세스 시간이 빠르지만 크게 만들기 어렵고 비싸서 주로 캐시 메모리로 사용.
ㅤ
그런데 임베디드같은 MCU의 메인 메모리는 막 1GB 이렇게 클 필요도 없고, 오히려 엑세스 시간이 더 중요하기 때문에 메인 메모리를 SRAM으로 만든다는거임!!! 홀리쓋!!!
ㅤ
그런데 더 나아가서, CPU와 메인 메모리의 엑세스 시간을 줄여서 더 빠르게 연산을 처리하기 위해서 MCU 칩 (STM32F429~ 이름을 가진 보드 가운데에 박혀있는 그 프로세서)에다가 아예 메인 메모리를 내장해버린다. 만약에 메인 메모리 용량이 좀 더 컸으면 하는 사람들을 위해서 칩 외부에 (보드 위에) RAM을 익스텐션처럼 추가할 수 있는 기능을 제공한다.
ㅤ
메인 메모리가 무조건 DRAM이고, CPU와 분리된 칩으로서 보드에 박혀있을거라는 나의 고정관념을 완전히 부숴버린 내용이라서 기록을 남긴다. 후…
ㅤ
RTOS와 OS의 관계
이번에 잠깐 스터디를 진행하다가 OS와 RTOS의 관계가 비슷해졌다. 나의 궁예로는 RTOS라는건 특정 시간 내에 Task가 완료되는 것을 목적으로 하기 때문에 “일반적인 OS에서 Task Scheduling 부분만 떼어내어 MCU의 OS로 활용하는 것” 이라고 생각하고 있었는데, 이게 맞는지에 대한 팩트체크가 필요하다고 생각되었다.
ㅤ
우선 목표부터 살펴보자
- OS : 전체 시스템의 처리량을 최대화 하는 것이 목표. 여러 작업을 적당히 빠르게 처리하기.
- RTOS : 정해진 시간 내에 작업 완료를 보장하는 것이 목표. 빠르게는 중요하지 않음. 정확한 시간 내에 처리할 수 있는 것이 RTOS의 지향점.
ㅤ
RTOS의 특징
- 같은 입력 → 같은 시간에 결과를 내는 것이 목표 (충격이 가해지면 항상 10ms 내에 에어백을 터뜨리기)
- 작은 Context Switching : Task의 전환이 매우 빨라야 한다 = 컨텍스트를 바꾸기 위해 드는 노력이 작아야 할 것 같군
- 우선순위 : 우선순위 역전 방지 메커니즘을 통해 급한 것을 항상 먼저 처리하도록 하기.
ㅤ
결국 RTOS도 OS의 하위분류인데, 공평하게 작업을 분배(Round Robin)하는 일반적인 OS과는 다르게 우선순위를 기반으로 스케줄링을 진행한다는 특징을 가진다.
ㅤ
그치만 RTOS가 Task Scheduling 만 수행하는 것은 아니다. RTOS도 OS로서의 책임을 다 한다! 다만 일반적인 OS에 비해서 훨씬 라이트하게 기능들을 수행한다. 왜냐면 무거우면 Task의 시간 내 완료를 보장하지 못할 수 있으니깐. 즉, RTOS는 Real-Time 요구사항에 특화된 완전한 OS라고 보아야 한다.
- Task 관리
- 메모리 관리 (동적 메모리 할당 + 메모리 보호…MMU)
- 동기화와 통신
- 인터럽트 처리
- 타이머 관리
- I/O 관리
'TIL' 카테고리의 다른 글
| [251102] Day 83 - 시간이 많이 흘렀구려 (0) | 2025.11.02 |
|---|---|
| [251021] Day 71 - 겨울이 온 것 같아요 (0) | 2025.10.22 |
| [251018] Day 68 - 텔레칩스 임베디드 스쿨 2개월차 회고이자 리뷰이자 후기 (1) | 2025.10.19 |
| [251017] Day 67 - Cㅂ 또 까먹었네 (0) | 2025.10.18 |
| [251016] Day 66 - 또다시 시작되어버린 임베디드와의 전쟁 (0) | 2025.10.18 |