All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Kiszka <jan.kiszka@domain.hid>
To: niklaus.giger@domain.hid
Cc: xenomai@xenomai.org
Subject: Re: [Xenomai-help] Working example for direct memory mapped IO
Date: Sun, 17 Dec 2006 21:26:58 +0100	[thread overview]
Message-ID: <4585A812.2060605@domain.hid> (raw)
In-Reply-To: <200612152125.09368.niklaus.giger@domain.hid>

[-- 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 --]

  reply	other threads:[~2006-12-17 20:26 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4585A812.2060605@domain.hid \
    --to=jan.kiszka@domain.hid \
    --cc=niklaus.giger@domain.hid \
    --cc=xenomai@xenomai.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.