(Rocketchip + Sifive-blocks UART) Unable to make use of system printf() function

80 Views Asked by At

I am currently working with the Rocket Chip repo to generate a 32-bit width microcontroller. I removed the debug module (The SimDTM or SimJTAG) for compiling on VCS 2014, so for debugging purpose I need to add GPIO and UART. I added the GPIO and UART modules from the Sifive-Blocks repo, and then modified the configuration of the Rocketchip accordingly (Add WithUART and WithGPIO into Configs, add HasPeripheryUART and HasPeripheryUARTModuleImp into ExampleRocketSubsystem etc.).

Then, in order to write to the UART, I wrote a UartStdOutInit() function as below:

void UartStdOutInit(void)
{
  *uartaddr32(UART_DIV) = DIVISOR;
  *uartaddr32(UART_TXEN) = TRUE; // tx enabled, stop bit 1 bit
  *uartaddr32(UART_RXEN) = TRUE; //rx enabled
  return;
}

With the header file like this:

#ifndef _UART_CONF_H
#define _UART_CONF_H

#define TRUE   1
#define FALSE  0
#define ERROR -1

typedef unsigned int U32;        //U32 is 32-bit length
#define UART_ADDR               0x54000000

#define UART_TXFIFO             0x00
#define UART_RXFIFO             0x04
#define UART_TXEN               0x08
#define UART_TXMARK             0x0a
#define UART_RXEN               0x0c
#define UART_RXMARK             0x0e

#define UART_IE                 0x10
#define UART_IP                 0x14
#define UART_DIV                0x18
#define UART_PARITY             0x1c
#define UART_WIRE4              0x20
#define UART_EITHER8OR9         0x24 \

#define uartaddr32(offset)  ((volatile U32 *)(UART_ADDR + offset))

#define DIVISOR 868 //10000000/115200 -1

/*Function declaration*/
void UartStdOutInit(void);
#endif

But after calling the Init function, I wasn't able to use either printf() or putchar() to write to my UART. If I used them, nothing will appear at the Txd line. The only way I can write to my UART is to create a new function like this:

void uartputchar(unsigned char c)
{
    *uartaddr32(UART_TXFIFO) = c;
}

And call it from a new print() function. Then my Txd line will toggle, and the data can be captured by a UART_capture module. But in this way I cannot use format strings, and it has been a big obstacle for my debugging process (still possible to hardcode through, but will be very messy and tedious). I have tried to find other resources but cannot, as most of them are doing FPGA projects or working from a IDE. Can anyone tell me what is missing or what is wrong with my UART implementation? Thank you very much!

1

There are 1 best solutions below

0
Jasminy On

I found out that the print related functions are not the ones defined in stdio.h, but rather the ones defined in syscalls.c -- actually in syscalls.c there are #undef to overwrite system functions like putchar(). So if I replace the function content of putchar() in syscalls.c with my own uartputchar(), the printf() will work with all the formatting etc. that have already been defined in syscalls.c.