123下一页
返回列表 发新帖我要提问本帖赏金: 20.00元(功能说明)

[APM32F4] 优雅使用IAR9.3调用printf打印信息

[复制链接]
 楼主| kai迪皮 发表于 2022-6-23 17:04 | 显示全部楼层 |阅读模式
<
本帖最后由 kai迪皮 于 2022-6-23 17:09 编辑

#申请原创# @21小跑堂

前言

最近发现IAR 发布了新版本9.30.1,在新版本中Geehy的众多MCU都完成了支持。

image-20220623165029967.png

我这边刚好有APM32F407IG的MINIBOARD,想着使用IAR编译一下工程下载运行一下程序。不料却发现了问题,APM32F4xx_SDK_V1.1中的IAR例程是基于 IAR8.5制作的,关于printf的重定向都已经在工程内进行了设置。使用8.5的工程也可以正常使用printf功能。但在9.x的IAR对printf重定向有了新的要求,导致IAR 9.x版本无法运行含有printf功能的例程。

本文档就解决APM32F4xx_SDK_V1.1中使用IAR9.3进行编译使用printf功能进行记录分享。

值得注意的是:

- printf重定向前需完成对应串口的初始化操作。

1 IAR 8.x的printf重定向

IAR 8.x的printf重定向与Keil并无差异,仅需在内部的任意一个C文件中重定向printf后设置工程的相应参数即可完成。

1. 重定向printf代码如下(发送串口为串口1,头文件需包含stdio.h)
  1. /* Includes */
  2. #include "stdio.h"


  3. /*!
  4. * [url=home.php?mod=space&uid=247401]@brief[/url]       Redirect C Library function printf to serial port.
  5. *              After Redirection, you can use printf function.
  6. *
  7. * @param       ch:  The characters that need to be send.
  8. *
  9. * @param       *f:  pointer to a FILE that can recording all information
  10. *              needed to control a stream
  11. *
  12. * @retval      The characters that need to be send.
  13. */
  14. int fputc(int ch, FILE *f)
  15. {
  16.     /** send a byte of data to the serial port */
  17.     USART_TxData(DEBUG_USART,(uint8_t)ch);

  18.     /** wait for the data to be send  */
  19.     while (USART_ReadStatusFlag(DEBUG_USART, USART_FLAG_TXBE) == RESET);

  20.     return (ch);
  21. }


2. 设置工程相应参数,将General Option 的 Library Configuration 选项卡下Library选择为“Full”,CMSIS 项目勾选“Use CMSIS”。

   image-20220623153910714.png

至此程序中便可以正常使用printf函数。

2 IAR 9.x的printf重定向

通过查阅IAR的开发文档。(在Help选项卡下打开“C/C++ Development Guide”)

image-20220623154256105.png

在开发文档的“BRIEFLY ABOUT RETARGETING”章节,我们可以看到IAR9.x要求我们使用printf时需要重定向__write函数。

image-20220623154827836.png

重定向的详细内容请查阅文档,此处不在赘述。这里给出参考操作。

1. 在源码目录下,新建“write.c”文件用于存放我们重定向的代码。

2. 打开需要重定向的工程,在工程中添加我们刚刚新建的“write.c”。

image-20220623155536963.png

3. 编辑“write.c”文件,添加重定向代码。代码内容如下。

  1. /*******************
  2. *
  3. * Copyright 1998-2017 IAR Systems AB.
  4. *
  5. * This is a template implementation of the "__write" function used by
  6. * the standard library.  Replace it with a system-specific
  7. * implementation.
  8. *
  9. * The "__write" function should output "size" number of bytes from
  10. * "buffer" in some application-specific way.  It should return the
  11. * number of characters written, or _LLIO_ERROR on failure.
  12. *
  13. * If "buffer" is zero then __write should perform flushing of
  14. * internal buffers, if any.  In this case "handle" can be -1 to
  15. * indicate that all handles should be flushed.
  16. *
  17. * The template implementation below assumes that the application
  18. * provides the function "MyLowLevelPutchar".  It should return the
  19. * character written, or -1 on failure.
  20. *
  21. ********************/

  22. #include <LowLevelIOInterface.h>
  23. #include "Board.h"
  24. #include "apm32f4xx.h"

  25. #pragma module_name = "?__write"

  26. uint8_t USART_Transmit(USART_T* usart, uint8_t *pdata, uint16_t Size);

  27. /*
  28. * If the __write implementation uses internal buffering, uncomment
  29. * the following line to ensure that we are called with "buffer" as 0
  30. * (i.e. flush) when the application terminates.
  31. */

  32. size_t __write(int handle, const unsigned char * buffer, size_t size)
  33. {
  34.   if (buffer == 0)
  35.   {
  36.     /*
  37.      * This means that we should flush internal buffers.  Since we
  38.      * don't we just return.  (Remember, "handle" == -1 means that all
  39.      * handles should be flushed.)
  40.      */
  41.     return 0;
  42.   }

  43.   /* This template only writes to "standard out" and "standard err",
  44.    * for all other file handles it returns failure. */
  45.   if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR)
  46.   {
  47.     return _LLIO_ERROR;
  48.   }
  49.   
  50.   /* Sending in normal mode */
  51.   if(USART_Transmit(USART1,(uint8_t *)buffer,size) == 1)
  52.   {
  53.     return size;
  54.   }
  55.   else
  56.   {
  57.     return _LLIO_ERROR;
  58.   }
  59. }

  60. uint8_t USART_Transmit(USART_T* usart, uint8_t *pdata, uint16_t Size)
  61. {
  62.   uint8_t ch = 0;
  63.   uint16_t i = 0;
  64.   uint16_t timeout = 0x1000;
  65.   
  66.   for(i=0;i<Size;i++)
  67.   {
  68.     ch = pdata[i];
  69.    
  70.     /** send a byte of data to the serial port */
  71.     USART_TxData(usart,(uint8_t)ch);

  72.     /** wait for the data to be send  */
  73.     while ((USART_ReadStatusFlag(usart, USART_FLAG_TXBE) == RESET) && (timeout -- ));
  74.    
  75.     if(timeout == 0)
  76.     {
  77.       return 0;
  78.     }
  79.    
  80.     timeout = 0x1000;
  81.    
  82.   }
  83.   
  84.   return 1;
  85. }


    __write函数为IAR要求我们进行重定向的函数,这里使用的发送串口是串口1,若需要使用其他串口,请相应修改“USART_Transmit(USART1,(uint8_t *)buffer,size) == 1”中的USART1参数。

    USART_Transmit函数是为了便捷使用发送功能进行定义的函数,其采用的是轮训发送的操作,有超时设置,返回1为发送成功,返回0为发送失败。

至此程序中便可以正常使用printf函数。



以上便是APM32F4xx_SDK_V1.1中的IAR工程使用9.30打开后如何使用printf进行打印的全部内容。

APM32F4xx_SDK_V1.1_IAR 9.30.1.zip

298.52 KB, 下载次数: 28

打赏榜单

21小跑堂 打赏了 20.00 元 2022-06-28
理由:恭喜通过原创文章审核!请多多加油哦!

评论

@billzeng :一样的,主要修改一下USART_Transmit函数的内容实现即可。里面的内容使用ST的库进行实现。  发表于 2022-10-9 23:43
@kai迪皮 :大师,STM32需要怎么改?  发表于 2022-7-16 20:08
大师,STM32需要怎么改?  发表于 2022-7-16 20:06
@21小跑堂 :谢谢支持  发表于 2022-7-1 09:29
升级最新IAR软件,发现问题,解决问题,通过自己的努力解决最新版本printf重定向的问题。  发表于 2022-6-28 16:01
caigang13 发表于 2022-7-1 18:25 来自手机 | 显示全部楼层
s
学习了,谢谢楼主分享。
chenjun89 发表于 2022-7-3 10:39 来自手机 | 显示全部楼层
s
下载看看,谢谢分享。
weifeng90 发表于 2022-7-4 08:16 来自手机 | 显示全部楼层
s
IAR居然都更新到9版本了
linfelix 发表于 2022-7-4 15:32 | 显示全部楼层
s
自己重映射吧。   

评论

是的,自己完成重映射  发表于 2022-10-19 09:31
selongli 发表于 2022-7-4 15:48 | 显示全部楼层
s
IAR效果怎么样   
七毛钱 发表于 2022-7-4 15:53 来自手机 | 显示全部楼层
s
下载看看感谢分享
nomomy 发表于 2022-7-4 16:14 | 显示全部楼层
s
这个跟keil一样的。   
iyoum 发表于 2022-7-4 17:00 | 显示全部楼层
s
这个sprintf也可以使用。   
两只袜子 发表于 2022-7-5 15:07 来自手机 | 显示全部楼层
s
我优雅的点开这篇文章优雅的看一看,哈哈
uytyu 发表于 2022-7-5 16:03 | 显示全部楼层
s
printf重定向与Keil并无差异  
bartonalfred 发表于 2022-7-5 17:04 | 显示全部楼层
s
是自带的库吗?  

评论

APM32的官方标准库  发表于 2022-7-6 11:21
isseed 发表于 2022-7-5 17:56 | 显示全部楼层
s
printf应用还是比较多的。   

评论

是的,printf很常用  发表于 2022-7-6 11:21
chenqianqian 发表于 2022-7-6 08:21 来自手机 | 显示全部楼层
s
学习了,谢谢楼主分享经验。
cashrwood 发表于 2022-7-8 10:12 | 显示全部楼层
s
如何在C语言中用printf()输出某个值的地址?
i1mcu 发表于 2022-7-8 15:24 | 显示全部楼层
s
自动使用stdio标准输入输出的printf函数
xiaoyaozt 发表于 2022-7-8 16:16 | 显示全部楼层
s
怎样用一个printf函数输出多行字符
pl202 发表于 2022-7-9 13:09 | 显示全部楼层
s
printf是格式化输出函数,它可以直接打印十进制,八进制,十六进制,输出控制符分别为%d, %o, %x
plsbackup 发表于 2022-7-9 14:33 | 显示全部楼层
s
printf函数用来打印输出的调试信息
htmlme 发表于 2022-7-9 16:12 | 显示全部楼层
s
开发板中是如何实现printf这个打印的?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

43

主题

292

帖子

11

粉丝
快速回复 在线客服 返回列表 返回顶部