* [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.cVmoâ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ö\x04R=à\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Ó<gUeuË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^[ÿ ST§\r©¦g¨¥Y«½ç"Î\x16 \x13m\x12.^[³³©4\x16&ÛB©O¶ç\x16ãô\v¹'ÝÏ©ØÝY®lu³|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êyieηÓLزtÚ!p\x13
Ý»\x10~à`ôÛ ãûpz
Z>\x14Øì+Ô>ïØP\x10ÒØ³i5²¤ñØñ×[\ª[åÄ_\x05f\x13{õAN§ÌÍUN#2$[îyE,üÂY²N\x19ax3Æ\x04´»\bÕïÂþ¸WJ\¶Ã^ÔÞ½CI\x19©Ò8zþl\x04W\x1aø\a\x17¯\x12; ¥\x1cY ©T.¶\0îæn\x12(ùWmVÌ,Xû²åtIØ0ý"kx\x1fÁí%k\b3[%Ö/¾\x16¡}:³ÿH\x164Á5½Àª·¯A5H²Fï
Û[ÜÚ\x04@Ö\x0ePJß ~»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¿È\x01fæ\x15ÀÊ ´÷ÿRöÐíwUîvõ/\x0e-ì&.=Qdû7("n¥5-K=ôJí\x7f\x15»² 4ëp´\x13\x1d/°¹aßE Z
-Á.msM©í¦Ø±¨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ܬ¸èLyd¬
-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.uEPK\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, ¶m);
/* 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.