Hi,
I'm using RT-Linux version 2.2.14-rtl2.2 downloaded as prepatched
archive.
After installing I wrote my first rtl module which creates a variable
count of threads which were reading periodic a byte from a serial port
and write them to fifos.
This was running last week.
Today, after insmoding the module, I get a reboot of the system.
I needed some tries until I found that the call of 'rtl_setclockmode()'
is the reason.
I attached the file if you want to test this.
What I wanted to test is, if it's possible to have 4-6 threads running
reading with a frequency of 2 kHz
data from a port address (later this should be a A/D board with
analog/digital I/O using comedi as driver),
writing this data to fifos and do some mathematics inside an other RT
process with this data on a Pentium 133 MHz.
I'm new in RTLinux, and I noticed, that the documentation coming with
RTL is very spare. Is there more on writing
driver and processes?
I tried to compile 'monotonic' downloaded from the RTL application page,
but I my system miss the file
/usr/src/rtlinux/include/linux/modversions.h. I searched my disc, but
could not find it. I tried to mail to author, but he address is
unreachable. Does someone run 'monotonic' on rtl2.2?
Maybe it's only working with older versions. If so, which on should I
prefer?
TIA
Vasili
/************************************************************************************************/
all: rtltest.o
rtltest.o: rtltest.c
make -f /usr/src/rtlinux/rtl.mk $@
/*************************************************************************************************/
/* rtltest.c */
#include <asm/io.h>
#include <linux/vmalloc.h>
#include <rtl.h>
#include <rtl_fifo.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
int THREADCOUNT=1;
float FREQUENCY=2000; /* frequ. of thread run time in HZ */
int fifo_size=4000; /*size of rtl fifos*/
unsigned long address = 0x2F8; /* address of /dev/ttyS0 */
MODULE_PARM ( THREADCOUNT, "i" );
MODULE_PARM_DESC( THREADCOUNT, "Count of threads how will run
concurent");
MODULE_PARM ( FREQUENCY, "i" );
MODULE_PARM_DESC( FREQUENCY, "Frequency of thread calls" );
MODULE_PARM ( WORKTIME, "i" );
MODULE_PARM_DESC( WORKTIME, "Time let thread sleep" );
MODULE_PARM ( address, "i" );
pthread_t *thread;
int init_module ( void );
void cleanup_module ( void );
void delete_threads ( unsigned int first, unsigned int last );
void * start_routine ( void *arg );
void * thread_code ( void *param );
int init_module ( void ) {
int thread_creation = 0,
thread_index = 0;
/* unsigned long tmp = 0; */
if ( THREADCOUNT > 15 ){
rtl_printf ( "max of 15 threads! Try again." );
return -1;
}
thread = (pthread_t *) vmalloc ( sizeof ( pthread_t ) * THREADCOUNT );
if ( thread == NULL ){
rtl_printf ( "error allocating memory to store threads\n" );
return -1;
}
for ( thread_index = 0; thread_index < THREADCOUNT; thread_index++ ) {
thread_creation = pthread_create ( &thread[thread_index], NULL,
start_routine, (void*)thread_index );
if ( thread_creation != 0 ) {
if ( thread_index > 0 ) {
delete_threads ( 0, thread_index-1 );
}
return -1;
}
}
return 0;
}
void cleanup_module ( void ) {
delete_threads ( 0, THREADCOUNT );
vfree ( thread );
}
void delete_threads ( unsigned int first, unsigned int last ){
int Index = 0;
for( Index = first; Index < last; Index++ ){
close ( Index );
rtl_printf ( "fifo %d closed\n", Index );
rtf_destroy ( Index );
rtl_printf ( "fifo %d destroyed\n", Index );
if ( pthread_delete_np ( thread[Index] ) != 0 )
rtl_printf ( "can't delete thread number %d\n", Index ) ;
else
rtl_printf ( "thread number %d deleted\n", Index );
/*
* pthread_cancel ( thread[ Index ] );
* pthread_join ( thread[ Index ] );
*/
}
}
void * start_routine( void *arg ){
pthread_attr_t attr;
struct sched_param sched_param;
int thread_status;
int thread_index = (int)arg;
int fifo_status = 0;
rtl_printf ( "About to create threads number %d\n", thread_index );
rtl_printf ("RTL rtltest module on CPU %d\n", rtl_getcpuid() );
pthread_attr_init ( &attr );
sched_param.sched_priority = 1;
pthread_attr_setschedparam ( &attr, &sched_param );
/*
* pthread_setcancelstate ( PTHREAD_CANCEL_ENABLE, NULL );
* pthread_setcanceltype ( PTHREAD_CANCEL_ASYNCHRONOUS );
*/
rtf_destroy ( thread_index );
rtl_printf ( "going to create fifo number %d\n", thread_index );
fifo_status = rtf_create ( thread_index, fifo_size );
if ( fifo_status ) {
rtl_printf ( "rtltest fail. fifo_status of fifo number %d = %d\n",
thread_index,
fifo_status );
return (void*)-1;
}
thread_status = pthread_create ( &thread[ thread_index ], &attr,
thread_code, (void *)thread_index);
if( thread_status != 0 ){
rtl_printf( "creation of thread failed.\n" );
return (void*)-1;
}
return (void*)0;
}
void * thread_code ( void *param ) {
hrtime_t start_time;
DECLARE_CPUID(cpu_id);
struct timespec resolution;
unsigned int thread_index = (unsigned int)param;
unsigned char byte = 0;
unsigned long ulong = 0, tmplong = 0;
char fifo_path[ sizeof("/dev/rtf") + 3 ];
int fd_fifo = -1, written = -1;
hrtime_t period = ( 1 / FREQUENCY ) * 1000 * 1000 * 1000; /*period in
nano sec.*/
/*
* int ret = rtl_setclockmode ( rtl_getschedclock(),
RTL_CLOCK_MODE_PERIODIC,
*
period );
* if (ret != 0) {
* rtl_printf("Setting mode failed\n");
* return (void*)-1;
* }
*/
sprintf ( fifo_path, "/dev/rtf%d", thread_index );
rtl_printf ( "going to open %s\n", fifo_path );
fd_fifo = open( fifo_path, O_NONBLOCK );
if ( fd_fifo < 0 ) {
rtl_printf ( "/dev/rtf%d open returned %d. errno = %d\n",
thread_index, fd_fifo, errno );
return (void *) -1;
}
/* need to round up the period; should this be done
* in pthread_make_periodic? */
clock_getres (rtl_getschedclock(), &resolution);
period = timespec_to_ns (&resolution);
rtl_printf ( "thread %d opened fifo", thread_index );
/*
* start_time = clock_gethrtime(rtl_getschedclock()) + 2 * period;
//start at actual time + 2 periods
* pthread_make_periodic_np (pthread_self(), start_time, period);
*/
/*
* while ( 1 ){
*
* //do something
* tmplong += 1;
* if ( (tmplong % 100) == 0 )
* rtl_printf ( "thread %d runns %ul times\n", thread_index,
tmplong
);
*
* byte = readb ( address );
* ulong = 0xFFF0 | byte;
* written = write ( fd_fifo, &ulong, sizeof( ulong ) );
* if ( written < sizeof( ulong ) )
* rtl_printf ( "write returned %d. errno = %d", written, errno );
*
*
*
* pthread_wait_np (); // now sleep until next period expires
* }
*
*/
return (void*)0;
}
-- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
---
For more information on Real-Time Linux see:
http://www.rtlinux.org/rtlinux/