IAR에서 printf 를 쓸 수 있으면 정말 편리해진다.
정말 C like 하게 프로그래밍을 하면 보기도 편하고 일부 기능은 바로 다른 C compiler 에 옮겨서 확인해볼 수 있으니 여러모로 편리하다.
나도 uC/OS 에 printf 를 쓰려고 여러군데 찾아봤다.
여러군데 찾아봐도 딱 한 부분만 잘라서 이야기 하면서,
왜 그렇게 되는지 자세히 이유도 안 적어놓고 그냥 대충 둘러대는 곳만 너무 많이 봤다. ;;;;
그래서 나도 똑같이 대략적으로 말 하기만 하는건 좀 그래서...
결국은 내가 썼던 코드의 일부분을 올린다..;;;;
중요한거를 몇가지 잡아보자면, (개념은 알아야 될것 아니냐..;; )
(나도 잘 모르지만..;;) printf 든 뭐든 결국 하위 함수로 putchar 를 호출하게 된다고 한다.
이것을 IAR 에서 제공하는 USART_SendData 함수로 바꿔서 개개별의 문자를 UART 통신을 시킨다.
또한 UART 통신을 하려면 기본적으로 해당 Pin 에 대한 GPIO(General Port I/O) 설정과, UART 관련 설정은 당연한것.
빠뜨리지 않고 보도록 하자.
먼저 putchar 을 UART 통신으로 바꿔버리는 부분.
/*******************************************************************************
* Function Name : PUTCHAR_PROTOTYPE
* Description : Retargets the C library printf function to the USART.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
PUTCHAR_PROTOTYPE
{
/* Write a character to the USART */
USART_SendData(USARTx, (u8) ch);
/* Loop until the end of transmission */
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET){}
return ch;
}
이 부분이 연결되는 부분을 또 만들어야 하겠지.
컴파일의 환경에 따라서 다음과 같이 연결하면 된다.
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
이렇게 하면 연결하는것은 OK.
나머지 GPIO 설정과, UART 설정들..
/*******************************************************************************
* Function Name : GPIO_Configuration
* Description : Configures the different GPIO ports.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
#if defined USE_USART1 && defined USE_STM3210B_EVAL
/* Enable AFIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
/* Enable the USART2 Pins Software Remapping */
GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);
#endif
/* Configure USARTx_Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_TxPin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOx, &GPIO_InitStructure);
/* Configure USARTx_Rx as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_RxPin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOx, &GPIO_InitStructure);
/* Enable GPIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
}
/*******************************************************************************
* Function Name : UART_Configuration
*******************************************************************************/
void UART_Configuration(void){
USART_InitTypeDef USART_InitStructure;
/* USARTx configuration ------------------------------------------------------*/
/* USARTx configured as follow:
- BaudRate = 115200 baud
- Word Length = 8 Bits
- One Stop Bit
- No parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled
*/
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
/* Configure the USARTx */
USART_Init(USARTx, &USART_InitStructure);
/* Enable the USARTx */
USART_Cmd(USARTx, ENABLE);
}
대략적으로 이정도는 최소한(??) 해줘야 이제 printf 가 살랑살랑 되려고 할꺼다.
하지만.. 이게 다라고 믿지는 말길...
신은 우리에게 항상 삽질을 던져주리라. ㅋㅋ
platform_config.h 등의 설정은 알아서 하길.. ㅋㅋㅋ..
(그런데 그정도도 설정 안 하면서 저 위에꺼를 배껴서 그냥 쓰기만 한다면....
어디서 에러가 나더라도 아마 잡기가 힘들지 않을까 싶다. )