原子哥的USART代码中,有一部分感觉看得不是很懂
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
/* Whatever you require here. If the only file you are using is */
/* standard output using printf() for debugging, no file handling */
/* is required. */
};
/* FILE is typedef’ d in stdio.h. */
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
_sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}
#endif
参考了相关资料:
RealView 编译工具 开发指南
RealView 编译工具 库和浮点支持指南
下面分析代码:
相当于一段废话,就是永远判断为正
要理解这一句话,要先了解半主机的概念以及如何构建用于非半主机环境的应用程序
半主机是用于 ARM 目标的一种机制,可将来自应用程序代码的输入/输出请求
传送至运行调试器的主机。 例如,使用此机制可以启用 C 库中的函数,如
printf() 和 scanf(),来使用主机的屏幕和键盘,而不是在目标系统上配备屏幕
和键盘。
这种机制很有用,因为开发时使用的硬件通常没有最终系统的所有输入和输出
设备。 半主机可让主机来提供这些设备。
如果不想使用任何半主机功能,则必须删除对半主机函数的所有调用,或者使
用非半主机函数重新实现它们。
要构建不使用半主机功能的应用程序,请执行以下操作:
例如,使用半主机调用或依赖于目标内存映射的函数。
要确保应用程序中不包含任何使用半主机的函数,请使用以下任一方法:
• 汇编语言中的 IMPORT __use_no_semihosting
• C 中的 #pragma import(__use_no_semihosting)。
IMPORT __use_no_semihosting 只需添加到一个汇编源文件中。 同样, #pragma
import(__use_no_semihosting) 只需添加到一个 C 源文件中。 不需要将这些插入添
加到每个源文件中。
从2.2.2可以看出,这句话确保应用程序不包含任何使用半主机的函数
printf()这一高级函数通过调用与目标相关的函数来执行,重新实现printf(),需要重新定义低级函数
重新实现有此需要的函
数
__FILE: 文件结构
__stdout: __FILE类型的标准输出对象
fputc():将一个字符输出到文件中
ferror():返回在文件 I/O 期间累积的错误状态
《RealView编译工具-库和浮点支持指南》中的demo
#include
struct __FILE
{
int handle;
/* Whatever you require here. If the only file you are using is */
/* standard output using printf() for debugging, no file handling */
/* is required. */
};
/* FILE is typedef’ d in stdio.h. */
FILE __stdout;
int fputc(int ch, FILE *f)
{
/* Your implementation of fputc(). */
return ch;
}
int ferror(FILE *f)
{
/* Your implementation of ferror(). */
return 0;
}
void test(void)
{
printf( “Hello world\n” );
}
通过之前的分析,可以理解原子哥关于 __FILE; __stdout的代码是什么意思了
重定义了 __FILE; __stdout;
位7:
TXE:发送数据寄存器空 (Transmit data register empty)
当TDR寄存器中的数据被硬件转移到移位寄存器的时候,该位被硬件置位。如果USART_CR1
寄存器中的TXEIE为1,则产生中断。对USART_DR的写操作,将该位清零。
0:数据还没有被转移到移位寄存器;
1:数据已经被转移到移位寄存器。
位31:9:
保留位,硬件强制为0
位8:0
DR[8:0]:数据值 (Data value)
包含了发送或接收的数据。由于它是由两个寄存器组成的,一个给发送用(TDR),一个给接收
用(RDR),该寄存器兼具读和写的功能。
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}
相当于先等待之前的字符通过USART1发送完成后,通过USART1将一个字符发出
__sys_exit()是库函数退出函数,所有从库中的退出最后都会调用__sys_exit()
在这里重新定义,避免使用半主机模式