Devin.KR

CPU·메모리·주변장치의 경계

75분 안팎

학습 목표

CPU·RAM·저장장치·GPIO와 HAL 호출 경계를 구성도로 제출합니다.

개념

기록기의 위치를 먼저 그립니다

센서 값을 저장하는 코드와 핀을 켜는 코드가 같은 일을 한다고 생각하면 보드가 바뀔 때 버퍼까지 고치게 됩니다. 앞 모듈의 Buffer는 Sample 16개와 length를 소유했습니다. 이번에는 이 저장 정책을 유지하면서 바깥 환경의 입력·출력·시간을 분리합니다. 먼저 누가 값을 보관하고 누가 장치 상태를 바꾸는지를 그려야 함수 이름만 바꾼 추상화에 머물지 않습니다. 구성도는 그림 솜씨가 아니라 변경 책임을 확인하는 작업입니다.

이 모듈은 Python 3 브라우저 실습과 로컬 C 실습을 사용합니다. Python은 8비트 계산 모형이며 보드 프로그램이 아닙니다. C는 gcc 명령을 제공하는 컴파일러·make·Python 3 표준 라이브러리로 실행합니다. 각 압축 파일을 독립 폴더에 풀고 Makefile이 있는 위치에서 make test를 입력합니다. starter에는 의도한 동작 오류가 있어 일부 검사가 실패합니다. 구현을 수정하고 같은 테스트가 통과하는지 확인하며 테스트 기대값은 바꾸지 않습니다.

따라하기의 C 출력은 solution을 임시 폴더로 복사해 직접 실행한 결과입니다. make -s는 명령 표시를 줄이지만 프로그램 출력까지 숨기지는 않습니다. 맥의 gcc가 Apple Clang일 수 있으므로 사용한 컴파일러를 기록합니다. 하드웨어 주소를 PC에서 역참조하지 않으며 가짜 레지스터는 유효한 RAM 객체로 만듭니다. 이번 실행은 전압이나 실제 핀 파형의 증거가 아닙니다. 외부 패키지나 실물 보드 없이 논리 계약을 반복 검증합니다.

CPU와 세 종류의 저장을 나눕니다

CPU는 명령을 실행하고 계산을 수행합니다. 코드가 놓이는 저장 영역과 계산 중 값을 담는 RAM은 역할이 다릅니다. MCU에서는 프로그램을 비휘발성 플래시에 저장하는 구성이 흔하지만 구체적인 배치는 링크 설정과 보드에 달려 있습니다. static이나 const라는 C 키워드 하나로 물리적인 플래시 주소를 확정할 수는 없습니다. 구성도에는 프로그램 저장 영역이라고 적고 실제 보드의 배치는 메모리 맵과 링크 결과로 확인한다고 표시합니다.

RAM에는 현재 샘플, Buffer, HAL 시뮬레이터의 입력·출력 값이 존재합니다. Buffer를 사용하는 동안 객체가 살아 있어야 한다는 앞 모듈의 수명 계약은 그대로입니다. RAM에 기록했다고 전원 차단 뒤에도 남는 것은 아닙니다. 아직 파일이나 SPI 저장 장치로 복사하지 않았으므로 이번 기록기는 실행 중 보관까지만 합니다. 기록이라는 이름만 보고 영구 저장을 구현했다고 설명하면 제출물의 증거 범위를 넘습니다.

저장장치는 전원 이후 기록 보존을 담당할 수 있는 별도의 구성 요소입니다. 앞으로 SPI 저장 경로를 붙이지만 현재 미션에는 없습니다. 구성도에서 미래 연결은 예정이라고 표시합니다. UART 출력 역시 전송이며 보존을 보장하지 않습니다. PC의 stdout으로 출력했다는 사실과 보드의 플래시나 외부 장치에 저장했다는 사실을 같은 선으로 그리지 않습니다. 어디까지 구현했는지가 구성도에서 읽혀야 합니다.

GPIO는 주변장치의 디지털 입력·출력 경로입니다. 버튼은 입력 값의 출처이고 LED는 출력의 대상입니다. CPU는 GPIO 제어·상태 레지스터를 통해 값을 읽거나 출력 설정을 바꿀 수 있습니다. 레지스터라는 말은 CPU 내부 계산용 레지스터에도 쓰이지만 이 모듈은 주변장치 레지스터를 다룹니다. GPIO 출력 레지스터의 숫자와 핀에서 관측한 전압은 관련되지만 동일한 측정 대상은 아닙니다.

호출 경계와 데이터 흐름을 겹치지 않습니다

HAL은 hardware abstraction layer의 약자로 여기에서는 하드웨어 의존 동작을 함수 계약 뒤에 감추는 계층입니다. 기록기는 hal_gpio_read로 버튼의 논리 레벨을 받고 hal_gpio_write로 LED 논리 레벨을 요청하며 hal_now_ms로 시각을 얻습니다. Buffer는 이 함수들을 알 필요가 없습니다. HAL 역시 샘플 16건을 어떻게 보존할지 결정하지 않습니다. 기록 정책과 장치 접근이 서로의 내부 필드를 몰라도 연결되는 구조를 목표로 합니다.

구성도에서 호출 화살표는 기록기에서 HAL로, 장치 측 화살표는 HAL에서 GPIO와 시간원으로 향합니다. 샘플 데이터 화살표는 입력 파서에서 기록기로, 기록기에서 Buffer로 향합니다. 버튼 값이 Sample의 raw에 들어가는 것으로 그리면 서로 다른 입력을 혼동한 것입니다. raw는 센서 모형의 정수이고 버튼 레벨은 LED 표시를 위한 제어 입력입니다. 두 값의 범위와 목적을 별도 표에 적습니다.

PC에서는 실제 GPIO 대신 hal_sim.c의 input_reg와 output_reg를 둡니다. 입력 bit0은 버튼, 출력 bit1은 LED이며 두 레지스터는 독립 객체입니다. 출력 bit1을 켠다고 입력 bit1이 자동으로 바뀌는 연결은 만들지 않았습니다. reset이나 fixture 함수는 테스트가 주변 환경을 배치하기 위한 통로입니다. 애플리케이션이 fixture를 호출해 결과를 스스로 만들어 버리면 장치로부터 값을 읽는 계약을 시험할 수 없습니다.

시간도 운영체제 시계와 분리합니다. fixture가 250을 주면 hal_now_ms는 250ms를 반환합니다. 호출할 때 자동으로 1씩 증가하는 시계는 아닙니다. 같은 입력을 반복해 같은 레코드 시각을 얻으므로 시험이 결정적입니다. 실제 응답 속도 측정이나 인터럽트 주기를 구현한 결과로 해석하지 않습니다. 앞 모듈 record-buffer의 토큰별 100ms 규칙과 새 HAL의 주입 시각은 서로 다른 실행 경로로 남습니다.

주소와 쓰기 의미를 구성도에 적습니다

실물 메모리 맵 입출력은 제조사가 정의한 주소에 접근했을 때 주변장치가 반응하는 방식입니다. PC 프로세스에서 숫자 주소 0x40000000을 포인터로 바꿔 읽으면 MCU가 나타나는 것이 아닙니다. 접근 권한이 없는 주소이거나 의미 없는 위치일 수 있습니다. 이번 그림에는 실제 주소 대신 HAL 함수 이름을 표시합니다. 주소·접근 폭·예약 비트는 나중에 보드 구현이 확인할 항목으로 경계 밖에 적습니다.

레지스터가 RAM처럼 보인다는 이유로 쓰기 규칙까지 RAM과 같다고 가정하지 않습니다. 일반 RW는 쓴 값을 저장하지만 상태 플래그 중에는 1을 써야 지워지는 W1C가 있습니다. 구성도의 레지스터 상자에 접근 종류를 표시해 다음 레슨에서 어느 연산을 적용할지 판단할 준비를 합니다. 현재 GPIO 출력 모형은 일반 RW이며 상태 플래그 모형은 별도 연습입니다. 모든 GPIO가 W1C라는 뜻은 아닙니다.

시니어 리뷰에서는 화살표마다 호출자, 반환 단위, 실패 정책을 말해 보게 합니다. read의 성공은 1이며 입력 레벨 0도 정상 데이터입니다. write는 잘못된 핀이나 레벨을 거부합니다. now의 단위는 ms입니다. 반환값 0을 버튼을 안 눌렀다는 뜻으로만 설명하면 오류와 정상 레벨을 구별하지 못합니다. 구성도 옆 계약표에 함수의 상태 반환과 데이터 반환을 서로 다른 칸으로 둡니다.

제출물을 스스로 점검합니다

구성도 한 장과 계약표 한 장을 작성합니다. CPU, 프로그램 저장, RAM Buffer, GPIO 버튼·LED, HAL, 가상 시간원을 넣고 SPI 저장은 후속이라고 표시합니다. PC RAM 레지스터와 실물 레지스터 주소의 차이를 한 문장으로 적습니다. raw 0과 버튼 0과 read 실패 0을 각각 설명해 서로 다른 의미임을 확인합니다. 장치가 바뀔 때 수정될 파일은 hal 구현이고 Buffer의 용량 계약은 그대로라는 근거를 적습니다.

상자의 수만 세어 통과시키지 않습니다. 기록기에서 가짜 레지스터로 바로 가는 선이 있으면 HAL 경계를 다시 검토합니다. Buffer에서 LED로 이어진 선은 저장 모듈이 입출력을 책임지게 했다는 신호입니다. 전원 차단 뒤 데이터가 남는다고 써 두었다면 현재 구현에 영구 저장 단계가 있는지 확인합니다. 이 설계 실습은 실행 출력 대신 자신의 구성도와 책임 설명으로 완료 여부를 평가합니다.

따라하기

이전 산출물의 책임 표시

m02 미션 solution의 buffer.h와 record_main.c를 열고 Sample·Buffer·입력 파서의 책임을 세 줄로 적습니다.

두 종류의 화살표 그리기

종이에 호출 흐름과 샘플 데이터 흐름을 다른 선으로 그립니다. HAL과 Buffer 사이에는 직접 호출선을 만들지 않습니다.

교체 실험을 설명하기

PC HAL을 보드 HAL로 교체할 때 변경 파일과 보존할 계약을 표시하고 raw·버튼 레벨·상태 반환값을 구별해 계약표를 완성합니다.

확인 문제

실습

구성도와 함수 계약표를 제출합니다. CPU·프로그램 저장·RAM Buffer·GPIO·HAL·가상 시간원을 표시하고 호출선과 샘플 데이터선을 구분합니다. 예정 SPI 저장을 현재 구현과 구별하며 보드 교체 때 바꿀 파일과 PC 모형의 검증 한계를 설명합니다.

더 읽기

면접 질문

  • 특정 레지스터 비트만 바꾸는 코드를 설명해 주시면 됩니다.