Home > Back-end >  writing to FILE for transmission over USART
writing to FILE for transmission over USART

Time:04-30

I have a bit of code written by someone else that I'm trying to understand. I'm familiar with c enough to make basic/intermediate functions, but never really learned to use the FILE handler. The code relates to how i use/initialise the USART on an ATMEL microcontroller, and I am adding comments to every line to help keep track, but i'm struggling a little with this.

#include <stdio.h>


int USART_0_printCHAR(char character, FILE *stream) // character =  the received character, FILE = reference file, *stream = pointer
{
    USART_Transmit_Char(character); //send the character over USART
    return 0; // return 0 to the caller for exit success.
}

FILE USART_0_stream = FDEV_SETUP_STREAM(USART_0_printCHAR, NULL, _FDEV_SETUP_WRITE); //what do these arguments mean? is it replacing a standard output stream with the character that is written to the buffer.

void USART_Transmit_Char(char data)
{
// code omitted: 
// check the Transmit buffer
// wait for free space in the buffer
// put the character into the buffer
// enable the Data Register Empty Interrupt for TX
}


Thanks.

CodePudding user response:

You example initializes the default stream for the standard IO facilities. It creates a write only stream that writes its output to USART_0_printCHAR.

See Standard IO facilities

The standard streams stdin, stdout, and stderr are provided, but contrary to the C standard, since avr-libc has no knowledge about applicable devices, these streams are not already pre-initialized at application startup. Also, since there is no notion of "file" whatsoever to avr-libc, there is no function fopen() that could be used to associate a stream to some device. (See note 1.) Instead, the function fdevopen() is provided to associate a stream to a device, where the device needs to provide a function to send a character, to receive a character, or both.

As an alternative method to fdevopen(), the macro fdev_setup_stream() might be used to setup a user-supplied FILE structure.

#include <stdio.h>
static int uart_putchar(char c, FILE *stream);
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL,
                                         _FDEV_SETUP_WRITE);
static int
uart_putchar(char c, FILE *stream)
{
  if (c == '\n')
    uart_putchar('\r', stream);
  loop_until_bit_is_set(UCSRA, UDRE);
  UDR = c;
  return 0;
}
int
main(void)
{
  init_uart();
  stdout = &mystdout;
  printf("Hello, world!\n");
  return 0;
}

This example uses the initializer form FDEV_SETUP_STREAM() rather than the function-like fdev_setup_stream(), so all data initialization happens during C start-up.

  • Related