File indexing completed on 2025-05-11 08:24:34
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 #ifdef HAVE_CONFIG_H
0036 #include "config.h"
0037 #endif
0038
0039 #include "tmacros.h"
0040 #include <rtems/libio.h>
0041 #include <stdlib.h>
0042 #include <termios.h>
0043 #include <rtems/termiostypes.h>
0044 #include <rtems/dumpbuf.h>
0045 #include "termios_testdriver_intr.h"
0046
0047
0048 void termios_test_driver_wait_for_tx_to_complete(void);
0049 rtems_timer_service_routine Rx_ISR(
0050 rtems_id ignored_id,
0051 void *ignored_address
0052 );
0053 rtems_timer_service_routine Tx_ISR(
0054 rtems_id ignored_id,
0055 void *ignored_address
0056 );
0057 ssize_t termios_test_driver_write_helper(
0058 int port,
0059 const char *buf,
0060 size_t len
0061 );
0062 int termios_test_driver_set_attributes(
0063 int minor,
0064 const struct termios *t
0065 );
0066 #if defined(TASK_DRIVEN)
0067 int termios_test_driver_inbyte_nonblocking(int port);
0068 #endif
0069
0070
0071 rtems_id Rx_Timer;
0072 rtems_id Tx_Timer;
0073
0074 #define TX_MAX 1024
0075 uint8_t Tx_Buffer[TX_MAX];
0076 int Tx_Index = 0;
0077 struct rtems_termios_tty *Ttyp;
0078
0079 void termios_test_driver_wait_for_tx_to_complete(void)
0080 {
0081 rtems_task_wake_after( 2 * rtems_clock_get_ticks_per_second() );
0082 }
0083
0084 void termios_test_driver_dump_tx(const char *c)
0085 {
0086 termios_test_driver_wait_for_tx_to_complete();
0087
0088 printf( "%s %d characters\n", c, Tx_Index );
0089 rtems_print_buffer( Tx_Buffer, Tx_Index );
0090 Tx_Index = 0;
0091 }
0092
0093 const uint8_t *Rx_Buffer;
0094 int Rx_Index = 0;
0095 int Rx_Length = 0;
0096 bool Rx_FirstTime = true;
0097 bool Rx_EnqueueNow = false;
0098
0099 #if defined(TASK_DRIVEN)
0100 int termios_test_driver_inbyte_nonblocking( int port )
0101 {
0102 if ( Rx_FirstTime == true ) {
0103 Rx_FirstTime = false;
0104 return -1;
0105 }
0106 if ( Rx_Index >= Rx_Length )
0107 return -1;
0108 return Rx_Buffer[ Rx_Index++ ];
0109 }
0110 #endif
0111
0112 rtems_timer_service_routine Rx_ISR(
0113 rtems_id ignored_id,
0114 void *ignored_address
0115 )
0116 {
0117 uint8_t ch;
0118
0119 if ( Rx_Index >= Rx_Length )
0120 return;
0121
0122 ch = Rx_Buffer[ Rx_Index++ ];
0123 rtems_termios_enqueue_raw_characters (Ttyp, (char *)&ch, 1);
0124 #if defined(TASK_DRIVEN)
0125 rtems_termios_rxirq_occured(Ttyp);
0126 #endif
0127
0128 (void) rtems_timer_fire_after( Rx_Timer, 10, Rx_ISR, NULL );
0129 }
0130
0131 rtems_timer_service_routine Tx_ISR(
0132 rtems_id ignored_id,
0133 void *ignored_address
0134 )
0135 {
0136 rtems_termios_dequeue_characters (Ttyp, 1);
0137
0138 (void) rtems_timer_fire_after( Tx_Timer, 10, Tx_ISR, NULL );
0139 }
0140
0141 void termios_test_driver_set_rx_enqueue_now(
0142 bool value
0143 )
0144 {
0145 Rx_EnqueueNow = value;
0146 }
0147
0148 void termios_test_driver_set_rx(
0149 const void *p,
0150 size_t len
0151 )
0152 {
0153 Rx_Buffer = p;
0154 Rx_Length = len;
0155 Rx_Index = 0;
0156
0157 if ( Rx_EnqueueNow == false) {
0158 (void) rtems_timer_fire_after( Rx_Timer, 10, Rx_ISR, NULL );
0159 return;
0160 }
0161
0162 do {
0163 uint8_t ch;
0164 ch = Rx_Buffer[ Rx_Index++ ];
0165 rtems_termios_enqueue_raw_characters (Ttyp, (char *)&ch, 1);
0166 } while (Rx_Index < Rx_Length );
0167 }
0168
0169 ssize_t termios_test_driver_write_helper(
0170 int port,
0171 const char *buf,
0172 size_t len
0173 )
0174 {
0175 if (len > 0) {
0176 Tx_Buffer[Tx_Index++] = buf[0];
0177 (void) rtems_timer_fire_after( Tx_Timer, 10, Tx_ISR, NULL );
0178 }
0179
0180 return 0;
0181 }
0182
0183
0184
0185
0186 int termios_test_driver_set_attributes(
0187 int minor,
0188 const struct termios *t
0189 )
0190 {
0191 return 0;
0192 }
0193
0194
0195
0196
0197 rtems_device_driver termios_test_driver_initialize(
0198 rtems_device_major_number major,
0199 rtems_device_minor_number minor,
0200 void *arg
0201 )
0202 {
0203 rtems_termios_initialize();
0204
0205
0206
0207
0208 (void) rtems_io_register_name( TERMIOS_TEST_DRIVER_DEVICE_NAME, major, 0 );
0209
0210 return RTEMS_SUCCESSFUL;
0211 }
0212
0213 static int first_open(int major, int minor, void *arg)
0214 {
0215 rtems_status_code status;
0216
0217 status = rtems_timer_create(rtems_build_name('T', 'M', 'R', 'X'), &Rx_Timer);
0218 if ( status != RTEMS_SUCCESSFUL )
0219 rtems_fatal_error_occurred(1);
0220
0221 status = rtems_timer_create(rtems_build_name('T', 'M', 'T', 'X'), &Tx_Timer);
0222 if ( status != RTEMS_SUCCESSFUL )
0223 rtems_fatal_error_occurred(1);
0224
0225 return 0;
0226 }
0227
0228 static int last_close(int major, int minor, void *arg)
0229 {
0230 rtems_status_code status;
0231
0232 status = rtems_timer_cancel(Rx_Timer);
0233 if ( status != RTEMS_SUCCESSFUL )
0234 rtems_fatal_error_occurred(1);
0235
0236 status = rtems_timer_cancel(Tx_Timer);
0237 if ( status != RTEMS_SUCCESSFUL )
0238 rtems_fatal_error_occurred(1);
0239
0240 status = rtems_timer_delete(Rx_Timer);
0241 if ( status != RTEMS_SUCCESSFUL )
0242 rtems_fatal_error_occurred(1);
0243
0244 status = rtems_timer_delete(Tx_Timer);
0245 if ( status != RTEMS_SUCCESSFUL )
0246 rtems_fatal_error_occurred(1);
0247
0248 return 0;
0249 }
0250
0251 rtems_device_driver termios_test_driver_open(
0252 rtems_device_major_number major,
0253 rtems_device_minor_number minor,
0254 void * arg
0255 )
0256 {
0257 rtems_status_code sc;
0258 rtems_libio_open_close_args_t *args = arg;
0259 static const rtems_termios_callbacks Callbacks = {
0260 first_open,
0261 last_close,
0262 #if defined(TASK_DRIVEN)
0263 termios_test_driver_inbyte_nonblocking,
0264 #else
0265 NULL,
0266 #endif
0267 termios_test_driver_write_helper,
0268 termios_test_driver_set_attributes,
0269 NULL,
0270 NULL,
0271 #if defined(TASK_DRIVEN)
0272 TERMIOS_TASK_DRIVEN
0273 #else
0274 TERMIOS_POLLED
0275 #endif
0276 };
0277
0278 if ( minor > 2 ) {
0279 puts( "ERROR - Termios_testdriver - only 1 minor supported" );
0280 rtems_test_exit(0);
0281 }
0282
0283 sc = rtems_termios_open (major, minor, arg, &Callbacks);
0284 directive_failed( sc, "termios open" );
0285
0286 Ttyp = args->iop->data1;
0287
0288 return RTEMS_SUCCESSFUL;
0289 }
0290
0291 rtems_device_driver termios_test_driver_close(
0292 rtems_device_major_number major,
0293 rtems_device_minor_number minor,
0294 void * arg
0295 )
0296 {
0297 return rtems_termios_close (arg);
0298 }
0299
0300 rtems_device_driver termios_test_driver_read(
0301 rtems_device_major_number major,
0302 rtems_device_minor_number minor,
0303 void * arg
0304 )
0305 {
0306 return rtems_termios_read (arg);
0307 }
0308
0309 rtems_device_driver termios_test_driver_write(
0310 rtems_device_major_number major,
0311 rtems_device_minor_number minor,
0312 void * arg
0313 )
0314 {
0315 return rtems_termios_write (arg);
0316 }
0317
0318 rtems_device_driver termios_test_driver_control(
0319 rtems_device_major_number major,
0320 rtems_device_minor_number minor,
0321 void * arg
0322 )
0323 {
0324 return rtems_termios_ioctl (arg);
0325 }