IAR9.X printf串口底层重定向方法,否则提示Linker Error: "no definition for __write"
IAR9不能使用fputc了,实现如下:
添加如下代码:
/*******************
*
* Copyright 1998-2017 IAR Systems AB.
*
* This is a template implementation of the "__write" function used by
* the standard library.Replace it with a system-specific
* implementation.
*
* The "__write" function should output "size" number of bytes from
* "buffer" in some application-specific way.It should return the
* number of characters written, or _LLIO_ERROR on failure.
*
* If "buffer" is zero then __write should perform flushing of
* internal buffers, if any.In this case "handle" can be -1 to
* indicate that all handles should be flushed.
*
* The template implementation below assumes that the application
* provides the function "MyLowLevelPutchar".It should return the
* character written, or -1 on failure.
*
********************/
#include <LowLevelIOInterface.h>
#pragma module_name = "?__write"
int MyLowLevelPutchar(int x)
{
comSendChar(COM1, x);
return x;
}
/*
* If the __write implementation uses internal buffering, uncomment
* the following line to ensure that we are called with "buffer" as 0
* (i.e. flush) when the application terminates.
*/
size_t __write(int handle, const unsigned char * buffer, size_t size)
{
/* Remove the #if #endif pair to enable the implementation */
#if 1
size_t nChars = 0;
if (buffer == 0)
{
/*
* This means that we should flush internal buffers.Since we
* don't we just return.(Remember, "handle" == -1 means that all
* handles should be flushed.)
*/
return 0;
}
/* This template only writes to "standard out" and "standard err",
* for all other file handles it returns failure. */
if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR)
{
return _LLIO_ERROR;
}
for (/* Empty */; size != 0; --size)
{
if (MyLowLevelPutchar(*buffer++) < 0)
{
return _LLIO_ERROR;
}
++nChars;
}
return nChars;
#else
/* Always return error code when implementation is disabled. */
return _LLIO_ERROR;
#endif
}
666,感谢楼主分享 之前我把msp430,stm8,arm安装在一起了,花了一天时间,安装在一起可以不用切换iar就可以打开任意工程,安装最新的,可能msp430、stm8环境会失效。 重庆破锅 发表于 2021-11-14 12:28
之前我把msp430,stm8,arm安装在一起了,花了一天时间,安装在一起可以不用切换iar就可以打开任意工程,安 ...
IAR有必要搞个多合一就方便了。 重庆破锅 发表于 2021-11-14 12:28
之前我把msp430,stm8,arm安装在一起了,花了一天时间,安装在一起可以不用切换iar就可以打开任意工程,安 ...
同一个版本的是可以,不同版本的需要安装不同路径即可,因为共用的iar基础不一样,不能兼容 Error: no definition for "__dwrite"
我按照你给的代码 添加到IAR里面,然后编译提示如上错误,
lyhawk2007 发表于 2022-4-19 08:15
Error: no definition for "__dwrite"
我按照 ...
你现在的具体版本多少,我这个是在9.20.1上测试的。 问题解决了 你好,请问这个代码是放在哪里都行吗 你好,请问,这个代码放在哪里都行吗 dsfeng 发表于 2022-6-6 14:01
你好,请问,这个代码放在哪里都行吗
对,这个是个弱定义,这里是做了个重定向。 你好 想问一下为啥我会提示未COM1 为定义?
freeman0323 发表于 2022-6-18 10:25
你好 想问一下为啥我会提示未COM1 为定义?
这个是我们自己的bsp_uart_fifo.c驱动定义的,你可以换成自己的函数。 eric2013 发表于 2022-6-19 10:18
这个是我们自己的bsp_uart_fifo.c驱动定义的,你可以换成自己的函数。
感觉这个 iar-arm v9.3xx 版本的是比之前的版本强悍了不少,不过目前还是有点不足之处,就是使用
#if 1
#else
#endif
这里定义时,不被编译的部分代码不会变色显示,要是能够吧这个解决了就比较完美了喔 :lol
不知道是哪里可以设置吗?? 说白了就是把原来小写的printf改成大写就好了,小写是打印到iar自带的终端,大写打印到串口:) https://github.com/mpaland/printf
printf库 按照楼主方法实现了重定向,但有个问题: __write 函数的参数 size 永远都是 1。
我写了个串口驱动,可以一次发送多个字节,也做了互斥支持多线程。
如果__write 函数的参数 size 永远都是 1 的话,那做的互斥就没用了,因为每发送完一个字节就会释放互斥量。
并且每次发送一个字节效率也很低。
这个问题大佬有解决方法吗?
ihavedone 发表于 2022-7-27 12:10
按照楼主方法实现了重定向,但有个问题: __write 函数的参数 size 永远都是 1。
我写了个串口驱动, ...
这就跟fputc差不多了。
做互斥在这里做效率太低,重新封装个printf做互斥好很多,比如这样:
/*
*********************************************************************************************************
* 函 数 名: App_Printf
* 功能说明: 线程安全的printf方式
* 形 参: 同printf的参数。
* 在C中,当无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表
* 返 回 值: 无
*********************************************************************************************************
*/
staticvoidApp_Printf(const char *fmt, ...)
{
charbuf_str; /* 特别注意,如果printf的变量较多,注意此局部变量的大小是否够用 */
va_list v_args;
va_start(v_args, fmt);
(void)vsnprintf((char *)&buf_str,
(size_t ) sizeof(buf_str),
(char const *) fmt,
v_args);
va_end(v_args);
/* 互斥操作 */
tx_mutex_get(&AppPrintfSemp, TX_WAIT_FOREVER);
printf("%s", buf_str);
tx_mutex_put(&AppPrintfSemp);
} eric2013 发表于 2022-7-29 09:28
这就跟fputc差不多了。
做互斥在这里做效率太低,重新封装个printf做互斥好很多,比如这样:
这个改发用于自己的代码还好,但如果是移植了第三方软件包,其中用到 printf 函数的话,就会麻烦点。
所以最好还是能直接用 printf ,但我找了几天,MDK 下实现的 _sys_write 函数就可以实现一次输出多个字节。
IAR 下怎么搞都不行,每次一个,放弃了。
:lol
接下来还要重定向文件操作,别也是一个一个字节来的,那就搞不成器了。。 ihavedone 发表于 2022-7-29 16:39
这个改发用于自己的代码还好,但如果是移植了第三方软件包,其中用到 printf 函数的话,就会麻烦点。
所 ...
这个担心是多余的。
第三方库基本都不会直接调用printf的,都会做个重定向的#define LOGXXXprintf,凡是第3方库直接倒腾printf的都是骚操作。必须让他们"整改"。 eric2013 发表于 2022-7-29 16:48
这个担心是多余的。
第三方库基本都不会直接调用printf的,都会做个重定向的#define LOGXXXprintf, ...
我发现了问题所在,一定要加这句
#pragma module_name = "?__write"
不加的话,printf 进这个 __write 函数时,size 参数总是 1,每次只能打印一个字节。
ihavedone 发表于 2022-8-4 21:30
我发现了问题所在,一定要加这句
#pragma module_name = "?__write"
你前面是不是把这个看成乱码给删了。。
本帖最后由 ihavedone 于 2022-9-3 16:31 编辑
eric2013 发表于 2022-8-5 09:46
你前面是不是把这个看成乱码给删了。。
今天使用发现了这个重定向的另一个问题,printf 长度最大只能输出 80 个字节。后面的自动就没了。。
之前一直没输出过这么长,大佬那边能超过这个限制吗?
使用 printf 时进入 重定向的 write 函数,size 参数最大只有 80(0x50)
但是使用 文件操作 fwrite 时,进入重定向的 write 函数,size 参数就可以超过 80.。。 很奇怪
并且用 printf 打印常量字符串,最终到重定向的 write 函数中时,字符串参数的地址 在 0x20000000 开始的内存区(H743芯片)。
但是常量字符串应该是保存在代码区 0x08000000 开始的位置才对。
感觉是 printf 函数内部进行了内容复制。
ihavedone 发表于 2022-9-3 16:22
今天使用发现了这个重定向的另一个问题,printf 长度最大只能输出 80 个字节。后面的自动就没了。。
之 ...
输出100多个字符,没问题。
ihavedone 发表于 2022-9-3 16:22
今天使用发现了这个重定向的另一个问题,printf 长度最大只能输出 80 个字节。后面的自动就没了。。
之 ...
然后我们LUA小程序读取对应地址内容,没问题,也是在内部Flash里面。
eric2013 发表于 2022-9-3 17:30
然后我们LUA小程序读取对应地址内容,没问题,也是在内部Flash里面。
第一个你这边能输出超过 80 个字符,我这里还要看看原因是什么。
第二个你查看 0x80004434 的地址,是表示这个字符串的原始位置是这里。但是经过 printf 调用后,最终传递到重定向的那个 write 函数的地址是否仍然是这个地址,或者是 printf 内部把这个字符串复制到了另外的地址,比如 0x20000000 那段,然后把复制后的字符串传递给了 write。这个从第二个实验看不出来。 ihavedone 发表于 2022-9-4 01:08
第一个你这边能输出超过 80 个字符,我这里还要看看原因是什么。
第二个你查看 0x80004434 的地址,是表 ...
1、这个不知道怎么回事了。
2、有可能,有时间我再看下。 eric2013 发表于 2022-9-4 01:49
1、这个不知道怎么回事了。
2、有可能,有时间我再看下。
问题解决,原因如下:
ihavedone 发表于 2022-9-5 15:31
问题解决,原因如下:
应该是你的IAR设置问题,我这里没有进入过buffer = 0
妙啊,学到了 你好,我的提示Fatal Error: cannot open source file "LowLevelIOInterface.h"是为什么呢
0error 发表于 2023-3-28 21:45
你好,我的提示Fatal Error: cannot open source file "LowLevelIOInterface.h"是为什么呢
这个是iar的系统文件,你下载我这个例子,使用iar9.x编译是否正常
https://www.armbbs.cn/forum.php?mod=viewthread&tid=118149 感谢分享,但是还有个什么半主机模式的? xmetoo 发表于 2023-4-21 16:28
感谢分享,但是还有个什么半主机模式的?
对,输出非常慢,非常卡
IAR自带的Terminal I/O不错,可以通过半主模式输出打印数据
https://www.armbbs.cn/forum.php?mod=viewthread&tid=89459&fromuid=58
(出处: 硬汉嵌入式论坛)
ihavedone 发表于 2022-9-3 16:22
今天使用发现了这个重定向的另一个问题,printf 长度最大只能输出 80 个字节。后面的自动就没了。。
之 ...
你打printf(“\n”)
试试,这个是Flush操作。 lyhawk2007 发表于 2022-4-19 08:15
Error: no definition for "__dwrite"
我按照 ...
大佬,这个问题最后你是怎么解决的呀 请教一个问题,我把串口驱动移植到STM32L051上,如果使用你这个方法使用printf函数,还是没有输出,串口正常的,使用comSendbuf输出正常的 Aaron_EE 发表于 2023-9-7 17:34
请教一个问题,我把串口驱动移植到STM32L051上,如果使用你这个方法使用printf函数,还是没有输出,串口正 ...
正常进入到MyLowLevelPutchar函数里面没 eric2013 发表于 2023-9-7 17:37
正常进入到MyLowLevelPutchar函数里面没
谢谢eric大佬,问题解决了,现在遇到一个可笑的问题,使用STM32L051内部HSI,我开一个串口波特率还是很准的,开2个串口,波特率完全对不上了 Aaron_EE 发表于 2023-9-8 13:59
谢谢eric大佬,问题解决了,现在遇到一个可笑的问题,使用STM32L051内部HSI,我开一个串口波特率还是很准 ...
单独仅开另一个串口是否正常。
页:
[1]
2