* [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 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
* 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
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.