2023. 4. 12. 10:23ㆍ[Harman] 세미콘(semiconductor) 아카데미-반도체설계/임베디드 시스템을 위한 SW 구조설계
저번시간에 공부한 개념 복습 및 함수, 연산자, 플로팅연산을 공부하였고 STM32CubeIDE를 이용한 디버깅 사용법 숙지하였다.
- 하드웨어는 가산과 승산으로만 이루어져있다.
- 맨 끝자리 비트수를 이용하여 부호 표현을 할 수 있다.
signed -
unsigned
- 통신 코드 작성 시 BCD코드 + 3을 한 express3 코드를 많이 사용한다
- 헌팅턴 가설 = 2진수 연산을 하기 위한 가설
- 드모르간 정리 - 회로설계 시 AND게이트 -> OR게이트 / OR게이트 -> AND게이트로 바꿀 때 자주 사용
- 반가산기 = 2개의 비트를 더하면 CARRY발생
- 전가산기 = 반가산기를 2개 합친 것 (전가산기를 합쳐 ALU(덧셈회로)를 만든다)
https://www.st.com/en/microcontrollers-microprocessors/stm32f411re.html#tools-software
STM32보드를 이용한 디버거를 정상적으로 사용하기 위해서는 STM32CubeIDE와 STM32CubeProg를 다운로드해야한다.
- 전처리기(Preprocesser)
#을 이용한 명령어들을 "전처리기" 라 한다. 전처리기(Preprocesser)는 프로그램을 컴파일할 때 컴파일 직전에 실행되는 별도의 프로그램이다.
프로그램의 실행 흐름이나 변수의 값에 영향을 주지 않는다.
- define
#define A B (#define 상수 상수의 값)의 형태로 사용된다. A라는 상수를 만들어 B라는 값을 넣는다는 뜻이다. 이 define으로 설정한 상수는 ROM에 저장된다. define 을 이용하여 함수 또한 상수명에 집어넣을 수 있다.
- include
#include는 컴파일러에게 명령을 알려주는 "의사 명령어"이다.
#include는 <oo>과 "oo"의 2가지 방법으로 사용가능하다. < >과 " "의 차이는 해당 헤더파일이 존재하는 경로의 차이이다.
- #include < > = 컴파일러가 설치된 폴더에서 < >안의 헤더파일을 찾으라는 지시
- #include " " = 사용자의 프로젝트 폴더나 개발자가 추가한 디렉토리로 지정해준 경로에서 찾으라는 명령어 / 개발자가 만든 헤더파일이나 추가로 외부 라이브러리를 코드에 추가하고 싶은 경우 " "을 이용하여 추가한다.
컴파일러안의 해더파일 경로는 STM32CubeIDE를 통해 설정가능하다.
위의 경로를 통해 우리가 사용하는 프로젝트의 헤더파일의 디렉토리 주소를 알 수 있고, 헤더파일 경로를 추가할 수 있다. (<>의 경로에 해당) -> 해당 기능을 통해 경로를 지정해주면 소스코드상으로 <>로 지정해주지 않아도 해당 헤더파일 사용 가능
프로젝트 - Properties에서 헤더파일 경로 지정 이외에도 프로그램 안의 링크, 빌드 등의 디렉토리주소를 알 수 있다.
- 조건부 컴파일
앞에서 본 #define 전처리기는 상수를 "매크로"라고도 부른다. 형태는 #define 매크로 매크로값 으로도 볼 수 있다.
# 이후 if문을 이용하여 코드를 작성할 수도 있다.
[#if ... #endif]
기존 C언어에서 사용하는 if문과 같은 개념이다. 대신 중괄호({ })를 사용하지 않고 #endif를 통해 #if의 끝을 알린다.
#if - debug 매크로 값이 2보다 이상이면 debug 2를 출력해야하지만 2보다 작은 1의 값을 가지므로 false라 출력하지 않는다. 다음 #if 1은 true값을 가지므로 1을 출력하고 #if 0은 false로 0을 출력하지 않는다. 다음 #endif를 통해 구문을 끝낸다. #if를 사용할 때는 반드시 #endif문이 존재해야한다.
컴퓨터는 true와 false를 구별하는 법이있다.
false = 0
true = 0 이외의 값
[#ifdef ... #endif]
#if는 매크로가 참인지 거짓인지를 기준으로 작동하였지만 #ifdef는 매크로가 정의되어 있는지 아닌지를 기준으로 동작한다.
debug는 정의되어있고 time은 주석처리했기 땨문에 정의되어 있지 않아 #ifdef문에서 debug쪽만 코드를 수행하게 되었다.
[#ifndef ... #endif]
[#ifdef ... #endif]가 매크로가 정의되어 있는지 아닌지를 기준으로 동작한다면 [#ifndef ... #endif]는 반대로 정의되어 있지 않다면 동작하고 정의되어있으면 동작하지 않는 구문이다.
정의된 debug는 실행되지 않고 주석처리하여 정의되지 않는 time은 정상실행되는 것을 확인할 수 있다.
[#else / #elif]
기본 if문의 else와 동일하게 #if, #ifdef, #ifndef에도 #else를 이용 가능.
[#if안에 사용하는 defined 연산자]
defined 연산자는 괄호안의 매크로가 존재하는지 판단한다.
[미리 정의되어 있는 매크로]
C언어에는 컴파일러가 참고해야 할 정보를 알려주기 위해 몇개의 매크로를 미리 정의하여 제공하고 있다. 미리 정의된 매크로는 #define 으로 정의하지 않아도 사용 가능하나, 사용자가 재정의할 수는 없다.
미리 정의된 매크로 | 설명 |
__DATA__ | 컴파일러가 코드를 실행한 날짜를 "Mmm dd yy" 형식으로 나타낸 문자열 |
__TIME | 컴파일러가 코드를 실행한 시간을 ""hh:mm:ss"형식으로 나타낸 문자열 |
__FILE__ | 현재 소스코드의 파일명을 나타내는 문자열 |
__LINE__ | 현재 소스파일의 행 번호를 나타내는 상수 |
STM32CubeIDE에서 코드 작성 후 디버깅할때는 코드 입력 후 좌측 행 번호를 더블클릭하면 디버깅할 breakpoint를 설정할 수 있다.
해당 디버깅 창에서 Expressions - 알아볼 변수의 명 입력하면 breakpoint에 해당하는 순간의 그 변수의 값을 볼 수 있다.
좌측부터 "재연결 / 디버깅(breakpoint기준) / 디버깅 중지 / 연결해제 / 코드 한줄씩 실행 / breakpoint기준 코드 실행
디버깅창에선 SFRs에서 MCU, Peripheral의 주소값과 할당값 또한 볼 수 있다.
- static변수 (정적변수)
함수내에 사용되는 지역변수는 함수를 벗어나오는 순간 메모리에서 지워진다. 그러나 static 변수를 사용하면, 함수를 나와서도 메모리에 저장되어있는 변수이다. 전역변수와 지역변수의 장점을 같이 사용 가능한 변수.
함수내에 static 변수를 선언하고 값을 넣지 않으면 초기값(0)으로 설정된다.
- 포인터 개념 개인공부
static변수 대신 포인터 변수를 사용하면 역참조 연산자를 이용해 static변수와 같이 함수를 벗어나도 메모리에 값이 저장되어 사용할 수 있다.
- 주소 연산자(&) = 변수의 주소를 나타내는 연산자
- 역참조 연산자(*) = 그 주소 내부에 있는 값에 접근하는 연산자
- 널(null)포인터 = 포인터가 아무것도 가리키지 않는다는 것을 의미 / NULL값 = 0 / 주로 포인터를 안전하게 초기화할 때 사용
ex) int *a = NULL;
- 해당 코드는 먼저 X = 100이란 변수를 선언한 후, 주소값을 저장할 포인터 연산자 ds를 선언하였다.
- 포인터 연산자 ds는 주소연산자(&)를 이용하여 x의 주소값을 입력한 후 main문에 있는 해당 함수들 plus, min의 매개변수로 넣어준다(현재 ds는 x의 주소값을 가진 상태)
- main문 밖의 함수 plus, min은 매개변수로 ds의 주소값을 받았으니 그 주소 내부에 있는 값을 받기위해 역참조연산자(*)를 사용한다
- 역참조 연산자로 받은 값을 해당 함수에 맞는 연산을 하기 위해 지역변수 a를 선언하여 값을 연산한 후 연산한 값을 다시 넣어준다
정상적으로 동작되는 것 확인.
'[Harman] 세미콘(semiconductor) 아카데미-반도체설계 > 임베디드 시스템을 위한 SW 구조설계' 카테고리의 다른 글
임베디드 시스템을 위한 SW 구조설계 6 (3) | 2023.04.18 |
---|---|
임베디드 시스템을 위한 SW 구조설계 5 (1) | 2023.04.16 |
임베디드 시스템을 위한 SW 구조설계 4 (0) | 2023.04.15 |
임베디드 시스템을 위한 SW 구조설계 2 (0) | 2023.04.08 |
임베디드 시스템을 위한 SW 구조설계 1.2 (0) | 2023.04.08 |