/** * @file * * @brief Generic console driver implementation. */ /* * Copyright (c) 2011 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Obere Lagerstr. 30 * 82178 Puchheim * Germany * * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. */ #include #include static const struct termios console_generic_termios = { .c_cflag = CS8 | CREAD | CLOCAL | B115200 }; static void console_generic_char_out(char c) { int minor = (int) console_generic_minor; const console_generic_callbacks *cb = console_generic_info_table [minor].callbacks; if (c == '\n') { (*cb->poll_write)(minor, '\r'); } (*cb->poll_write)(minor, c); } static int console_generic_char_in(void) { int minor = (int) console_generic_minor; const console_generic_callbacks *cb = console_generic_info_table [minor].callbacks; return (*cb->poll_read)(minor); } static void console_generic_char_out_do_init(void) { int minor = (int) console_generic_minor; const console_generic_callbacks *cb = console_generic_info_table [minor].callbacks; const struct termios *term = &console_generic_termios; BSP_output_char = console_generic_char_out; (*cb->termios_callbacks.setAttributes)(minor, term); } static void console_generic_char_out_init(char c) { console_generic_char_out_do_init(); console_generic_char_out(c); } rtems_device_driver console_initialize( rtems_device_major_number major, rtems_device_minor_number minor, void *arg ) { rtems_status_code sc = RTEMS_SUCCESSFUL; const console_generic_info *info_table = console_generic_info_table; rtems_device_minor_number count = console_generic_info_count; rtems_device_minor_number console = console_generic_minor; if (count <= 0) { rtems_fatal_error_occurred(0xdeadbeef); } rtems_termios_initialize(); for (minor = 0; minor < count; ++minor) { const console_generic_info *info = info_table + minor; sc = rtems_io_register_name(info->device_path, major, minor); if (sc != RTEMS_SUCCESSFUL) { rtems_fatal_error_occurred(0xdeadbeef); } } sc = rtems_io_register_name(CONSOLE_DEVICE_NAME, major, console); if (sc != RTEMS_SUCCESSFUL) { rtems_fatal_error_occurred(0xdeadbeef); } console_generic_char_out_do_init(); return sc; } rtems_device_driver console_open( rtems_device_major_number major, rtems_device_minor_number minor, void *arg ) { rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_device_minor_number count = console_generic_info_count; if (minor < count) { const console_generic_info *info = &console_generic_info_table [minor]; sc = rtems_termios_open( major, minor, arg, &info->callbacks->termios_callbacks ); } else { sc = RTEMS_INVALID_ID; } return sc; } rtems_device_driver console_close( rtems_device_major_number major, rtems_device_minor_number minor, void *arg ) { return rtems_termios_close(arg); } rtems_device_driver console_read( rtems_device_major_number major, rtems_device_minor_number minor, void *arg ) { return rtems_termios_read(arg); } rtems_device_driver console_write( rtems_device_major_number major, rtems_device_minor_number minor, void *arg ) { return rtems_termios_write(arg); } rtems_device_driver console_control( rtems_device_major_number major, rtems_device_minor_number minor, void *arg ) { return rtems_termios_ioctl(arg); } BSP_output_char_function_type BSP_output_char = console_generic_char_out_init; BSP_polling_getchar_function_type BSP_poll_char = console_generic_char_in;