[Date Prev][Date Next] [Chronological] [Thread] [Top]

[rtl] Shared Memory problem (the non-messy edition)



>I know this subject has been beaten to death but I can't seem to get it to go on my system. 
>[snip]
>Garth Gaddy


Hi Garth,

Nice to meet you at the show, I looked at your code, and I can't see
anything obviously wrong.

I have attached a stand alone test program that gives a simple example
of using shared memory. I tested it on rtl 0.9j+ (1.0) and 2.0.36.  You
may need to change the -I in the makefile and some hash defines for the
size of memory on your system.

Details of how to use it are in the source header.

I hope this works for you.

Regards

Stuart.

-

Visit http://www.zentropix.com/ for Real Time Linux Tools
////////////////////////////////////////////////////////////////////////////////
//
//      Copyright © 1998 Zentropic Computing, All rights reserved
//
// Authors:		Stuart Hughes
// Original date:	Mon 16 Aug 1999
// Id:			@(#)$Id$
// License:		GPL
//
// Description:		This is an example that shows how to set up shared
//			memory under real time Linux to allow access
//			from both user and real time context.  Build it by
//			typing "make -f Makefile.shm", to run the program,
//			do an insmod of rtl_sched, and shm_rt.  Next run
//			./shm.  If it is working, you should see an
//			incrementing number printed at the tty.
//
// Scheme		The user space loop increments a counter in shared
//			memory, this location is copied in the real-time
//			task (asynchronously) to another shared memory 
//			location.  The user space print the contents of
//			the shared memory location written to by the
//			real time task.
//
// Variables		Shared memory is reserved by adding a line like
//			append="mem=63m" (example to reserve 1 meg in a
//			64 meg machine)
//			The include path for RTL may need chaning in the
//			Makefile.shm for your system
//
// Notes:		For 2.2 kernels you need to uses ioremap and iounmap
//			in place of vremap and vfree.
//			Error checking omitted for clarity.
//
//
////////////////////////////////////////////////////////////////////////////////
static char id_shm_c[] __attribute__ ((unused)) = "@(#)$Id$";


// change this line if you have a different memory size
#define SHM_BASE	((63 * 0x100000))

struct shm_vars
{
    int from_user;
    int to_user;
}; 
struct shm_vars *shm_ptr;

///////////////////////////////////////////////////////////////////////////////
//
// kernel module
//
///////////////////////////////////////////////////////////////////////////////
#ifdef __KERNEL__

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <rtl_sched.h>

RT_TASK task_str;

void func(int arg)
{
    while(1) {
        shm_ptr->to_user = shm_ptr->from_user;
	rt_task_wait();
    }
}

int init_module(void)
{
    shm_ptr = (struct shm_vars *) vremap(SHM_BASE, sizeof(struct shm_vars));
    shm_ptr->from_user = shm_ptr->to_user = 0;

    rt_task_init(&task_str, func, 0, 3000, 4);
    rt_task_make_periodic(&task_str, rt_get_time(), (RT_TICKS_PER_SEC/10000));

    return 0;
}

void cleanup_module(void)
{
    rt_task_suspend(&task_str);
    rt_task_delete(&task_str);
    vfree(shm_ptr);
}

///////////////////////////////////////////////////////////////////////////////
//
// user process
//
///////////////////////////////////////////////////////////////////////////////

#else

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>

int main()
{
    int mem_fd;

    if(( mem_fd = open("/dev/mem", O_RDWR)) < 0) {
	printf("open(/dev/mem, O_RDWR) : %s\n", strerror(errno));
	exit(1);
    }

    shm_ptr = (struct shm_vars *) mmap(0,
                                  sizeof(struct shm_vars),
                                  PROT_READ | PROT_WRITE, 
				  MAP_FILE | MAP_SHARED,
                                  mem_fd, 
				  SHM_BASE );
    if( shm_ptr == MAP_FAILED ) {
	printf("mmap failed: %s\n", strerror(errno));
	exit(1);
    }
    close(mem_fd);

    // main loop, update counter, read back and print copy from RT
    while(1) {

	shm_ptr->from_user++;
	printf("counter = %d\n", shm_ptr->to_user);
	usleep(100000);

    }
}




#endif

# you will need to change this 
INC = -I /usr/src/rtl/include



all: shm shm_rt

shm_rt: shm.c
	gcc $(INC) -D__RT__ -D__KERNEL__ -DMODULE -O2 -g -c -o shm_rt.o shm.c
	ld -r -static -o shm_rt shm_rt.o
	rm shm_rt.o
	 
clean:
	rm shm shm.o shm_rt shm_rt.o