강좌 & 팁
얼마전에 stm32로 펌웨어를 작성할 일이 생겨서 급하게 환경을 만들었습니다.
우선 컴파일러는
https://launchpad.net/gcc-arm-embedded 의 win32 용을 사용 하였습니다.
콘솔 디버깅은 st 에서 공급하는 tiny_printf.c 를 사용 하기로 하였습니다.
platform_config.h 에 아래와 같이 선언하고,
extern int printf(const char *fmt, ...);
함수를 아래와 같이 변경 하였습니다.
물론 콘솔로 사용할 uart는 설정을 미리 했습니다.
int printf(const char *fmt, ...)
{
int length = 0, printf_loop_count = 0;
va_list va;
va_start(va, fmt);
length = ts_formatlength(fmt, va);
va_end(va);
{
char buf[length];
va_start(va, fmt);
length = ts_formatstring(buf, fmt, va);
length = _write(1, buf, length);
#if 1
for(printf_loop_count=0 ; printf_loop_count<length ; printf_loop_count++)
{
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
{
}
USART_SendData(USART1, buf[printf_loop_count]);
}
#endif
va_end(va);
}
return length;
}
이렇게하고 테스트 해보니
printf("test"); 이런 라인은 동작을 안하고
printf("value : %x", value); 이런 라인은 동작을 하였습니다.
그래서 디어셈블러 보니 아래와 같이 링크가 되어있었습니다.
동작 하지 않는 라인은 아래와 같이
call puts
동작 하는 라인은 아래와 같이
call printf
열심비 구글을 한 결과 아래와 같은 사이트를 발견 하였습니다.
http://www.ciselant.de/projects/gcc_printf/gcc_printf.html
결론 적으로 아래 표로 다 설명이 됩니다.
출처 : http://www.ciselant.de/projects/gcc_printf/gcc_printf.html
제가 사용한 gcc 버전을 보니 아래와 같았습니다.
gcc version 4.8.4 20140725 (release) [ARM/embedded-4_8-branch revision 213147] (GNU Tools for ARM Embedded Processors)
본론으로 돌아와서, 그래서 위 사이트의 해결책 -fno-builtin-printf 을 컴파일 옵션에 추가 하였으며,
잘 동작 하는 것을 확인 하였습니다.
그럼 이만...
끝 -