00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdio.h>
00024 #include <signal.h>
00025 #include <unistd.h>
00026 #include <sys/mman.h>
00027
00028 #include <native/task.h>
00029 #include <native/timer.h>
00030
00031 #include <rtdm/rtserial.h>
00032
00033 #define MAIN_PREFIX "main : "
00034 #define WTASK_PREFIX "write_task: "
00035 #define RTASK_PREFIX "read_task: "
00036
00037 #define WRITE_FILE "rtser0"
00038 #define READ_FILE "rtser1"
00039
00040 int read_fd = -1;
00041 int write_fd = -1;
00042
00043 #define STATE_FILE_OPENED 1
00044 #define STATE_TASK_CREATED 2
00045
00046 unsigned int read_state = 0;
00047 unsigned int write_state = 0;
00048
00049
00050 RTIME write_task_period_ns = 100000000llu;
00051 RT_TASK write_task;
00052 RT_TASK read_task;
00053
00054 static const struct rtser_config read_config = {
00055 .config_mask = 0xFFFF,
00056 .baud_rate = 115200,
00057 .parity = RTSER_DEF_PARITY,
00058 .data_bits = RTSER_DEF_BITS,
00059 .stop_bits = RTSER_DEF_STOPB,
00060 .handshake = RTSER_DEF_HAND,
00061 .fifo_depth = RTSER_DEF_FIFO_DEPTH,
00062 .rx_timeout = RTSER_DEF_TIMEOUT,
00063 .tx_timeout = RTSER_DEF_TIMEOUT,
00064 .event_timeout = 1000000000,
00065 .timestamp_history = RTSER_RX_TIMESTAMP_HISTORY,
00066 .event_mask = RTSER_EVENT_RXPEND,
00067 };
00068
00069 static const struct rtser_config write_config = {
00070 .config_mask = RTSER_SET_BAUD | RTSER_SET_TIMESTAMP_HISTORY,
00071 .baud_rate = 115200,
00072 .timestamp_history = RTSER_DEF_TIMESTAMP_HISTORY,
00073
00074 };
00075
00076 static int close_file( int fd, char *name)
00077 {
00078 int err, i=0;
00079
00080 do {
00081 i++;
00082 err = rt_dev_close(fd);
00083 switch (err) {
00084 case -EAGAIN:
00085 printf(MAIN_PREFIX "%s -> EAGAIN (%d times)\n",
00086 name, i);
00087 rt_task_sleep(50000);
00088 break;
00089 case 0:
00090 printf(MAIN_PREFIX "%s -> closed\n", name);
00091 break;
00092 default:
00093 printf(MAIN_PREFIX "%s -> %s\n", name,
00094 strerror(-err));
00095 break;
00096 }
00097 } while (err == -EAGAIN && i < 10);
00098
00099 return err;
00100 }
00101
00102 void cleanup_all(void)
00103 {
00104 if (read_state & STATE_FILE_OPENED) {
00105 close_file(read_fd, READ_FILE" (read)");
00106 read_state &= ~STATE_FILE_OPENED;
00107 }
00108
00109 if (write_state & STATE_FILE_OPENED) {
00110 close_file(write_fd, WRITE_FILE " (write)");
00111 write_state &= ~STATE_FILE_OPENED;
00112 }
00113
00114 if (write_state & STATE_TASK_CREATED) {
00115 printf(MAIN_PREFIX "delete write_task\n");
00116 rt_task_delete(&write_task);
00117 write_state &= ~STATE_TASK_CREATED;
00118 }
00119
00120 if (read_state & STATE_TASK_CREATED) {
00121 printf(MAIN_PREFIX "delete read_task\n");
00122 rt_task_delete(&read_task);
00123 read_state &= ~STATE_TASK_CREATED;
00124 }
00125 }
00126
00127 void catch_signal(int sig)
00128 {
00129 cleanup_all();
00130 printf(MAIN_PREFIX "exit\n");
00131 return;
00132 }
00133
00134 void write_task_proc(void *arg)
00135 {
00136 int err;
00137 RTIME write_time;
00138 ssize_t sz = sizeof(RTIME);
00139 ssize_t written = 0;
00140
00141 err = rt_task_set_periodic(NULL, TM_NOW,
00142 rt_timer_ns2ticks(write_task_period_ns));
00143 if (err) {
00144 printf(WTASK_PREFIX "error on set periodic, %s\n",
00145 strerror(-err));
00146 goto exit_write_task;
00147 }
00148
00149 while (1) {
00150 err = rt_task_wait_period(NULL);
00151 if (err) {
00152 printf(WTASK_PREFIX
00153 "error on rt_task_wait_period, %s\n",
00154 strerror(-err));
00155 break;
00156 }
00157
00158 write_time = rt_timer_read();
00159
00160 written = rt_dev_write(write_fd, &write_time, sz);
00161 if (written < 0 ) {
00162 printf(WTASK_PREFIX "error on rt_dev_write, %s\n",
00163 strerror(-err));
00164 break;
00165 } else if (written != sz) {
00166 printf(WTASK_PREFIX "only %d / %d byte transmitted\n",
00167 written, sz);
00168 break;
00169 }
00170 }
00171
00172 exit_write_task:
00173 if ((write_state & STATE_FILE_OPENED) &&
00174 close_file(write_fd, WRITE_FILE " (write)") == 0)
00175 write_state &= ~STATE_FILE_OPENED;
00176
00177 printf(WTASK_PREFIX "exit\n");
00178 }
00179
00180 void read_task_proc(void *arg)
00181 {
00182 int err;
00183 int nr = 0;
00184 RTIME read_time = 0;
00185 RTIME write_time = 0;
00186 RTIME irq_time = 0;
00187 ssize_t sz = sizeof(RTIME);
00188 ssize_t read = 0;
00189 struct rtser_event rx_event;
00190
00191 printf(" Nr | write->irq | irq->read | write->read |\n");
00192 printf("-----------------------------------------------------------\n");
00193
00194
00195
00196
00197
00198
00199
00200 while (1) {
00201
00202 err = rt_dev_ioctl(read_fd, RTSER_RTIOC_WAIT_EVENT, &rx_event);
00203 if (err) {
00204 printf(RTASK_PREFIX
00205 "error on RTSER_RTIOC_WAIT_EVENT, %s\n",
00206 strerror(-err));
00207 if (err == -ETIMEDOUT)
00208 continue;
00209 break;
00210 }
00211
00212 irq_time = rx_event.rxpend_timestamp;
00213 read = rt_dev_read(read_fd, &write_time, sz);
00214 if (read == sz) {
00215 read_time = rt_timer_read();
00216 printf("%3d |%16llu |%16llu |%16llu\n", nr,
00217 irq_time - write_time,
00218 read_time - irq_time,
00219 read_time - write_time);
00220 nr++;
00221 } else if (read < 0 ) {
00222 printf(RTASK_PREFIX "error on rt_dev_read, code %s\n",
00223 strerror(-err));
00224 break;
00225 } else {
00226 printf(RTASK_PREFIX "only %d / %d byte received \n",
00227 read, sz);
00228 break;
00229 }
00230 }
00231
00232 if ((read_state & STATE_FILE_OPENED) &&
00233 close_file(read_fd, READ_FILE " (read)") == 0)
00234 read_state &= ~STATE_FILE_OPENED;
00235
00236 printf(RTASK_PREFIX "exit\n");
00237 }
00238
00239 int main(int argc, char* argv[])
00240 {
00241 int err = 0;
00242
00243 signal(SIGTERM, catch_signal);
00244 signal(SIGINT, catch_signal);
00245
00246
00247 mlockall(MCL_CURRENT | MCL_FUTURE);
00248
00249
00250 write_fd = rt_dev_open( WRITE_FILE, 0);
00251 if (write_fd < 0) {
00252 printf(MAIN_PREFIX "can't open %s (write), %s\n", WRITE_FILE,
00253 strerror(-write_fd));
00254 goto error;
00255 }
00256 write_state |= STATE_FILE_OPENED;
00257 printf(MAIN_PREFIX "write-file opened\n");
00258
00259
00260 err = rt_dev_ioctl(write_fd, RTSER_RTIOC_SET_CONFIG, &write_config);
00261 if (err) {
00262 printf(MAIN_PREFIX "error while RTSER_RTIOC_SET_CONFIG, %s\n",
00263 strerror(-err));
00264 goto error;
00265 }
00266 printf(MAIN_PREFIX "write-config written\n");
00267
00268
00269 read_fd = rt_dev_open( READ_FILE, 0 );
00270 if (read_fd < 0) {
00271 printf(MAIN_PREFIX "can't open %s (read), %s\n", READ_FILE,
00272 strerror(-read_fd));
00273 goto error;
00274 }
00275 read_state |= STATE_FILE_OPENED;
00276 printf(MAIN_PREFIX "read-file opened\n");
00277
00278
00279 err = rt_dev_ioctl(read_fd, RTSER_RTIOC_SET_CONFIG, &read_config);
00280 if (err) {
00281 printf(MAIN_PREFIX "error while rt_dev_ioctl, %s\n",
00282 strerror(-err));
00283 goto error;
00284 }
00285 printf(MAIN_PREFIX "read-config written\n");
00286
00287
00288 err = rt_task_create(&write_task, "write_task", 0, 50, 0);
00289 if (err) {
00290 printf(MAIN_PREFIX "failed to create write_task, %s\n",
00291 strerror(-err));
00292 goto error;
00293 }
00294 write_state |= STATE_TASK_CREATED;
00295 printf(MAIN_PREFIX "write-task created\n");
00296
00297
00298 err = rt_task_create(&read_task, "read_task", 0, 51, 0);
00299 if (err) {
00300 printf(MAIN_PREFIX "failed to create read_task, %s\n",
00301 strerror(-err));
00302 goto error;
00303 }
00304 read_state |= STATE_TASK_CREATED;
00305 printf(MAIN_PREFIX "read-task created\n");
00306
00307
00308 printf(MAIN_PREFIX "starting write-task\n");
00309 err = rt_task_start(&write_task, &write_task_proc, NULL);
00310 if (err) {
00311 printf(MAIN_PREFIX "failed to start write_task, %s\n",
00312 strerror(-err));
00313 goto error;
00314 }
00315
00316
00317 printf(MAIN_PREFIX "starting read-task\n");
00318 err = rt_task_start(&read_task,&read_task_proc,NULL);
00319 if (err) {
00320 printf(MAIN_PREFIX "failed to start read_task, %s\n",
00321 strerror(-err));
00322 goto error;
00323 }
00324
00325 pause();
00326 return 0;
00327
00328 error:
00329 cleanup_all();
00330 return err;
00331 }