임베디드 소프트웨어를 짜다보면 PC랑 연결해서 디버깅 해야할수도있습니다.
저는 UART통신으로 PC랑 연결해서 디버깅하려고 합니다.
임베디드 코드상에서 printf사용하면 그 내용들이 PC로 전달돼서 시리얼 통신 프로그램에 뜨도록 할 수 있습니다.
이때 printf와 비슷한 효과를 내는 fun이라는 함수를 만들어보려고 합니다.
내장함수를 사용하지않고 필요한 함수들은 만들었습니다.
일반 printf함수의 경우 가변인자로 매개변수의 개수 제한이 없습니다.
하지만 임베디드의 경우 CPU종속적이기때문에 인수의 개수는 10개로 제한하려고합니다.
# 가변인자란?
인수의 개수와 타입이 미리 정해져있지않다는 것
[조건]
1. 함수 형태는 fun(”Hello %d”, &a) 이고 a값이 123일 때 출력은 Hello 123
2. 출력 형식은 %d, %s이런거 대신 %1, %2, %4로 설정
- 1은 tU08에서 Char로
- 2는 tU16에서 Char로
- 4는 tU32에서 Char로
unsigned char은 tU08
unsigned int는 tU16
unsigned long은 tU32 로 정의했습니다.
# 함수의 매개변수가 메모리에 저장되는 방식
: stack에 little endian방식으로 저장됩니다.
함수를 호출할 경우 매개변수가 stack에 저장되고 함수가 종료될 경우 stack에서 소멸됩니다.
출력 함수 형태 : fun ("asdfas %1", arg )
문자열과 arg를 받아오는 함수이고 %1자리에 arg를 대입해야합니다.
배열로 하나씩 검사해서 %를 만나면 그 뒷자리가 1,2,4중 어떤 것인지 switch로 구분하고 각 case마다 형변환을 합니다.
숫자를 대입했을 때 문자로 바꾸는 방식 : 아스키 코드 사용
[숫자 3221을 문자 3221로 출력하기]
3221 / 1000 +0x30 = 0x33
221 / 100 +0X30 = 0x32
21 /10 +0X30 = 0x32
1 /1 +0X30 = 0x31
=> 0x33 0x32 0x32 0x31을 문자로 출력해보면 3221로 출력되는 것을 확인할 수 있습니다.
작성한 코드는 github에 올려뒀습니다.
! 코드 오류 발생
1. error: conflicting types for '함수이름' : 함수의 위치가 잘못돼서 발생한 오류입니다.
2. invalid operands to binary % : %, / 연산자는 integer형태일 때만 가능합니다. (int)를 붙여 형변환을 시켜주면 됩니다.
3. invalid use of void expression : 함수가 void로 정의되어있는데 return을 char로 하려면 char로 맞춰줘야합니다.
# 코드 작성중 발생한 이슈
1. argbuffer에는 받아온 변수값의 주소를 저장하는데 계산해야하는 것은 해당주소의 값인데
이를 어떻게 받아올수있을까
- 해결 전 : tU08 h = argbuffer[argindex]
- 해결 후 : tU08 h = *(tU08*)argbuffer[argindex]
2. 전역변수로 선언한 format 배열을 0으로 초기화했는데 함수에서 어떻게 입력된 값으로 format을 초기화하지
- 함수에서 사용되는 format배열은 지역변수이기때문에 같은 이름을 사용할 경우 전역변수로 값을 대입할 수 없습니다.
그러므로 전역변수는 format으로 두고 input_fomat이라는 이름으로 값을 받아와서 for문으로 하나씩 format에
대입했습니다.
*(tU08*) 의미
tU08 a1=100;
tU08* b1=&a1;
tU08 c1=*(tU08*)b1;
printf("%d\n",a1); // 100
printf("%d\n",b1); // 6422014
printf("%d\n",c1); // 100
b1 : a1의 주소를 저장
c1 : b1의 값이 a1의 주소이므로 그 주소의 값을 저장(a1값 저장)
본 코드에서 argbuffer에는 입력받은 값의 주소들이 저장되어있습니다.
그러므로 그 주소의 값을 불러와야합니다. 그래서 *(tU08*)을 붙여서 원하는 값을 불러오도록 설계했습니다.