File indexing completed on 2025-05-11 08:23:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <sys/stat.h>
0037 #include <assert.h>
0038 #include <fcntl.h>
0039 #include <unistd.h>
0040 #include <termios.h>
0041
0042 #include <bspopts.h>
0043 #include <bsp/uart-bridge.h>
0044 #include <rtems/termiostypes.h>
0045
0046 #define TRANSMIT_EVENT RTEMS_EVENT_13
0047
0048 static void serial_settings(int fd)
0049 {
0050 struct termios term;
0051 int rv = tcgetattr(fd, &term);
0052 assert(rv == 0);
0053
0054 term.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
0055 term.c_oflag &= ~OPOST;
0056 term.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
0057 term.c_cflag &= ~(CSIZE | PARENB);
0058 term.c_cflag |= CS8;
0059
0060 term.c_cc [VMIN] = 1;
0061 term.c_cc [VTIME] = 1;
0062
0063 rv = tcsetattr(fd, TCSANOW, &term);
0064 assert(rv == 0);
0065 }
0066
0067 static void uart_bridge_master_service(intercom_packet *packet, void *arg)
0068 {
0069 rtems_status_code sc = RTEMS_SUCCESSFUL;
0070 uart_bridge_master_context *ctx = arg;
0071
0072 sc = rtems_chain_append_with_notification(
0073 &ctx->transmit_fifo,
0074 &packet->glue.node,
0075 ctx->transmit_task,
0076 TRANSMIT_EVENT
0077 );
0078 assert(sc == RTEMS_SUCCESSFUL);
0079 }
0080
0081 static void receive_task(rtems_task_argument arg)
0082 {
0083 uart_bridge_master_context *ctx = (uart_bridge_master_context *) arg;
0084 intercom_type type = ctx->type;
0085
0086 int fd = open(ctx->device_path, O_RDONLY);
0087 assert(fd >= 0);
0088
0089 serial_settings(fd);
0090
0091 while (true) {
0092 intercom_packet *packet = qoriq_intercom_allocate_packet(
0093 type,
0094 INTERCOM_SIZE_64
0095 );
0096 ssize_t in = read(fd, packet->data, packet->size - 1);
0097 if (in > 0) {
0098 packet->size = (size_t) in;
0099 qoriq_intercom_send_packet(QORIQ_UART_BRIDGE_SLAVE_CORE, packet);
0100 } else {
0101 qoriq_intercom_free_packet(packet);
0102 }
0103 }
0104 }
0105
0106 static void transmit_task(rtems_task_argument arg)
0107 {
0108 rtems_status_code sc = RTEMS_SUCCESSFUL;
0109 uart_bridge_master_context *ctx = (uart_bridge_master_context *) arg;
0110 rtems_chain_control *fifo = &ctx->transmit_fifo;
0111
0112 int fd = open(ctx->device_path, O_WRONLY);
0113 assert(fd >= 0);
0114
0115 serial_settings(fd);
0116
0117 while (true) {
0118 intercom_packet *packet = NULL;
0119 sc = rtems_chain_get_with_wait(
0120 fifo,
0121 TRANSMIT_EVENT,
0122 RTEMS_NO_TIMEOUT,
0123 (rtems_chain_node **) &packet
0124 );
0125 assert(sc == RTEMS_SUCCESSFUL);
0126 write(fd, packet->data, packet->size);
0127 qoriq_intercom_free_packet(packet);
0128 }
0129 }
0130
0131 static rtems_id create_task(
0132 char name,
0133 rtems_task_entry entry,
0134 uart_bridge_master_context *ctx
0135 )
0136 {
0137 rtems_status_code sc = RTEMS_SUCCESSFUL;
0138 rtems_id task = RTEMS_ID_NONE;
0139 char index = (char) ('0' + ctx->type - INTERCOM_TYPE_UART_0);
0140
0141 sc = rtems_task_create(
0142 rtems_build_name('U', 'B', name, index),
0143 QORIQ_UART_BRIDGE_TASK_PRIORITY,
0144 0,
0145 RTEMS_DEFAULT_MODES,
0146 RTEMS_DEFAULT_ATTRIBUTES,
0147 &task
0148 );
0149 assert(sc == RTEMS_SUCCESSFUL);
0150
0151 sc = rtems_task_start(
0152 task,
0153 entry,
0154 (rtems_task_argument) ctx
0155 );
0156 assert(sc == RTEMS_SUCCESSFUL);
0157
0158 return task;
0159 }
0160
0161 bool qoriq_uart_bridge_master_probe(rtems_termios_device_context *base)
0162 {
0163 uart_bridge_master_context *ctx = (uart_bridge_master_context *) base;
0164 intercom_type type = ctx->type;
0165
0166 qoriq_intercom_service_install(type, uart_bridge_master_service, ctx);
0167 create_task('R', receive_task, ctx);
0168 ctx->transmit_task = create_task('T', transmit_task, ctx);
0169
0170 return true;
0171 }
0172
0173 static bool first_open(
0174 struct rtems_termios_tty *tty,
0175 rtems_termios_device_context *base,
0176 struct termios *term,
0177 rtems_libio_open_close_args_t *args
0178 )
0179 {
0180 return false;
0181 }
0182
0183 static bool set_attributes(
0184 rtems_termios_device_context *base,
0185 const struct termios *term
0186 )
0187 {
0188 return false;
0189 }
0190
0191 const rtems_termios_device_handler qoriq_uart_bridge_master = {
0192 .first_open = first_open,
0193 .set_attributes = set_attributes,
0194 .mode = TERMIOS_POLLED
0195 };