All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-help] Working example for direct memory mapped IO
@ 2006-12-13 21:48 Niklaus Giger
  2006-12-14 13:14 ` Jan Kiszka
  0 siblings, 1 reply; 7+ messages in thread
From: Niklaus Giger @ 2006-12-13 21:48 UTC (permalink / raw)
  To: xenomai

[-- Attachment #1: Type: text/plain, Size: 367 bytes --]

Hi

To document basic Xenomai/Linux patterns I developed the attached small 
example for our PPC405 board, which just rolls the 8 debug LEDs.

Are there any comments about it? 

Shall I put it into the Wiki at http://www.xenomai.org/index.php/Examples or 
does somebody want to commit it to the examples part of the subversion trunk?

Best regards

-- 
Niklaus Giger

[-- Attachment #2: hw_direct_io.c.zip --]
[-- Type: application/x-zip, Size: 1467 bytes --]

PK\x03\x04\x14\0\0\0\b\0\x0f¶5HQ\x16&4\x05\0\0µ
\0\0\x0e\0\0\0hw_direct_io.cVmoâ8\x10þ¼üŠQW]%¬\x17Bßv÷ú"! -º–¢@UÝí­"“8à6Ø‘m(Õíío¿±“Ph{/\x11"Ž=žyfæñŒ›õ\x1aÔa<ã\x1aôœf\x19°\x15ç\x19ÃÏ™|Ô€\x7f`$Ð8fZÜͥz‚„+\x16›ì©a÷ö\r<rÜ(Eö\x04R=à\b†ÃÎApx1T0¡š%\x10/´‘s¸¼ƒ‰¤*\x01™Â€iC3¸¦:žqÁ\x04´/Juhy‘%ÄÚfK¦\bL\x180ª9ê§	Í\rêCHšÏyF\x15êÜD¡c%ñEñ…x¿ÀU¯«ÁãÂ0µDk­æžµ­Y,Eâ\x13xœñx\x06T1˜Ó<g‰UeuË9ƒ	7VÖÌ\x18\\fû7ÕøÙµ\I^[\x15©\\x1cƸ-c,\aܶÐ\x18@+¼\ÝaD0˜\x0f\X\x05+&äœr·¡#ó'ŧ3\x03^ìÃ^\x10\x1cÁ€?dt¡á‚O™‚\x13Q|6¦î“\x1a^[ÿ	ST§\r©¦g¨¥Y«½ç"Î\x16	ƒ\x13m\x12.^[³³©4\x16&ÛžB©ŒO¶ç\x16‚ãô\v¹'ݜϩؚÝY®lŽu³|7f;µ\x1a†\x17””&23Åh\x12qÁç\x1f×–’'[\vl…\vv\x16\x17\x17Bó©À\fRL¡ž±$dSDÁT¹\x11ꘓ®£Z_Vk^<Ü×i’¨Ê\0\0"½bɈ\x19o­Ô‰aÆ\x17\fÅjï\x13–"Çàº=ŒFýß{p\x10|=º½Úš¿n~\x05o-ñ	Zþzý²s»\x1f!•¢°wÑ\x1f{!¼ù\x04«ÞùQ\x10|\x0e‚Úÿt¡ögÍntÂV6²Ç… 9–\™6J\x1c»u™¦‘\x01CÕ”\x198\x05ïÙO\f½\x0fN\x15|€Ÿ•\x1fÅ.›–4A÷ÝGêyi‚›e΄·ÓLز‰tÚ!p\x13…Ý»\x10~à`ôÛ ãûpz
ŸZ>\x14Øì“+Ô•>ï‚ØžP\x10ÒØ³i5²¤ñ‡Øñ×[\ª[åÄ_\x05†f\x13{ŽõAN§ÌÍUN#2$[îyE,üÂY²N\x19ax3Æ\x04´»\bՍïÂþ¸WJ\¶Ã^—ÔÞ½CI\x19©Ò8zþl\x04ƒW\x1aø\a\x17¯‹\x12‡; ¥\x1cY	©T.¶\0îæ€n\x12(ùWmVÌ,”Xû²åt•IØ0ý"kx\x1fÁƒí%k\b3[%Ö/¾\x16¡}:³ÿH\x164Á‘5½Àª·›¯A“5H²Fïž
Û[ÜÚ\x04@Ö\x0e•PJߟ	‹~»Š€uN¸Ò‹õu\x1a\x13(i¯¦Ëoß\vâÛ5Ã\v†Î3\x19?`\x03ò®;WQç6\f{ƒñ\x0f;>¿\x1d߆=ß	QãhõáeMqPP\x13ÆØPý0Êé#rÜJ¡Û­€\0þö÷ê­`w~;è\fÇ¡ÿªf¡,Ù#ûä€\x1c’#ò™|!_I+°¦-Ø\x14<kâ\f\x02¿È\x01–fæ\x15ÀÊ ´œ÷ÿRöÐíwUîvõ/\x0e-ì&.=Qdû7ƒ("n¥5-K=›ôJí\x7f\x15»² 4ëpŽ´•\x13\x1d/°¹aßE Z
-ÁŒ.™ms‚M©í¦Ø±¨H°ïòÔ\x14mËꂽ}Û\x03µ•´“\x19ÃUÛq¬Ízí*\x12l×s\x1f~\x16JNNP\x0f΃·ûD\x01yÛ™{Ç­ÍHíâáÓoÄ)Šºíq¯\x18û×8\x02ÿ\x18ÜÑà  ãÖ\b§\x19×Ôp¼™\x14ø7Ño?§^[\a°èLþ[5¼,âþ«ÎPœ
4-ØÊØ`Û³hÃ\x17Keuà[\x18¼£àñÀÔã	©î\x17Ѹ\x13¾F÷­õ}\v\°úœ¦,ÀçØ\x1a\x19c \x19Œ\f¦\x11ï\x13…b{'( \fðòV^ˆäBYµÚ%Ú1\x17(dܘ¬¸èL˜yd¬
-yÞý)Ú¸‡“Sø‚ï\x1f\x1dëË‚iÙÙe\x19}òŽì!D\0\x17HI¿yX•Ågž¶,	î‹ù¢(n&6Ávð*¯…°;7A1.OX`‰ô7PK\x01\x02\x14\x03\x14\0\0\0\b\0\x0f¶5HQ\x16&4\x05\0\0µ
\0\0\x0e\0	\0\0\0\0\0\0\0\0\0¤\0\0\0\0hw_direct_io.cUT\x05\0\a.u€EPK\x05\x06\0\0\0\0\x01\0\x01\0E\0\0\0`\x05\0\0\0\0

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Xenomai-help] Working example for direct memory mapped IO
  2006-12-13 21:48 [Xenomai-help] Working example for direct memory mapped IO Niklaus Giger
@ 2006-12-14 13:14 ` Jan Kiszka
  2006-12-15 20:25   ` Niklaus Giger
  0 siblings, 1 reply; 7+ messages in thread
From: Jan Kiszka @ 2006-12-14 13:14 UTC (permalink / raw)
  To: niklaus.giger; +Cc: xenomai

[-- Attachment #1: Type: text/plain, Size: 1313 bytes --]

Niklaus Giger wrote:
> Hi
> 
> To document basic Xenomai/Linux patterns I developed the attached small 
> example for our PPC405 board, which just rolls the 8 debug LEDs.
> 
> Are there any comments about it? 

I like the idea of having useful generic code patterns like this in the
examples repos. But I also have a few wishes regarding this particular one:

 * I would prefer that generic patterns are coded against POSIX or maybe
   Native, not against a special RTOS skin (not everyone know the
   VxWorks API by heart ;) ).

 * Try to make use of as less additional patterns beyond the core aspect
   as possible. E.g., running the lights in main would avoid quite some
   code for init/cleanup. This helps the reader to grab the essence of
   the demo. Still, the demo should remain functional!

 * Please format your code according to kernel style (could be any
   style, but we need a standard, so pick that one)

> 
> Shall I put it into the Wiki at http://www.xenomai.org/index.php/Examples or 
> does somebody want to commit it to the examples part of the subversion trunk?

I would happily merge a cleaned up version into the repos, e.g. under
the related skin.

Thanks,
Jan


PS: If you want to contribute VxWorks-specific code pattern, you are
welcome as well!


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [Xenomai-help] Working example for direct memory mapped IO
@ 2006-12-14 14:14 Fillod Stephane
  0 siblings, 0 replies; 7+ messages in thread
From: Fillod Stephane @ 2006-12-14 14:14 UTC (permalink / raw)
  To: niklaus.giger, xenomai

Niklaus Giger wrote:
>To document basic Xenomai/Linux patterns I developed the attached small

>example for our PPC405 board, which just rolls the 8 debug LEDs.
>
>Are there any comments about it? 

This is a worthy example. I strongly recommend you to declare your 
ledRegister variable as volatile. You'll find another example in
the Denx's FAQ[1], and accessible through shorter URL[2].
Personally, I always access hardware registers through in_[lbe]{8,16,32}
out_[lbe]{8,16,32} macros, so the code is portable across machines of 
different endianess, and thanks to the integrated memory barriers, 
I known exactly when the CPU will actually perform the I/O with respect 
to the other C instructions.

[1]
http://www.denx.de/wiki/bin/view/PPCEmbedded/DeviceDrivers#Section_Acces
singPeripheralsFromUserSpace
[2] http://tinyurl.com/6c7th

Best regards
-- 
Stephane


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Xenomai-help] Working example for direct memory mapped IO
  2006-12-14 13:14 ` Jan Kiszka
@ 2006-12-15 20:25   ` Niklaus Giger
  2006-12-17 20:26     ` Jan Kiszka
  0 siblings, 1 reply; 7+ messages in thread
From: Niklaus Giger @ 2006-12-15 20:25 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai

[-- Attachment #1: Type: text/plain, Size: 2075 bytes --]

Am Donnerstag, 14. Dezember 2006 14:14 schrieb Jan Kiszka:
> Niklaus Giger wrote:
> > Hi
> >
> > To document basic Xenomai/Linux patterns I developed the attached small
> > example for our PPC405 board, which just rolls the 8 debug LEDs.
> >
> > Are there any comments about it?
>
> I like the idea of having useful generic code patterns like this in the
> examples repos. But I also have a few wishes regarding this particular one:
>
>  * I would prefer that generic patterns are coded against POSIX or maybe
>    Native, not against a special RTOS skin (not everyone know the
>    VxWorks API by heart ;) ).
>
>  * Try to make use of as less additional patterns beyond the core aspect
>    as possible. E.g., running the lights in main would avoid quite some
>    code for init/cleanup. This helps the reader to grab the essence of
>    the demo. Still, the demo should remain functional!
I used the Linux "sleep" function and could eliminate all RT specifics and it 
still runs, albeit five times slower on my target.
>  * Please format your code according to kernel style (could be any
>    style, but we need a standard, so pick that one)
Tried, using Documentation/CodingStyle from the kernel. Hope I didn't miss to 
many thinks
> > Shall I put it into the Wiki at http://www.xenomai.org/index.php/Examples
> > or does somebody want to commit it to the examples part of the subversion
> > trunk?
>
> I would happily merge a cleaned up version into the repos, e.g. under
> the related skin.
I hope the attached version satisfy you now. Also added some suggestions made 
by Stephan Fillod.

> PS: If you want to contribute VxWorks-specific code pattern, you are
> welcome as well!
Will come to this a little bit later, as I making good progress to port our 
existing vxWorks application over to Xenomai. In any case, there is 
ksrc/skins/vxworks/demos/satch.c and the the simulator testsuite under
sim/skins/vxworks/testsuite/. But if you open for each skin a directory (what 
could be a good idea) one could add a README pointing to it.

Best regards

-- 
Niklaus Giger

[-- Attachment #2: hw_direct_io.c --]
[-- Type: text/x-csrc, Size: 3858 bytes --]

/*
 * This small examples shows how to access memory directly.
 *
 * Copyright (c) 2006 Niklaus Giger <niklaus.giger at member.fsf.org>
 *
 * It will only work on PPC405GPr based custom HW board of Nestal Maschinen AG
 *
 * It should, however, be easily adapted to similar HW
 * It will scroll across 8 LEDs (interval 1/2 of second), which are mapped
 * to some bit of the GPIO of the PPC405GPr processor.
 * To sleep it uses the Linux sleep a second, so do not expect a real time behaviour.
 * Compile it with at least -O to expand the inline assembler code.
 *
 * You may find another example at http://www.denx.de/wiki/bin/view/\
 *     PPCEmbedded/DeviceDrivers#Section_AccessingPeripheralsFromUserSpace
 *     Wherefrom we stole the out_32 and iounmap procedures.
 *
 * Fillod Stephane recommends:
 * "Personally, I always access hardware registers through in_[lbe]{8,16,32}
 * "out_[lbe]{8,16,32} macros, so the code is portable across machines of 
 * "different endianess, and thanks to the integrated memory barriers, 
 * "I known exactly when the CPU will actually perform the I/O with respect 
 * "to the other C instructions." 
 * These macros are defined e.g. asm-ppc/io.h, but only available to the kernel
 *
 */

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

void  *mapDirectIoRegister(unsigned long addr, size_t length);
int    iounmap(volatile void *start, size_t length);
void   sysLedSet(unsigned char value);

#define MAP_SIZE			4096UL
#define MAP_MASK 			(MAP_SIZE - 1)
#define HCU3_LED_REGISTER               0xEF600700

volatile unsigned long *ledRegister;

#ifdef __PPC__
extern inline void out_32(volatile unsigned long *addr, unsigned val)
{
        __asm__ __volatile__("stw%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
}
/* etc., cf asm/io.h */
#else
extern inline void out_32(volatile unsigned long *addr, unsigned val)
{ * which shows you how to use PPC assembler code to ensure correct IO ordering.

        *addr = val & 0xff;
}
#endif

void  *mapDirectIoRegister(unsigned long addr, size_t length)
{
	void *map_base, * virtAddr;
	off_t target = ((unsigned int) addr) & ~MAP_MASK;
	int fd;
	
	if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) {
		printf("/dev/mem could not be opened.\n");
		exit(1);
	}
	
	// Map one page
	map_base = mmap((void *)target, length, PROT_READ | PROT_WRITE, MAP_SHARED,
			fd, target);
	if(map_base == (void *) -1) {
		printf("Memory map failed for address 0x%lx\n", addr);
		return map_base;
	}
	
	virtAddr = (void *) ((unsigned long)map_base + ( (unsigned long)addr & MAP_MASK));
	printf("Memory map 0x%lx -> %p offset 0x%lx virtual %p\n", addr, map_base,
		addr & MAP_MASK, virtAddr);
	return virtAddr;
}

int iounmap(volatile void *start, size_t length)
{
	unsigned long ofs_addr;
	ofs_addr = (unsigned long)start & (getpagesize()-1);
	
	/* do some cleanup when you're done with it */
	return munmap((void*)start-ofs_addr, length+ofs_addr);
}

void   sysLedSet(unsigned char value)
{
	/* For obscure HW reasons, we have to negated it and shift the value 23 bits to the left  */
	*ledRegister = (( unsigned long ) ~value << 23) ;
        out_32(ledRegister, ( unsigned long ) ~value << 23);
}

int main (int argc, char *argv[])
{
	unsigned char j;
	printf("%s: %s %s\n", __FUNCTION__, __DATE__, __TIME__ ); 
	
	/* HW initialisation */
	ledRegister     = (unsigned long *)mapDirectIoRegister(HCU3_LED_REGISTER, MAP_SIZE);
	/* next we set the correct control mask in the GPIO_TCR */
	ledRegister[1]  = 0x7ffe0000; /* Three State Control */
	
	/* Now scroll our leds and pause a little bit between */
	for (j=0; j <= 8; j++) {
		sleep(1);
                printf("."); fflush(stdout);
		sysLedSet(1 << j);
	}
	iounmap((volatile void *)HCU3_LED_REGISTER, MAP_SIZE);
	printf("\n%s:done\n", __FUNCTION__); 
	return 0;
}

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Xenomai-help] Working example for direct memory mapped IO
  2006-12-15 20:25   ` Niklaus Giger
@ 2006-12-17 20:26     ` Jan Kiszka
  2006-12-19 20:04       ` Niklaus Giger
  0 siblings, 1 reply; 7+ messages in thread
From: Jan Kiszka @ 2006-12-17 20:26 UTC (permalink / raw)
  To: niklaus.giger; +Cc: xenomai

[-- Attachment #1: Type: text/plain, Size: 7726 bytes --]

Niklaus Giger wrote:
> Am Donnerstag, 14. Dezember 2006 14:14 schrieb Jan Kiszka:
>> Niklaus Giger wrote:
>>> Hi
>>>
>>> To document basic Xenomai/Linux patterns I developed the attached small
>>> example for our PPC405 board, which just rolls the 8 debug LEDs.
>>>
>>> Are there any comments about it?
>> I like the idea of having useful generic code patterns like this in the
>> examples repos. But I also have a few wishes regarding this particular one:
>>
>>  * I would prefer that generic patterns are coded against POSIX or maybe
>>    Native, not against a special RTOS skin (not everyone know the
>>    VxWorks API by heart ;) ).
>>
>>  * Try to make use of as less additional patterns beyond the core aspect
>>    as possible. E.g., running the lights in main would avoid quite some
>>    code for init/cleanup. This helps the reader to grab the essence of
>>    the demo. Still, the demo should remain functional!
> I used the Linux "sleep" function and could eliminate all RT specifics and it 
> still runs, albeit five times slower on my target.

You could replace sleep() with absolute clock_nanosleep(), kill the
printfs, do an appropriate pthread_setschedparam() on init, and you
would allow to gain determinism again by linking against the POSIX skin.

>>  * Please format your code according to kernel style (could be any
>>    style, but we need a standard, so pick that one)
> Tried, using Documentation/CodingStyle from the kernel. Hope I didn't miss to 
> many thinks

Just a few +80 char lines and some not-yet-tabs indentions.

>>> Shall I put it into the Wiki at http://www.xenomai.org/index.php/Examples
>>> or does somebody want to commit it to the examples part of the subversion
>>> trunk?
>> I would happily merge a cleaned up version into the repos, e.g. under
>> the related skin.
> I hope the attached version satisfy you now. Also added some suggestions made 
> by Stephan Fillod.

Almost :). Find comments below.

> 
>> PS: If you want to contribute VxWorks-specific code pattern, you are
>> welcome as well!
> Will come to this a little bit later, as I making good progress to port our 
> existing vxWorks application over to Xenomai. In any case, there is 
> ksrc/skins/vxworks/demos/satch.c and the the simulator testsuite under
> sim/skins/vxworks/testsuite/. But if you open for each skin a directory (what 
> could be a good idea) one could add a README pointing to it.

The idea is that those demos get migrated to examples over the time to
let us focus on one repository. If there are some sim-tests that can
serve as examples as well, they could be copied and adopted. Once
someone posts the first vxworks code for inclusion (e.g. a reformatted
and commented existing demo), I'm going to create a new dir and push it
in. Again: all examples should focus on one core idea (one for simple
periodic tasks, one for message queues, ...).

> 
> Best regards
> 
> 
> 
> ------------------------------------------------------------------------
> 
> /*
>  * This small examples shows how to access memory directly.
>  *
>  * Copyright (c) 2006 Niklaus Giger <niklaus.giger at member.fsf.org>
>  *
>  * It will only work on PPC405GPr based custom HW board of Nestal Maschinen AG
>  *
>  * It should, however, be easily adapted to similar HW
>  * It will scroll across 8 LEDs (interval 1/2 of second), which are mapped
>  * to some bit of the GPIO of the PPC405GPr processor.
>  * To sleep it uses the Linux sleep a second, so do not expect a real time behaviour.

See above.

>  * Compile it with at least -O to expand the inline assembler code.
>  *
>  * You may find another example at http://www.denx.de/wiki/bin/view/\
>  *     PPCEmbedded/DeviceDrivers#Section_AccessingPeripheralsFromUserSpace
>  *     Wherefrom we stole the out_32 and iounmap procedures.
>  *
>  * Fillod Stephane recommends:
>  * "Personally, I always access hardware registers through in_[lbe]{8,16,32}
>  * "out_[lbe]{8,16,32} macros, so the code is portable across machines of 
>  * "different endianess, and thanks to the integrated memory barriers, 
>  * "I known exactly when the CPU will actually perform the I/O with respect 
>  * "to the other C instructions." 
>  * These macros are defined e.g. asm-ppc/io.h, but only available to the kernel

This is a user-space demo, right? In what way can the comment above help
the reader then? Might rather cause confusions.

>  *
>  */
> 
> #include <stdio.h>
> #include <fcntl.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <sys/mman.h>
> #include <unistd.h>
> 
> void  *mapDirectIoRegister(unsigned long addr, size_t length);
> int    iounmap(volatile void *start, size_t length);
> void   sysLedSet(unsigned char value);

Not needed.

> 
> #define MAP_SIZE			4096UL
> #define MAP_MASK 			(MAP_SIZE - 1)
> #define HCU3_LED_REGISTER               0xEF600700
> 
> volatile unsigned long *ledRegister;
> 
> #ifdef __PPC__
> extern inline void out_32(volatile unsigned long *addr, unsigned val)
> {
>         __asm__ __volatile__("stw%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));

Maybe some explanation on this code would be helpful. It contains a
memory barrier, right? The user should find a notice that other arch
/may/ require barriers as well.

> }
> /* etc., cf asm/io.h */
> #else
> extern inline void out_32(volatile unsigned long *addr, unsigned val)
> { * which shows you how to use PPC assembler code to ensure correct IO ordering.

???

> 
>         *addr = val & 0xff;

????

> }
> #endif
> 
> void  *mapDirectIoRegister(unsigned long addr, size_t length)
> {
> 	void *map_base, * virtAddr;
> 	off_t target = ((unsigned int) addr) & ~MAP_MASK;
> 	int fd;
> 	
> 	if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) {
> 		printf("/dev/mem could not be opened.\n");
> 		exit(1);
> 	}
> 	
> 	// Map one page

/* */ please.

> 	map_base = mmap((void *)target, length, PROT_READ | PROT_WRITE, MAP_SHARED,
> 			fd, target);
> 	if(map_base == (void *) -1) {
> 		printf("Memory map failed for address 0x%lx\n", addr);
> 		return map_base;
> 	}
> 	
> 	virtAddr = (void *) ((unsigned long)map_base + ( (unsigned long)addr & MAP_MASK));
> 	printf("Memory map 0x%lx -> %p offset 0x%lx virtual %p\n", addr, map_base,
> 		addr & MAP_MASK, virtAddr);
> 	return virtAddr;
> }
> 
> int iounmap(volatile void *start, size_t length)
> {
> 	unsigned long ofs_addr;
> 	ofs_addr = (unsigned long)start & (getpagesize()-1);
> 	
> 	/* do some cleanup when you're done with it */
> 	return munmap((void*)start-ofs_addr, length+ofs_addr);
> }
> 
> void   sysLedSet(unsigned char value)
> {
> 	/* For obscure HW reasons, we have to negated it and shift the value 23 bits to the left  */

Means: on your specific board? Please make this explicit.

> 	*ledRegister = (( unsigned long ) ~value << 23) ;
>         out_32(ledRegister, ( unsigned long ) ~value << 23);
> }
> 
> int main (int argc, char *argv[])
> {
> 	unsigned char j;
> 	printf("%s: %s %s\n", __FUNCTION__, __DATE__, __TIME__ ); 
> 	
> 	/* HW initialisation */
> 	ledRegister     = (unsigned long *)mapDirectIoRegister(HCU3_LED_REGISTER, MAP_SIZE);
> 	/* next we set the correct control mask in the GPIO_TCR */
> 	ledRegister[1]  = 0x7ffe0000; /* Three State Control */
> 	
> 	/* Now scroll our leds and pause a little bit between */
> 	for (j=0; j <= 8; j++) {
> 		sleep(1);
>                 printf("."); fflush(stdout);
> 		sysLedSet(1 << j);
> 	}
> 	iounmap((volatile void *)HCU3_LED_REGISTER, MAP_SIZE);
> 	printf("\n%s:done\n", __FUNCTION__); 
> 	return 0;
> }

Thanks again,
Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Xenomai-help] Working example for direct memory mapped IO
  2006-12-17 20:26     ` Jan Kiszka
@ 2006-12-19 20:04       ` Niklaus Giger
  2006-12-19 20:35         ` Jan Kiszka
  0 siblings, 1 reply; 7+ messages in thread
From: Niklaus Giger @ 2006-12-19 20:04 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai

[-- Attachment #1: Type: text/plain, Size: 284 bytes --]

Am Sonntag, 17. Dezember 2006 21:26 schrieb Jan Kiszka:
> Niklaus Giger wrote:
> > Am Donnerstag, 14. Dezember 2006 14:14 schrieb Jan Kiszka:
<..>
Aller guten Ding sind drei. 

Here my third try. Hopefully I got everything right now. See attachement.

Best regards

-- 
Niklaus Giger

[-- Attachment #2: hw_direct_io.c --]
[-- Type: text/x-csrc, Size: 3696 bytes --]

/*
 * This small examples shows how to access memory directly.
 *
 * Copyright (c) 2006 Niklaus Giger <niklaus.giger at member.fsf.org>
 *
 * It will only work on PPC405GPr based custom HW board of Nestal Maschinen AG
 *
 * It should, however, be easily adapted to similar HW
 * It will scroll across 8 LEDs (interval 1/5 of second), which are mapped
 * to some bit of the GPIO of the PPC405GPr processor.
 * Compile it with at least -O to expand the inline assembler code.
 *
 * You may find another example at http://www.denx.de/wiki/bin/view/\
 *     PPCEmbedded/DeviceDrivers#Section_AccessingPeripheralsFromUserSpace
 *     Wherefrom we stole the out_32 and iounmap procedures.
 *
 *
 */

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <posix/time.h>
#include <posix/pthread.h>
#include <sys/mman.h>
#include <unistd.h>

#define MAP_SIZE			4096UL
#define MAP_MASK 			(MAP_SIZE - 1)

/* board specific, please put in correct values for your HW */
#define HCU3_LED_REGISTER		0xEF600700

volatile unsigned long *ledRegister;

#ifdef __PPC__
extern inline void out_32(volatile unsigned long *addr, unsigned val)
{
	/* Here we  use PPC assembler code to ensure that the IO is actually */
	/* performed before executing the next instruction. */
	/* This behaviour is also called a "memory barrier" */
	__asm__ __volatile__("stw%U0%X0 %1,%0; eieio" : "=m" (*addr)
				 : "r" (val));
}
#else
extern inline void out_32(volatile unsigned long *addr, unsigned val)
{ 
	/* Depending on your architectue you may need to add memory barriers */
	*addr = val;
}
#endif

void  *mapDirectIoRegister(unsigned long addr, size_t length)
{
	void *map_base, * virtAddr;
	off_t target = ((unsigned int) addr) & ~MAP_MASK;
	int fd;
	
	if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) {
		printf("/dev/mem could not be opened.\n");
		exit(1);
	}
	
	/* Map one page */
	map_base = mmap((void *)target, length, PROT_READ | PROT_WRITE, 
			MAP_SHARED, fd, target);
	if(map_base == (void *) -1) {
		printf("Memory map failed for address 0x%lx\n", addr);
		exit(1);
	}
	
	virtAddr = (void *) ((unsigned long)map_base + 
				( (unsigned long)addr & MAP_MASK));
	printf("Memory map 0x%lx -> %p offset 0x%lx virtual %p\n", 
		addr, map_base, addr & MAP_MASK, virtAddr);
	return virtAddr;
}

int iounmap(volatile void *start, size_t length)
{
	unsigned long ofs_addr;
	ofs_addr = (unsigned long)start & (getpagesize()-1);
	
	/* do some cleanup when you're done with it */
	return munmap((void*)start-ofs_addr, length+ofs_addr);
}

void   sysLedSet(unsigned char value)
{
	/* board specific, please put in correct values for your HW */
	/* Here: inverse and shift the value 23 bits to the left */
        out_32(ledRegister, ( unsigned long ) ~value << 23);
}

int main (int argc, char *argv[])
{
	unsigned char j;
	int res;
	struct sched_param param;
	printf("%s: %s %s\n", __FUNCTION__, __DATE__, __TIME__ );
	param.__sched_priority = 99;
	res = pthread_setschedparam(pthread_self(),  SCHED_FIFO, &param);

	/* HW initialisation */
	ledRegister     = (unsigned long *)mapDirectIoRegister(
				HCU3_LED_REGISTER, MAP_SIZE);
	/* next we set the correct control mask in the GPIO_TCR */
	/* board specific, please put in correct values for your HW */
	ledRegister[1]  = 0x7ffe0000; /* Three State Control */
	
	/* Now scroll our leds and pause a little bit between */
	for (j=0; j <= 8; j++) {
		struct timespec waittime, remaining;
		waittime.tv_sec = 0;
		waittime.tv_nsec = 200*1000*1000; /* 0.2 sec in nanosecs */
		nanosleep(&waittime, &remaining);
		sysLedSet(1 << j);
	}
	iounmap((volatile void *)HCU3_LED_REGISTER, MAP_SIZE);
	printf("\n%s:done\n", __FUNCTION__); 
	return 0;
}

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Xenomai-help] Working example for direct memory mapped IO
  2006-12-19 20:04       ` Niklaus Giger
@ 2006-12-19 20:35         ` Jan Kiszka
  0 siblings, 0 replies; 7+ messages in thread
From: Jan Kiszka @ 2006-12-19 20:35 UTC (permalink / raw)
  To: niklaus.giger; +Cc: xenomai

[-- Attachment #1: Type: text/plain, Size: 458 bytes --]

Niklaus Giger wrote:
> Am Sonntag, 17. Dezember 2006 21:26 schrieb Jan Kiszka:
>> Niklaus Giger wrote:
>>> Am Donnerstag, 14. Dezember 2006 14:14 schrieb Jan Kiszka:
> <..>
> Aller guten Ding sind drei. 

:)

> 
> Here my third try. Hopefully I got everything right now. See attachement.

Yeah, I committed it to examples/common. I guess some more generic
examples may pop up over the time, so a separate directory is useful.

Thanks!
Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2006-12-19 20:35 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-12-13 21:48 [Xenomai-help] Working example for direct memory mapped IO Niklaus Giger
2006-12-14 13:14 ` Jan Kiszka
2006-12-15 20:25   ` Niklaus Giger
2006-12-17 20:26     ` Jan Kiszka
2006-12-19 20:04       ` Niklaus Giger
2006-12-19 20:35         ` Jan Kiszka
  -- strict thread matches above, loose matches on Subject: below --
2006-12-14 14:14 Fillod Stephane

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.