完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、gcc环境下输入输出重定向问题
在 gcc环境下,printf重定向跟以往的在 IDE上的重定向有点不同。 在以往的 Keil、IAR等 IDE上面,都是用以下方式重定向的: int fputc(int ch, FILE *f) int fgetc(FILE *f) 但是在 gcc环境下,使用的是如下方式: int _write(int file, char *ptr, int len) int _read(int file, char *ptr, int len) 现在明确了 gcc环境下输入输出重定向问题,那么就可以编写对应的函数了。一般地,我们会参考官方的 demo来进行修改编写,很幸运的是官方提供了示例工程,在固件库的 ...STM32Cube_FW_F1_V1.8.0ProjectsSTM32F103RB-NucleoExamplesUARTUART_Printf 目录中可以找到它;然,我们真正需要的是 syscalls.c 文件,syscalls翻译过来是系统调用的意思,从里面可以找得到 _write函数和 _read函数的实现方式: __attribute__((weak)) int _read(int file, char *ptr, int len) { int DataIdx; for (DataIdx = 0; DataIdx < len; DataIdx++) { *ptr++ = __io_getchar(); } return len; } __attribute__((weak)) int _write(int file, char *ptr, int len) { int DataIdx; for (DataIdx = 0; DataIdx < len; DataIdx++) { __io_putchar(*ptr++); } return len; } 于是乎我们直接把整个 syscalls.c 文件移植过来就好了; 在 _write函数和 _read函数里面,我们可以看到它是留有接口的,即:__io_putchar和 __io_getchar ,所以我们真正要实现的是 __io_putchar和 __io_getchar ;当然,你也可以直接重新实现 _write函数和 _read函数。 然后为了对不同编译环境的使用处理,往往我们利用宏来进行选择,而在 gcc环境中 __GNUC__ 是默认定义了的,因此得到了以下实现方式: #ifdef __GNUC__ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #define GETCHAR_PROTOTYPE int __io_getchar(void) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #define GETCHAR_PROTOTYPE int fgetc(FILE *f) #endif /* __GNUC__ */ /** * 函数功能: 重定向 c库函数 printf到 DEBUG_USARTx * 输入参数: 无 * 返 回 值: 无 * 说 明:无 */ PUTCHAR_PROTOTYPE { HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF); return ch; } /** * 函数功能: 重定向 c库函数 getchar,scanf到 DEBUG_USARTx * 输入参数: 无 * 返 回 值: 无 * 说 明:无 */ GETCHAR_PROTOTYPE { uint8_t ch = 0; HAL_UART_Receive(&huart1, &ch, 1, 0xFFFF); return ch; } 然后,在这里值得注意的是: syscalls.c 文件移植到自己的工程后,记得在 Makefile中添加对它的进行编译的操作。 二、gcc环境下的输出流刷新 在 gcc环境下,使用 printf()输出,如果输出数据中没有附带 n 换行符,那么,在遇到 n 之前或着缓冲区溢出,是不会在屏幕上输出任何数据;除此之外,还有一种方法可以刷新输出数据,那就是在发完数据之后,运行一次 fflush(stdout) 强制刷新一次输出流,这样数据就能发出去了。 三、HAL库上的一些函数理解 1、在中断处理上,STM32cubeMX初始化生成代码后,要靠 HAL_UART_Transmit_IT 来打开发送或 HAL_UART_Receive_IT 来打开接收等完成剩下的中断配置并打开?。。而且,第三个参数值 Size 决定了触发进入中断的参数;eg:HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 8); 那就表示着只有接收的数据大于或等于 8的时候才出发接收中断,并且大于 8的时候会进入多次,视情况而定。 2、在使用非中断处理的函数 HAL_UART_Transmit 和 HAL_UART_Receive 处理收发数据时,第四个参数 Timeout 超时机制,使用的是 STM32cubeMX配置的 Timebase Source时钟(一般为 systick)来进行超时判定的: 四、未完待续。。。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1937 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1711 浏览 1 评论
1192 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
788 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1755 浏览 2 评论
1997浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
831浏览 4评论
stm32f4下spi+dma读取数据不对是什么原因导致的?
284浏览 3评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
638浏览 3评论
648浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-2-5 17:14 , Processed in 0.584045 second(s), Total 42, Slave 37 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号