From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: <491C6ED8.6030903@domain.hid> Date: Thu, 13 Nov 2008 19:15:52 +0100 From: Gilles Chanteperdrix MIME-Version: 1.0 References: <491805AE.1060809@domain.hid> In-Reply-To: <491805AE.1060809@domain.hid> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Subject: Re: [Xenomai-help] Mode switch when using RT heap on ARM List-Id: Help regarding installation and common use of Xenomai List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Wolfgang Grandegger Cc: xenomai-help Wolfgang Grandegger wrote: > Hello, > > I realized that accessing memory allocated with rt_heap_alloc() causes > mode switches on ARM i.mx31. The attached patch provides a demo program > to demonstrate the problem, which actually does *not* show up on my > PowerPC TQM5200 board. Index: xenomai-2.4.x/examples/native/rtheap.c =================================================================== --- /dev/null +++ xenomai-2.4.x/examples/native/rtheap.c @@ -0,0 +1,164 @@ +#include +#include +#include +#include + +#include +#include +#include + +#define USE_HEAP +//#define USE_SIGXCPU + +#define HEAP_SIZE (1024*1024) +#define HEAP_MODE 0 /* Local heap. */ + +RT_HEAP heap_desc; +RT_TASK demo_task; + + +static int block_sizes[] = {16, 20, 90, 150, 310, 800, 1000}; + +/* NOTE: error handling omitted. */ + +void demo(void *arg) +{ + RTIME now, previous; + void *block; + int sizes = sizeof(block_sizes) / sizeof(int); + int count = 0; + int size, err; + int *ptr; + +#ifdef USE_SIGXCPU + /* Ask Xenomai to warn us upon switches to secondary mode. */ + rt_task_set_mode(0, T_WARNSW, NULL); +#endif + + /* + * Arguments: &task (NULL=self), + * start time, + * period (here: 1 s) + */ + rt_task_set_periodic(NULL, TM_NOW, 10000000); + previous = rt_timer_read(); + + while (1) { + rt_task_wait_period(NULL); + now = rt_timer_read(); + + size = block_sizes[count % sizes]; +#ifdef USE_HEAP + /* + * Request a 16-bytes block, asking for a non-blocking call + * since only Xenomai tasks may block. + */ + err = rt_heap_alloc(&heap_desc, size, TM_NONBLOCK, &block); + if (err) { + printf("rt_heap_alloc() failed with %d\n", err); + break; + } + + ptr = (int *)block; + *ptr = 0xdeadbeef; + if (*ptr != 0xdeadbeef) { + printf("Write/read test to heap failed\n"); + break; + } + + ptr = (int *)(block + size - sizeof(int)); This is not guaranteed to be aligned on an int. Could you try: ptr = (int *)(((unsigned long) block + size - sizeof(int)) & ~3); -- Gilles.