准备工作
查看SDK原有的log.c源码
打开官方提供的 Nationstech.N32WB452_Library.2.0.0压缩包,可以在projects/n32wb452_EVAL/bsp/src/log.c文件内看到以下内容。
/*****************************************************************************
* Copyright (c) 2019, Nations Technologies Inc.
*
* All rights reserved.
* ****************************************************************************
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Nations' name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ****************************************************************************/
/**
* [url=home.php?mod=space&uid=1455510]@file[/url] log.c
* [url=home.php?mod=space&uid=40524]@author[/url] Nations
* [url=home.php?mod=space&uid=644434]@version[/url] v1.0.1
*
* [url=home.php?mod=space&uid=855824]@copyright[/url] Copyright (c) 2019, Nations Technologies Inc. All rights reserved.
*/
#include "log.h"
#if LOG_ENABLE
void log_init(void) {
GPIO_InitType GPIO_InitStructure;
USART_InitType USART_InitStructure;
// close JTAG
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO | LOG_PERIPH_GPIO, ENABLE);
if (LOG_REMAP) {
if (LOG_REMAP == GPIO_RMP3_USART2) {
// release PB4
GPIO_ConfigPinRemap(GPIO_RMP_SW_JTAG_NO_NJTRST, ENABLE);
}
GPIO_ConfigPinRemap(LOG_REMAP, ENABLE);
}
LOG_ENABLE_PERIPH_CLK(LOG_PERIPH, ENABLE);
GPIO_InitStructure.Pin = LOG_TX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitPeripheral(LOG_GPIO, &GPIO_InitStructure);
// GPIO_InitStructure.Pin = LOG_RX_PIN;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
// GPIO_InitPeripheral(LOG_GPIO, &GPIO_InitStructure);
USART_InitStructure.BaudRate = 115200;
USART_InitStructure.WordLength = USART_WL_8B;
USART_InitStructure.StopBits = USART_STPB_1;
USART_InitStructure.Parity = USART_PE_NO;
USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
USART_InitStructure.Mode = USART_MODE_TX;
// init uart
USART_Init(LOG_USARTx, &USART_InitStructure);
// enable uart
USART_Enable(LOG_USARTx, ENABLE);
}
static int is_lr_sent = 0;
int fputc(int ch, FILE *f) {
if (ch == '\r') {
is_lr_sent = 1;
} else if (ch == '\n') {
if (!is_lr_sent) {
USART_SendData(LOG_USARTx, (uint8_t)'\r');
/* Loop until the end of transmission */
while (USART_GetFlagStatus(LOG_USARTx, USART_FLAG_TXDE) == RESET) {
}
}
is_lr_sent = 0;
} else {
is_lr_sent = 0;
}
USART_SendData(LOG_USARTx, (uint8_t)ch);
/* Loop until the end of transmission */
while (USART_GetFlagStatus(LOG_USARTx, USART_FLAG_TXDE) == RESET) {
}
return ch;
}
#ifdef USE_FULL_ASSERT
__WEAK void assert_failed(const uint8_t *expr, const uint8_t *file,
uint32_t line) {
log_error("assertion failed: `%s` at %s:%d", expr, file, line);
while (1) {
}
}
#endif // USE_FULL_ASSERT
#endif // LOG_ENABLE
这里我们可以看出,SDK源码通过projects/n32wb452_EVAL/bsp/inc/log.h里log串口部分定义,指定了log输出的串口,并重写了fputc,这样使用printf函数时,就会调用fputc,把内容输出到串口去。
现在我们要移植到腾讯TinyOS上,就需要将串口初始化部分代码调整到bsp目录里,然后在bsp代码里实现输出函数。
下面是调整后的代码(因个人书写习惯的原因,部分写法有区别)
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(char ch)
#define GETCHAR_PROTOTYPE int __io_getchar()
#else
#define PUTCHAR_PROTOTYPE int fputc(char ch)
#define GETCHAR_PROTOTYPE int fgetc()
#endif
static int is_lr_sent = 0;
PUTCHAR_PROTOTYPE {
if (ch == '\r') {
is_lr_sent = 1;
} else if (ch == '\n') {
if (!is_lr_sent) {
USART_SendData(LOG_USARTx, (uint8_t)'\r');
while (USART_GetFlagStatus(LOG_USARTx, USART_FLAG_TXDE) == RESET) {
}
}
is_lr_sent = 0;
} else {
is_lr_sent = 0;
}
USART_SendData(LOG_USARTx, (uint8_t)ch);
while (USART_GetFlagStatus(LOG_USARTx, USART_FLAG_TXDE) == RESET) {
}
return ch;
}
_write函数定义在utils组件中
int _write(int file, char *ptr, int len) {
int DataIdx;
for (DataIdx = 0; DataIdx < len; DataIdx++) {
__io_putchar(*ptr++);
}
return len;
}
串口初始化代码调整到bsp目录,其他内容不变。
然后编译测试,可以得到正确的输出。