[MM32软件]IAR使用printf函数后MCU挂掉了,看我如何解决的^^

做嵌入式(MCU)软件开发的小伙伴,对IAR的EWARM集成开发环境都不陌生,我之前都是使用的IAR EWARM 8.32版本的,使用也一直很稳定,有好长时间没有去关注和更新新的IAR EWARM版本了……最近突然心血来潮,更新到IAR EWARM 9.30.1版本,发现之前的项目工程突然都不灵了!!!咋回事呢???

回退到IAR EWARM 8.32版本,原先的项目工程依旧可以正常运行,但切换到IAR EWARM 9.30.1版本后,程序就卡在一半不执行了;经过一点一点的分析(在线调试、单步运行)后,发现竟然卡在了最常用的printf函数这里了……

对于要实现printf函数的功能,除了在工程配置时,需要增加_DLIB_FILE_DESCRIPTOR这个宏定义之外还需要重载一下fputc这个底层函数,当然也要初始化对应的打印串口参数哈:

/***********************************************************************************************************************

  * [url=home.php?mod=space&uid=247401]@brief[/url]  Initialize console for printf

  * [url=home.php?mod=space&uid=536309]@NOTE[/url]   none

  * @param  Baudrate : UART2 communication baudrate

  * @retval none

  *********************************************************************************************************************/

void PLATFORM_InitConsole(uint32_t Baudrate)

{

    GPIO_InitTypeDef GPIO_InitStruct;

    UART_InitTypeDef UART_InitStruct;



    RCC_APB1PeriphClockCmd(RCC_APB1ENR_UART2, ENABLE);



    UART_StructInit(&UART_InitStruct);

    UART_InitStruct.BaudRate      = Baudrate;

    UART_InitStruct.WordLength    = UART_WordLength_8b;

    UART_InitStruct.StopBits      = UART_StopBits_1;

    UART_InitStruct.Parity        = UART_Parity_No;

    UART_InitStruct.HWFlowControl = UART_HWFlowControl_None;

    UART_InitStruct.Mode          = UART_Mode_Tx;

    UART_Init(UART2, &UART_InitStruct);



    UART_Cmd(UART2, ENABLE);



    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE);



    GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_1);



    GPIO_StructInit(&GPIO_InitStruct);

    GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_2;

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AF_PP;

    GPIO_Init(GPIOA, &GPIO_InitStruct);

}



/***********************************************************************************************************************

  * @brief  Redefine fputc function

  * @note   For printf

  * @param  ch

  * @param  f

  * @retval ch

  *********************************************************************************************************************/

int fputc(int ch, FILE *f)

{

    UART_SendData(UART2, (uint8_t)ch);



    while (RESET == UART_GetFlagStatus(UART2, UART_FLAG_TXEPT))

    {

    }



    return (ch);

}


代码一丝丝都没修改过,不可能会有问题哈……

最后还是查看IAR的帮助文档,发现从IAR EWARM 9.3版本之后,要实现printf函数不是重载fputc这个函数了,而是需要重载__write这个函数,通过帮助文档里给出的示例代码作参考,尝试了一下:

/* Files include */

#include <stddef.h>

#include <LowLevelIOInterface.h>



/***********************************************************************************************************************

  * @brief  redefine __write function

  * @note   for printf

  * @param  handle

  * @param  *buf

  * @param  bufSize

  * @retval nChars

  *********************************************************************************************************************/

size_t __write(int handle, const unsigned char *buf, size_t bufSize)

{

    size_t nChars = 0;



    /* Check for the command to flush all handles */

    if (-1 == handle)

    {

        return (0);

    }



    /* Check for stdout and stderr (only necessary if FILE descriptors are enabled.) */

    if ((_LLIO_STDOUT != handle) && (_LLIO_STDERR != handle))

    {

        return (-1);

    }



    for (/* Empty */; bufSize > 0; --bufSize)

    {

        UART_SendData(UART2, *buf);



        while (RESET == UART_GetFlagStatus(UART2, UART_FLAG_TXEPT))

        {

        }



        ++buf; 

        ++nChars;

    }



    return (nChars);

}


此时再使用IAR EWARM 9.30.1版本软件进行编译、下载后,项目代码终于可以正常运行了……这个printf功能卡脖子有问题终于解决了!!!

那在代码中我如何判断当前IAR的版本是8.32还是9.30呢?在IAR编译器中提供了这样两个宏,一个是__ICCARM__,这个表示当前使用的IAR EWARM编译器环境,另外一个是__VER__,它可以判断当前编译器的软件版本号,这样我们就可以通过这两个宏来判断,我们在实现printf函数时,是需要重载fputc函数还是__write函数了,做到项目工程的兼容,不会再出现上述问题导致的MCU卡住了!
---------------------
作者:xld0932
链接:https://bbs.21ic.com/icview-3285314-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值