rt_serial_uprog.c
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/poll.h>
#include <rtai_lxrt.h>
#include <rtdm/rtserial.h>
#define LOG_PREFIX "rt_serial_uprog: "
#define WTASK_PREFIX "write_task: "
#define RTASK_PREFIX "read_task : "
#define RTSER_FILE "rtser0"
#define READ_FILE "rtser1"
int timer_started = 0;
int my_fd = -1;
#define STATE_FILE_OPENED 1
#define STATE_TASK_CREATED 2
unsigned int my_state = 0;
RT_TASK *maint;
// --s-ms-us-ns
RTIME write_task_period_ns = 1000000000llu;
RT_TASK *write_task;
RT_TASK *read_task;
static pthread_t write_thr, read_thr;
static const struct rtser_config ser_config = {
0xFFFF, /* config_mask */
9600, /* baud_rate */
RTSER_DEF_PARITY, /* parity */
RTSER_DEF_BITS, /* data_bits */
RTSER_DEF_STOPB, /* stop_bits */
RTSER_DEF_HAND, /* handshake */
RTSER_DEF_FIFO_DEPTH, /* fifo_depth*/
RTSER_DEF_TIMEOUT, /* rx_timeout */
RTSER_DEF_TIMEOUT, /* tx_timeout */
RTSER_DEF_TIMEOUT, /* event_timeout */
RTSER_RX_TIMESTAMP_HISTORY, /* timestamp_history */
RTSER_EVENT_RXPEND /* event mask */
};
static int close_file(int fd, char *name) {
int ret, i = 0;
do {
i++;
ret = rt_dev_close(fd);
switch(-ret){
case EBADF: printf(LOG_PREFIX "%s -> invalid fd or context\n",name);
break;
case EAGAIN: printf(LOG_PREFIX "%s -> EAGAIN (%d times)\n",name,i);
rt_sleep(nano2count(50000)); // wait 50us
break;
case 0: printf(LOG_PREFIX "%s -> closed\n",name);
break;
default: printf(LOG_PREFIX "%s -> ???\n",name);
break;
}
} while (ret == -EAGAIN && i < 10);
return ret;
}
void cleanup_all(void) {
if (my_state & STATE_FILE_OPENED) {
close_file( my_fd, READ_FILE" (read)");
my_state &= ~STATE_FILE_OPENED;
}
if (my_state & STATE_TASK_CREATED) {
printf(LOG_PREFIX "delete write_task\n");
rt_task_delete(write_task);
printf(LOG_PREFIX "delete read_task\n");
rt_task_delete(read_task);
my_state &= ~STATE_TASK_CREATED;
}
if (timer_started) {
printf(LOG_PREFIX "stop timer\n");
stop_rt_timer();
}
stop_rt_timer();
printf("end cleanup\n");
}
void catch_signal(int sig) {
pthread_join(write_thr, NULL);
pthread_join(read_thr, NULL);
cleanup_all();
rt_task_delete(maint);
printf(LOG_PREFIX "exit\n");
return;
}
void write_task_proc(void *arg) {
int ret;
ssize_t sz = sizeof(RTIME);
ssize_t written = 0;
unsigned char buf[17] = "CAPTAIN WAS HERE\0";
write_task = rt_task_init_schmod(nam2num("WRTSK"),
2, 0, 0, SCHED_FIFO, 0xF);
poll(0, 0, 10);
mlockall(MCL_CURRENT | MCL_FUTURE);
rt_make_hard_real_time();
rt_task_make_periodic_relative_ns(NULL, 0,
write_task_period_ns);
while (1) {
ret = rt_task_wait_period();
if (ret) {
printf(WTASK_PREFIX "error while rt_task_wait_period, code %d\n",ret);
goto exit_write_task;
}
sz = sizeof(buf);
written = rt_dev_write(my_fd, &buf, sizeof(buf));
printf(WTASK_PREFIX "rt_dev_write written=%d sz=%d\n", written, sz);
if (written != sz ) {
if (written < 0 ) {
printf(WTASK_PREFIX "error while rt_dev_write, code %d\n",written);
} else {
printf(WTASK_PREFIX "only %d / %d byte transmitted\n", written, sz);
}
goto exit_write_task;
}
}
exit_write_task:
if (my_state & STATE_FILE_OPENED) {
if (!close_file( my_fd, RTSER_FILE " (write)")) {
my_state &= ~STATE_FILE_OPENED;
}
rt_make_soft_real_time();
rt_task_delete(write_task);
}
printf(WTASK_PREFIX "exit\n");
}
void read_task_proc(void *arg) {
int ret;
ssize_t sz = sizeof(RTIME);
ssize_t red = 0;
struct rtser_event rx_event;
unsigned char buf[17];
read_task = rt_task_init_schmod(nam2num("RDTSK"), 1, 0, 0, SCHED_FIFO, 0xF);
poll(0, 0, 10);
mlockall(MCL_CURRENT | MCL_FUTURE);
rt_make_hard_real_time();
while (1) {
/* waiting for event */
ret = rt_dev_ioctl(my_fd, RTSER_RTIOC_WAIT_EVENT, &rx_event );
if (ret) {
printf(RTASK_PREFIX "error while RTSER_RTIOC_WAIT_EVENT, code %d\n",ret);
goto exit_read_task;
}
sz = sizeof(buf);
red = rt_dev_read(my_fd, &buf, sizeof(buf));
if (red == sz ) {
printf(RTASK_PREFIX "rt_dev_read=%s\n",buf);
} else {
if (red < 0 ) {
printf(RTASK_PREFIX "error while rt_dev_read, code %d\n",red);
} else {
printf(RTASK_PREFIX "only %d / %d byte received \n",red,sz);
}
goto exit_read_task;
}
}
exit_read_task:
if (my_state & STATE_FILE_OPENED) {
if (!close_file( my_fd, READ_FILE " (read)")) {
my_state &= ~STATE_FILE_OPENED;
}
}
rt_make_soft_real_time();
rt_task_delete(read_task);
}
int main(int argc, char* argv[]) {
int ret = 0;
signal(SIGTERM, catch_signal);
signal(SIGINT, catch_signal);
signal(SIGKILL, catch_signal);
maint = rt_task_init_schmod(nam2num("MAIN"), 3, 0, 0, SCHED_FIFO, 0xF);
rt_set_oneshot_mode();
start_rt_timer(0);
/* open rtser1 */
my_fd = rt_dev_open(RTSER_FILE, 0);
if (my_fd < 0) {
printf(LOG_PREFIX "can't open %s (read)\n", RTSER_FILE);
goto error;
}
my_state |= STATE_FILE_OPENED;
printf(LOG_PREFIX "read-file opened\n");
/* writing read-config */
ret = rt_dev_ioctl(my_fd, RTSER_RTIOC_SET_CONFIG, &ser_config);
if (ret) {
printf(LOG_PREFIX "error while rt_dev_ioctl, code %d\n",ret);
goto error;
}
printf(LOG_PREFIX "read-config written\n");
/* create read_task */
pthread_create(&read_thr, NULL, (void *)read_task_proc, NULL);
my_state |= STATE_TASK_CREATED;
printf(LOG_PREFIX "read-task created\n");
/* create write_task */
pthread_create(&write_thr, NULL, (void *)write_task_proc, NULL);
my_state |= STATE_TASK_CREATED;
printf(LOG_PREFIX "write-task created\n");
pause();
return 0;
error:
cleanup_all();
return ret;
}
|
rt_serial_uprog.c
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/mman.h>
#include <native/task.h>
#include <native/timer.h>
#include <rtdm/rtserial.h>
#define LOG_PREFIX "rt_serial_uprog: "
#define WTASK_PREFIX "write_task: "
#define RTASK_PREFIX "read_task : "
#define RTSER_FILE "rtser0"
#define READ_FILE "rtser0"
int timer_started = 0;
int my_fd = -1;
#define STATE_FILE_OPENED 1
#define STATE_TASK_CREATED 2
unsigned int my_state = 0;
// --s-ms-us-ns
RTIME write_task_period_ns = 1000000000llu;
RT_TASK write_task;
RT_TASK read_task;
static const struct rtser_config ser_config = {
0xFFFF, /* config_mask */
RTSER_9600_BAUD, /* baud_rate */
RTSER_ODD_PARITY , /* parity */
RTSER_8_BITS , /* data_bits */
RTSER_1_STOPB , /* stop_bits */
RTSER_NO_HAND , /* handshake */
RTSER_DEF_FIFO_DEPTH, /* fifo_depth*/
RTSER_DEF_TIMEOUT, /* rx_timeout */
RTSER_DEF_TIMEOUT, /* tx_timeout */
RTSER_DEF_TIMEOUT, /* event_timeout */
RTSER_RX_TIMESTAMP_HISTORY, /* timestamp_history */
RTSER_EVENT_RXPEND /* event mask */
};
static int close_file( int fd, unsigned char *name) {
int ret,i=0;
do {
i++;
ret = rt_dev_close(fd);
switch(-ret){
case EBADF: printf(LOG_PREFIX "%s -> invalid fd or context\n",name);
break;
case EAGAIN: printf(LOG_PREFIX "%s -> EAGAIN (%d times)\n",name,i);
rt_task_sleep(50000); // wait 50us
break;
case 0: printf(LOG_PREFIX "%s -> closed\n",name);
break;
default: printf(LOG_PREFIX "%s -> ???\n",name);
break;
}
} while (ret == -EAGAIN && i < 10);
return ret;
}
void cleanup_all(void) {
if (my_state & STATE_FILE_OPENED) {
close_file( my_fd, RTSER_FILE " (rtser)");
my_state &= ~STATE_FILE_OPENED;
}
if (my_state & STATE_TASK_CREATED) {
printf(LOG_PREFIX "delete write_task\n");
rt_task_delete(&write_task);
my_state &= ~STATE_TASK_CREATED;
}
if (my_state & STATE_TASK_CREATED) {
printf(LOG_PREFIX "delete read_task\n");
rt_task_delete(&read_task);
my_state &= ~STATE_TASK_CREATED;
}
if (timer_started) {
printf(LOG_PREFIX "stop timer\n");
rt_timer_stop();
}
}
void catch_signal(int sig) {
cleanup_all();
printf(LOG_PREFIX "exit\n");
return;
}
void write_task_proc(void *arg) {
int ret;
ssize_t sz = sizeof(RTIME);
ssize_t written = 0;
unsigned char buf[17] = "CAPTAIN WAS HERE\0";
ret = rt_task_set_periodic(NULL, TM_NOW, rt_timer_ns2ticks(write_task_period_ns));
if (ret) {
printf(WTASK_PREFIX "error while set periodic, code %d\n",ret);
goto exit_write_task;
}
while (1) {
/* switch to primary mode */
ret = rt_task_set_mode(0, T_PRIMARY, NULL);
if (ret) {
printf(WTASK_PREFIX "error while rt_task_set_mode, code %d\n",ret);
goto exit_write_task;
}
ret = rt_task_wait_period();
if (ret) {
printf(WTASK_PREFIX "error while rt_task_wait_period, code %d\n",ret);
goto exit_write_task;
}
sz = sizeof(buf);
written = rt_dev_write(my_fd, &buf, sizeof(buf));
printf(WTASK_PREFIX "rt_dev_write written=%d sz=%d\n", written, sz);
if (written != sz ) {
if (written < 0 ) {
printf(WTASK_PREFIX "error while rt_dev_write, code %d\n",written);
} else {
printf(WTASK_PREFIX "only %d / %d byte transmitted\n",written, sz);
}
goto exit_write_task;
}
}
exit_write_task:
if (my_state & STATE_FILE_OPENED) {
if (!close_file( my_fd, RTSER_FILE " (write)")) {
my_state &= ~STATE_FILE_OPENED;
}
}
printf(WTASK_PREFIX "exit\n");
}
void read_task_proc(void *arg) {
int ret;
ssize_t sz = sizeof(RTIME);
ssize_t red = 0;
struct rtser_event rx_event;
unsigned char buf[17];
// we are in secondary mode now
while (1) {
/* switch to primary mode */
ret = rt_task_set_mode(0, T_PRIMARY, NULL);
if (ret) {
printf(RTASK_PREFIX "error while rt_task_set_mode, code %d\n",ret);
goto exit_read_task;
}
/* waiting for event */
// be careful not to do printf or so here. Otherwise rt_dev_ioctl
// returns with an error, because we're not in hard real time
// anymore (primary mode)
ret = rt_dev_ioctl(my_fd, RTSER_RTIOC_WAIT_EVENT, &rx_event );
if (ret) {
printf(RTASK_PREFIX "error while RTSER_RTIOC_WAIT_EVENT, code %d\n",ret);
goto exit_read_task;
}
sz = sizeof(buf);
red = rt_dev_read(my_fd, &buf, sizeof(buf));
if (red == sz ) {
printf(RTASK_PREFIX "rt_dev_read=%s\n",buf);
} else {
if (red < 0 ) {
printf(RTASK_PREFIX "error while rt_dev_read, code %d\n",red);
} else {
printf(RTASK_PREFIX "only %d / %d byte received \n",red,sz);
}
goto exit_read_task;
}
}
exit_read_task:
if (my_state & STATE_FILE_OPENED) {
if (!close_file( my_fd, READ_FILE " (rtser)")) {
my_state &= ~STATE_FILE_OPENED;
}
}
printf(RTASK_PREFIX "exit\n");
}
int main(int argc, char* argv[]) {
int ret = 0;
signal(SIGTERM, catch_signal);
signal(SIGINT, catch_signal);
printf(LOG_PREFIX "PRESS CTRL-C to EXIT\n");
/* no memory-swapping for this programm */
mlockall(MCL_CURRENT | MCL_FUTURE);
/* start timer */
ret = rt_timer_start(TM_ONESHOT);
switch (ret) {
case 0: printf(LOG_PREFIX "timer started\n");
timer_started = 1;
break;
case -EBUSY: printf(LOG_PREFIX "timer is running\n");
timer_started = 0;
break;
case -ENOSYS: printf(LOG_PREFIX "can't start timer\n");
return ret;
}
/* open rtser0 */
my_fd = rt_dev_open( RTSER_FILE, 0);
if (my_fd < 0) {
printf(LOG_PREFIX "can't open %s\n", RTSER_FILE);
goto error;
}
my_state |= STATE_FILE_OPENED;
printf(LOG_PREFIX "rtser_file opened\n");
/* writing write-config */
ret = rt_dev_ioctl(my_fd, RTSER_RTIOC_SET_CONFIG, &ser_config);
if (ret) {
printf(LOG_PREFIX "error while RTSER_RTIOC_SET_CONFIG, code %d\n",ret);
goto error;
}
printf(LOG_PREFIX "serial-port-config written\n");
/* create read_task */
ret = rt_task_create(&read_task,"read_task",0,51,0);
if (ret) {
printf(LOG_PREFIX "failed to create read_task, code %d\n",ret);
goto error;
}
my_state |= STATE_TASK_CREATED;
printf(LOG_PREFIX "read-task created\n");
/* create write_task */
ret = rt_task_create(&write_task,"write_task",0,50,0);
if (ret) {
printf(LOG_PREFIX "failed to create write_task, code %d\n",ret);
goto error;
}
my_state |= STATE_TASK_CREATED;
printf(LOG_PREFIX "write-task created\n");
/* start write_task */
printf(LOG_PREFIX "starting write-task\n");
ret = rt_task_start(&write_task,&write_task_proc,NULL);
if (ret) {
printf(LOG_PREFIX "failed to start write_task, code %d\n",ret);
goto error;
}
/* start read_task */
printf(LOG_PREFIX "starting read-task\n");
ret = rt_task_start(&read_task,&read_task_proc,NULL);
if (ret) {
printf(LOG_PREFIX "failed to start read_task, code %d\n",ret);
goto error;
}
pause();
return 0;
error:
cleanup_all();
return ret;
}
|