四、E906移植----printf函数重映射至uart

四、E906移植----printf函数重映射至uart

上一篇实现了基本移植操作,完成了uart单字节输出,为了便于调试,我们可以将printf函数重映射到uart上进行信息输出。

如果查阅其他足够多的资料,都会提到printf函数最终调用fputc()来实现输出,而关于比较实用的修改案例只有正点原子的STM32的修改,参考不多。

我这里再按照自己的理解来大概苏理一下实现思路,

首先,例如这样的printf(“asd%d”,n)函数执行的是格式化输出字符串,如果是你来写printf函数如何要让几乎所有的支持c的平台都能实现该函数。

实际做法是,① printf的格式化控制部分的功能写成标准的,也即将含有不定数量个变量的格式化输入转换成字符串输出,大致就是检测“%”,然后根据后面的格式控制符进行各种字符处理,最后统一成一个字符串量。② 将转换完成的字符串交给底层打印函数输出,而且为了通用,最好底层实现是单个字符单个字符输出。

可以看到E906例程代码中,printf的一种参考实现:
四、E906移植----printf函数重映射至uart_第1张图片
里面调用了_vsnprintf()

而这个函数的大致实现就是如下,几乎都是字符的格式控制
四、E906移植----printf函数重映射至uart_第2张图片
可以猜测_vsnprintf() 后就调用了所谓的fputc来进行打印输出。

扯了那么多,其实是就是重新实现一下fputc函数来覆盖默认的定义。

最简单的main函数 前加一个fputc的函数

int fputc(int ch, FILE *stream)
{ 
	ck_uart_putc(&uart0, (char)ch);
}

最终整个hello_world:

#include "datatype.h"
#include "stdio.h"
#include "uart.h"

t_ck_uart_device uart0 = {0xFFFF};
//sys 50Mhz
void delay_ms(int time){
	int i,j;
	for(i=0;i<time;i++){
		for(j=0;j<50000;j++){
			;
		}
	}
}

//重写fputc
int fputc(int ch, FILE *stream)
{ 
	ck_uart_putc(&uart0, (char)ch);
}

int main (void)
{
   int a;
  //--------------------------------------------------------
  // setup uart
  //--------------------------------------------------------
  t_ck_uart_cfig   uart_cfig;
  uart_cfig.baudrate = BAUD;       // any integer value is allowed
  uart_cfig.parity = PARITY_NONE;     // PARITY_NONE / PARITY_ODD / PARITY_EVEN
  uart_cfig.stopbit = STOPBIT_1;      // STOPBIT_1 / STOPBIT_2
  uart_cfig.wordsize = WORDSIZE_8;    // from WORDSIZE_5 to WORDSIZE_8
  uart_cfig.txmode = ENABLE;          // ENABLE or DISABLE
  // open UART device with id = 0 (UART0)
  ck_uart_open(&uart0, 0);
  // initialize uart using uart_cfig structure
  ck_uart_init(&uart0, &uart_cfig);

//Section 1: Function
  printf("printf test!\n");

//Section 2: Uart
while(1){
	for(a=0;a<10;a++){
//		ck_uart_putc(&uart0, a+48);
//		delay_ms(10);

		printf("\n %d: Hello World!\n",a);
		delay_ms(10);
	}	
}
  return 0;
}

最后再把工程中 opene906-main/smart_run/tests/lib/clib/fputc.c文件中的 fputc函数注释掉

四、E906移植----printf函数重映射至uart_第3张图片

这样,printf就会输出到uart中去,
四、E906移植----printf函数重映射至uart_第4张图片

你可能感兴趣的:(c语言,RISCV,printf函数重映射)