< main.c >
extern int DoAdd(int, int); // -> 생략가능
extern float DoAddFloat(float, float);
int main()
{
printf("%d \r\n", DoAdd(3,4));
printf("%f \r\n", DoAddFloat(0.5, 1.5));
}
< extern.c >
int DoAdd (int a, int b)
{
return (a+b);
}
float DoAddFloat(float a, float b)
{
return(a+b);
}
- main문에서, int형 함수인 extern DoAdd 선언 구문은 생략이 가능하나, float DoAddFloat 실수형 함수 선언 구문은 생략 불가
- 그 이유는, 메모리상 정수형 저장과 실수형 저장 형식이 완전 다르기에 실수형 함수의 경우는 명확히 명시해야 한다
# static
* 외부 파일에 노출시키지 않도록 하는 함수는 static 키워드를 사용
# 코드 유지 관리 고려한 외부 변수 접근 방법
-> 헤더파일 작성
(작성중)
# CPU 내부 구조
- stm32 cpu는 현업에서 많이 사용된다
- bus와 연결된 것은 모두 IP
- Core내부 진짜레지스터, IP내부 특수 목적 레지스터
- ROM에 SFR 제어 코드가 적재되어 있음
- 코드는 ROM에, 실행은 Processor에서
- RAM에서 연산이 발생하면 Core에 Load 명령어를 통해 레지스터에 저장, 연산결과 또한 레지스터에 저장.
- Store 명령어를 통해 연산결과를 복구
- ROM에서 PC가 명령어를 전달(Instruction Fetch)
- PC가 4씩 증가하면서 명령어 패치, 명령어 수행됨
# 레지스터
R13 -> SP (스택포인터)
R14 -> LR (링크 레지스터)
R15 -> PC (프로그램 카운터)
어셈블리어 사용 시 주의! )
R0~R3, R12 : 이 레지스터들은 PUSH, POP 할 필요가 없다 (스택이 필요하지 않다)
나머지 레지스터 : 무조건 PUSH, POP을 사용해야 한다
# 매개변수
- 매개변수 네 개 까지는 레지스터에 작성이 가능하나, 다섯 개부터는 스택에 저장됨.
- int func (a, b, c, d, e) 함수의 매개변수가 이러면,
R0 <- a
R1 <- b
R2 <- c
R3 <- d
stack <- e
이렇게 저장됨.
- printf(" %#010x \r\n", a);
printf도 함수이므로 첫번째 매개변수 " %#010x \r\n"의 주소는 R0에 저장.
두번째 매개변수 a는 R1에 저장.
- 연산 결과를 반환하는 함수의 경우, 무조건 결과를 R0에 저장하고 그 값을 return
# 어셈블리어 슈도 명령어 (가짜코드)
- 상수 자체가 32bit가 되면 안됨. opcode 비트자리가 필요하기 때문.
MOV R0, #0X12345678 ; ERROR
위 코드는 에러로 발생. 이 때 슈도 명령어를 사용하면 컴파일러가 알아서 실행해준다
MOV R0, =0X12345678 ; 정상 작동
; 가짜 코드를 작성하면 컴파일러가 추가로 작성하는 코드들
LDR R0, [ PC, #offset ] ; 초과 되는 사이즈를 계산해 로드
MOV R0, #0x100 ; 해당 주소를 넘겨줌
정수의 범위가 너무 크게 되면, 안전한 곳에 저장하고 해당 위치들을 알린다.
" 레지스터만 스택에 저장 가능! "
'FW 심화 과정 > [2] STM32심화실습' 카테고리의 다른 글
0727 C프로그래밍 기초 10~13강 (0) | 2022.07.27 |
---|---|
0726 C프로그래밍 기초 1~3강 (0) | 2022.07.26 |
0722 브레드 보드의 스위치, LED를 GPIO로 제어하기 (0) | 2022.07.25 |
0720 포인터,배열의 동작구조 / 함수포인터 / 구조체 / union ~176 (0) | 2022.07.22 |
0720 형식지정자(typedef) / 매크로 ~84 (0) | 2022.07.21 |
0719 스택 / keil메모리값변화 / 포인터 ~64 (0) | 2022.07.19 |