Trying to Write ToggleLED for MPC860 using GCC inline assembly

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

Reply to
Fahd
Loading thread data ...

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.

Reply to
David Brown

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
 Click to see the full signature
Reply to
Michael N. Moran

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
Reply to
42Bastian Schick

critical !

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.

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 !
Reply to
David Brown

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
 Click to see the full signature
Reply to
Michael N. Moran

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.

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 (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
Reply to
Hans-Bernhard Broeker

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
 Click to see the full signature
Reply to
Wolfgang Denk

Wolfgang Denk wrote in news: snipped-for-privacy@denx.muc.de:

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

--
- Mark ->
--
Reply to
Mark A. Odell

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

Reply to
Rene Straub

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.