Embedded Design Handbook

ID 683689
Date 8/28/2023
Public
Document Table of Contents

4.2.3.3.2. Character Mode Devices

stdin, stdout, and stderr

The HAL can support the stdio functions provided in the GNU newlib library. Using the stdio library allows you to communicate with your application using functions such as printf() and scanf().

Currently, Intel supplies two system components that can support the stdio library, the UART and JTAG UART components. These devices can function as standard I/O devices.

To enable this functionality, use the --default_stdio <device> option during Nios® II BSP configuration. The stdin character input file variable and the stdout and stderr character output file variables can also be individually configured with the HAL BSP settings hal.stdin, hal.stdout, and hal.stderr.

Make sure that you assign values individually for each of the stdin, stdout, and stderr file variables that you use.

After your target system is configured to use the stdin, stdout, and stderr file variables with either the UART or JTAG UART peripheral, you can communicate with the target Nios® II system with the Nios® II EDS development tools. For more information about performing this task, refer to “Communicating with the Target”.

For more information about the --default_stdio <device> option, refer to “ Nios® II Software Build Tools Utilities” in the Nios® II Software Build Tools Reference chapter of the Nios® II Gen2 Software Developer's Handbook.

Blocking versus Non-Blocking I/O

Character mode devices can be configured to operate in blocking mode or non-blocking mode. The mode is specified in the device’s file descriptor. In blocking mode, a function call to read from the device waits until the device receives new data. In non-blocking mode, the function call to read new data returns immediately and reports whether new data was received. Depending on the function you use to read the file handle, an error code is returned, specifying whether or not new data arrived.

The UART and JTAG UART components are initialized in blocking mode. However, each component can be made non-blocking with the fnctl or the ioctl() function, as seen in the following open system call, which specifies that the device being opened is to function in non-blocking mode:

fd = open ("/dev/<your uart name>", O_NONBLOCK | O_RDWR);

The fnctl() system call shown in the example below specifies that a device that is already open is to function in non-blocking mode:

fnctl() System Call

/* You can specify <file_descriptor> to be
* STDIN_FILENO, STDOUT_FILENO, or STDERR_FILENO
* if you are using STDIO
*/
fnctl(<file_descriptor>, F_SETFL, O_NONBLOCK);

Non-Blocking Device Code Fragment

input_chars[128];
return_chars = scanf("%128s", &input_chars);
if(return_chars == 0)
{
if(errno != EWOULDBLOCK)
{
/* check other errnos */
}
}
else
{
/* process received characters */
}

The behavior of the UART and JTAG UART peripherals can also be modified with an ioctl() function call. The ioctl() function supports the following parameters:

  • For UART peripherals:
    • TIOCMGET (reports baud rate of UART)
    • TIOCMSET (sets baud rate of UART)
  • For JTAG UART peripherals:
    • TIOCSTIMEOUT (timeout value for connecting to workstation)
    • TIOCGCONNECTED (find out whether host is connected)

The altera_avalon_uart_driver.enable_ioctl BSP setting enables and disables the ioctl() function for the UART peripherals. The ioctl() function is automatically enabled for the JTAG UART peripherals.

The ioctl() function is not compatible with the altera_avalon_uart_driver.enable_small_driver and hal.enable_reduced_driver BSP settings. If either of these settings is enabled, ioctl() is not implemented.

Adding Your Own Character Mode Device

If you have a custom device capable of character mode operation, you can create a custom device driver that the stdio library functions can use.

For information about how to develop the device driver, refer to AN459: Guidelines for Developing a Nios® II HAL Device Driver.