Trying to Write ToggleLED for MPC860 using GCC inline assembly

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
Hello, I have never used inline assemblly before so i don't know the
calls or the structure. i have read other posts but am still pretty
confused how to do it. I have come up with the following code to do a
toggleled

#define    LED_RED    0x01 /* Red Ethernet LED on the Freakin Board */
#define ETHLED  0xFA400000 /*BCSR0*/
void
main (void)
{
    int count;
    while (1)
        {
            count = 0;
            toggleled(LED_RED);
            while(count < 50*5000) /* (MHZ)*(Number of nanosecs) */
                {
                ++count;
                }
        }
}

void
toggleled(unsigned char ledMask)
{
// insert inline assembly
}

I am trying to write a small inline assembly program that just writes
a "01" value into a register of address FA400000. Can anyone help me
figure out the syntax/commands for this operation? I have no idea what
so ever.

Thank you much.

Fahd

Re: Trying to Write ToggleLED for MPC860 using GCC inline assembly

Quoted text here. Click to load it

First off, why are you wanting to do this with inline assembly?  Inline
assembly is useful for two things - writing highly optomised code for
absolutely critical code sections, and for the occasional bit of low-level
access that can't be done directly in C.  The first reason does not apply
here (unless you are very fluent in the cpu's assembly, and fully understand
Knuth's rules of optomisation).  The second reason applies for things like
disabling interrupts, entering sleep modes, and the like - and on many
toolchains these are covered by library functions.

The code you are really looking for is:

void main(void) {
    volatile int count;            // The "volatile" qualifier is critical !

    while (1) {
        *((unsigned char*) ETHLED) = LED_RED;
        for (count = 0; count < 50*5000; count++);

       *((unsigned char*) ETHLED) = 0x00;
        for (count = 0; count < 50*5000; count++);
    };
}

No inline assembly is necessary.


Quoted text here. Click to load it



Re: Trying to Write ToggleLED for MPC860 using GCC inline assembly
Quoted text here. Click to load it

To avoid later problems, I'd suggest accesses to hardware also with
volatile:
    *((volatile unsigned char *)ETHLED) = LED_RED;

This mainly for status-bits.

Note: Look into the sources of the ppc-boot or linux. They even map
structS directly over hardware.
=> no assembly

---
42Bastian

Re: Trying to Write ToggleLED for MPC860 using GCC inline assembly

Quoted text here. Click to load it
critical !
Quoted text here. Click to load it

You are entirely correct here - hardware access should in general be done
with volatiles.  I suppose that's particularly important on a chip like the
ppc, which could re-order reads or writes otherwise.

Quoted text here. Click to load it

I think mapping structs to the hardware is an elegant way to do it, although
people have different opinions on that (and especially on the use of
bit-fields in these structs).  Constructs like "*((volatile unsigned char
*)ETHLED) = LED_RED" are a mess, and should really be avoided - or at least,
buried deep within low-level routines or macro definitions.  But at least it
should get the O/P started - it's nice to get your LED blinking first !





Re: Trying to Write ToggleLED for MPC860 using GCC inline assembly
Quoted text here. Click to load it
Actually, the powerpc knows nothing about whether an access (load/store)
is to a volatile location or not. If you need to ensure that the
processor does not reorder loads and stores, you need to use
a processor specific barrier instruction. In the case of the
powerpc this is the eieio instruction.

IOW, volatile only prevents the compiler from reordering
accesses, not the processor.

To be even more picky, volatile is only required for
hardware registers if the value can change without being
changed by the hardware, or the act of reading or writing
the location has other side effects, such as clearing
other status or beginning the execution of a command.



--
Michael N. Moran           (h) 770 516 7918
5009 Old Field Ct.         (c) 678 521 5460
We've slightly trimmed the long signature. Click to see the full one.
Re: Trying to Write ToggleLED for MPC860 using GCC inline assembly

Quoted text here. Click to load it

Wrong.  The semantics of the volatile qualifier, as defined by the
ruling standard document, quite explicitly state that its effect must
be that *no* reordering happens in the behaviour of the actual running
code, compared to the order of operations expressed in the source code
(the execution order of the so-called "abstract machine" on which all
the defintion of C's semantics is based).  This definition doesn't
care at all whether the reordering is done by the compiler or the CPU
--- it's the net effect of both combined that is restricted.

I.e. if you write a compiler for this kind of CPU that may reorder
accesses behind the machine code's back, then the compiler *must*
apply counter-measures to avoid that for volatile-qualified accesses.
At the very least, it has to run flow analysis to be able to decide
that reordering, even if it happens, cannot have any unwanted effect.
If that analysis fails, the compiler will have to output guard
instructions to protect those volatile-critical sections.  If it
doesn't, it's not worth whatever you paid for it --- even it came for
free.

Quoted text here. Click to load it

I think you got that one wrong, too.  It's needed if the value can
change without being changed by the *software*.  Typically because
it *was* changed by the hardware itself.


--
Hans-Bernhard Broeker ( snipped-for-privacy@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.

Re: Trying to Write ToggleLED for MPC860 using GCC inline assembly
Quoted text here. Click to load it

Having done some driver development on the PPC I feel I should add
my 2 cents too.

I've never seen GCC adding any synchronisation instructions (eieio, sync,
isync) to the code. When dealing with hardware registers you have to
declare them volatile to prevent the compiler from reordering or optimizing
away your code. To prevent the CPU core from reordering hardware
accesses or making speculative accesses to them, you have to mark the
memory area "guarded". No synchronisation instructions are required then.

BTW. Hans I don't think GCC or PPC are broken. This is just the way
PPC works. And it works well that way. If one does not understand these
concepts he better sticks to Windows programming and lets the experts
do the Embedded stuff :-)

Cheers
- Rene



Re: Trying to Write ToggleLED for MPC860 using GCC inline assembly

Quoted text here. Click to load it

I think ther eis little discussion about bitfields. They  are  highly
unportable and should be avoided.


Wolfgang Denk

--
Software Engineering:  Embedded and Realtime Systems,  Embedded Linux
Phone: (+49)-8142-4596-87  Fax: (+49)-8142-4596-88   Web: www.denx.de
We've slightly trimmed the long signature. Click to see the full one.
Re: Trying to Write ToggleLED for MPC860 using GCC inline assembly

Quoted text here. Click to load it

Agreed, but within a given CPU and compiler they can add greatly to driver
debugging when the debugger can "crack" bit-fields well.

--
- Mark ->
--

Re: Trying to Write ToggleLED for MPC860 using GCC inline assembly
Quoted text here. Click to load it

You need to tell us which compiler
you are using, since inline assembly
syntax varies among compilers.

Otherwise, I wonder why you would do this
in assembly?


--
Michael N. Moran           (h) 770 516 7918
5009 Old Field Ct.         (c) 678 521 5460
We've slightly trimmed the long signature. Click to see the full one.

Site Timeline