cross-link.c

00001 /*
00002  * cross-link.c
00003  *
00004  * Userspace test program (Xenomai native skin) for RTDM-based UART drivers
00005  * Copyright 2005 by Joerg Langenberg <joergel75@gmx.net>
00006  *
00007  * Updates by Jan Kiszka <jan.kiszka@web.de>
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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 /*                           --s-ms-us-ns */
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, /* 1 s */
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         /* the rest implicitely remains default */
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); /* wait 50us */
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          * We are in secondary mode now due to printf, the next
00196          * blocking Xenomai or driver call will switch us back
00197          * (here: RTSER_RTIOC_WAIT_EVENT).
00198          */
00199 
00200         while (1) {
00201                 /* waiting for event */
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         /* no memory-swapping for this programm */
00247         mlockall(MCL_CURRENT | MCL_FUTURE);
00248 
00249         /* open rtser0 */
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         /* writing write-config */
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         /* open rtser1 */
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         /* writing read-config */
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         /* create write_task */
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         /* create read_task */
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         /* start write_task */
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         /* start read_task */
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 }

Generated on Mon Mar 24 18:02:40 2008 for Xenomai API by  doxygen 1.5.3