RTAI Serial Port Communication Example (LXRT - RS232)
This is a simple RTAI/classic LXRT hard real time serial port example. It will send 3 characters over the serial port,
and if something is received within 100ms, those characters are displayed.
It was developed using the Atmel ATmega16 board, which
will just return any character sent to it via the serial port.
Or use a simple RS232 dummy adapter (loopback plug): Connect PIN 2 (RX) to PIN 3 (TX) (9-pin SUB-D RS232 connector on your machine),
or if you use a 25-pin SUB-D connector: Connect PIN 3 (RX) to PIN 2 (TX).
Tested on RTAI 3.1r2/adeos-linux-2.6.10-i386-r12.patch
and RTAI3.2/hal-linux-2.6.10-i386-r9.patch
Also see: Xenomai serial port example and
Serial (RS232) Port Pins and Registers
Compile the example with the Makefile, load the RTAI modules with loadmods.sh (remove them with rmmods.sh)
and run "serial". Make sure you have some device returning any character hooked up on the serial port,
otherwise you won't see any characters received.
You'll see this on your console:
# ./loadmods.sh
# ./serial
SERIAL TEST ON COM1
Sending data: OK
serial data=CAP
Receiving data: OK
Exiting
serial.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <rtai_serial.h>
#include <rtai_lxrt.h>
#define PERIOD 15625000LL
#define MS100 100000000LL
#define BAUD 9600
#define NUMBITS 8
#define STOPBITS 1
#define BUFLEN 4
int receivedata(int fd) {
unsigned char buf[BUFLEN] = {0};
if(rt_spread_timed(fd, &buf[0], BUFLEN, nano2count(MS100))) {
return 0;
}
printf("serial data=%s\n", buf);
return 1;
}
int senddata(int fd) {
unsigned char buf[BUFLEN];
buf[0] = 0x43;
buf[1] = 0x41;
buf[2] = 0x50;
buf[3] = 0x00;
if (rt_spwrite(fd, buf, sizeof(buf))) { return 0; }
return 1;
}
int main(int argc, char **argv) {
RTIME period;
RT_TASK *task;
int res;
if (!(task = rt_task_init(nam2num("SERTST"), 1, 0, 0))) {
printf("CANNOT INIT SERTST TASK\n");
exit(1);
}
rt_set_oneshot_mode();
start_rt_timer(nano2count(PERIOD));
mlockall(MCL_CURRENT | MCL_FUTURE);
printf("SERIAL TEST ON COM1\n");
res = rt_spopen(COM1, BAUD, NUMBITS, STOPBITS,
RT_SP_PARITY_ODD, RT_SP_NO_HAND_SHAKE, RT_SP_FIFO_DISABLE);
if(res) {
printf("Error: rt_spopen\n");
switch(res) {
case -ENODEV:
printf("No device %d\n", res);
break;
case -EINVAL:
printf("Invalid val %d\n", res);
break;
case -EADDRINUSE:
printf("Address in use %d\n", res);
break;
default:
printf("Unknown %d\n", res);
break;
}
exit(0);
}
rt_spclear_rx(COM1);
rt_spclear_tx(COM1);
rt_make_hard_real_time();
period = nano2count(PERIOD);
rt_task_make_periodic(task, rt_get_time() + 5 * period, period);
if(senddata(COM1)) {
// printf will break hard real time, so don't use it in
// production grade stuff
printf("Sending data: OK\n");
if(receivedata(COM1)) {
printf("Receiving data: OK\n");
} else {
printf("Receiving data: FAILED\n");
}
} else {
printf("Sending data: FAILED\n");
}
rt_task_wait_period();
rt_make_soft_real_time();
rt_spclose(COM1);
stop_rt_timer();
rt_task_delete(task);
printf("Exiting\n");
return 0;
}
Makefile
prefix := $(shell rtai-config --prefix)
ifeq ($(prefix),)
$(error Please add <rtai-install>/bin to your PATH variable)
endif
CC = $(shell rtai-config --cc)
LXRT_CFLAGS = $(shell rtai-config --lxrt-cflags)
LXRT_LDFLAGS = $(shell rtai-config --lxrt-ldflags)
all: serial
serial: serial.c
$(CC) $(LXRT_CFLAGS) -o $@ $< $(LXRT_LDFLAGS)
clean:
rm -f *.o serial
.PHONY: clean
loadmods.sh
#!/bin/sh
TMP=$PWD
cd /usr/realtime/modules/
insmod ./rtai_hal.ko
insmod ./rtai_lxrt.ko
insmod ./rtai_sem.ko
insmod ./rtai_serial.ko
cd $TMP
rmmods.sh
#!/bin/sh
rmmod rtai_serial
rmmod rtai_sem
rmmod rtai_lxrt
rmmod rtai_hal
Last-Modified: Sat, 04 Feb 2006 15:43:19 GMT