problem Inline Assembler return value

Go To Last Post
17 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,
I try to write an cpu test via inline assembler but i have a problem with the return value. The return value is checked in main (failure).

How can i be sure that the return value (temp_failure) is right independent of the compiler version?
Is this the right way to fix a register to a variable?

Example:


UINT8 CPU_Test(void) {

volatile register UINT8 temp_failure asm("r16");

/* inline assembler */
asm volatile (

/* test carry flag C */					
 "CLC           \n\t" /* clear C 	
 "BRCC 1f       \n\t" /* test pos. case */
 "RJMP 100f     \n\t" /* jump to error */

 "1:            \n\t" /*label*/
 "BRCS 100f     \n\t"  /* test neg. case */
 "SEC		\n\t"  /* set carry flag */
 "BRCS 2f    	\n\t"  /* test pos. case */
 "RJMP 100f 	\n\t" 

 "2:	        \n\t"  /*Label:*/
 "BRCC 100f  	\n\t"  /* test neg.case */
 "ldi r16, 0x00 \n\t"/ /* clear error in temp_failure */ 
 "RJMP 200      \n\t"/ 

/* error detected */
 "100:	        \n\t" /*label*/ 
 "ldi r16, 0x60 \n\t" /* set error in temp_failure */ 

 "200:	        \n\t" /*label*/
      :: ); /* end of inline assembler */
 
 return temp_failure;
}/* end */



int main(void)
{ 
  UINT8 failure = 0;
  
  failure = CPU_Test();
 
  if (failure != 0){
  //do anything...
  }
}

Thank you Andi

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
How can i be sure that the return value (temp_failure) is right independent of the compiler version?

Just an idea but don't return it. Instead write it to a Asm/C shared global.

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
How can i be sure that the return value (temp_failure) is right independent of the compiler version?
You use the gcc standard registers-
http://www.nongnu.org/avr-libc/u...
(r24 is used for a single byte)

No comment on testing the carry bit. You can do what you want.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you curtvm,

thats what i have looking for is see also in the simulator that the compiler use r24. Is this valid for all compiler version or is it different?

What you mean no comment about carry flag test. Its a request from the TÜV that each controller must test his own cpu :( like this (zero flag and so on) or u mean the way i do it its wrong?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Is this valid for all compiler version or is it different?
Gcc, yes (I don't know about versions before 3.4.6). I don't think they would change it too quickly, as it would break a lot of stuff. They have it thought out pretty well, also.
Quote:
What you mean no comment about carry flag test
I shouldn't start something that turns into a long thread, but it seems the ones who request these type of things don't know much about microcontrollers and want to just feel good that 'some cpu test' is done. I'm certainly no expert on the subject, but if you are going to test a few bits of the status register, that leaves a LOT of other things that can be just as bad. Unless you tackle them all, it seems to me its useless to even start. IF things fail like the carry bit, I would think they would fail sometime while its running, so unless you also frequently test these things, you won't catch the problem either. Then there is a failing program counter- testing that is a real bugger. And on and on.

But I suspect like most, you have to jump through hoops to make someone happy, so jump away.

By the way, the carry flag is used when loading data and clearing bss in the startup code. You may want to do your 'cpu testing' before stuff like that.

No comment, starting.... now.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes thats right :) we had the same discussion with the TÜV/FDA but the responsible person require this anyway
when we use only one controller in the system.
So we must go this way to get the accreditation for our maschine :(. Its stupid but its addicted of the person from the TÜV/FDA.

Thank you for all

ANDI

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The problem here of course is that in checking these flags you are using these flags. That means that if the flags are incorrect, the answer you receive will be wrong. Therefore if the answer you receive is that the flags are correct, then you know that you have a problem :wink:

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Andreas,

Can you tell us what device/application you are building that requires TÜV/FDA approval? This sounds like a medical device of some sort...

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes EW thats right, its a medical device.
The TÜV/FDA require some special test like
RAM and ROM Test while the program is running and also a simple CPU and register test.

Regards,
Andi

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

its a medical device

I suppose You have read this passage that is on one of the last pages of every AVR data sheet I have looked at:
Quote:
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You make a joke ;-) i have never heard or read this.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No joke. Specimen below is from ATtiny24/44/84 data sheet. I suspect that it is in most every AVR data sheet.

.

Attachment(s): 

Image icon .

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry for going "off topic" by returning to the original question. :-)

I think the proper way of doing so is to assign the desired return value to a temporary variable and return that variable in C. You can do this like this:

UINT8 CPU_Test(void)
{
    UINT8 temp_failure;

    asm volatile(
        // do some very complicated stuff
        // ...
        "ldi %[ret], 0x60 \n\t" // set return value
        : [ret] "=r" (temp_failure)
        :
    );
    return temp_failure;
}

(completely untested code. Use it at your own peril)

This is IMHO more readable and produces better code than fixing the return value to a specific register.

More information about inline assembly is available here:
http://www.nongnu.org/avr-libc/user-manual/inline_asm.html
and here:
http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Extended-Asm.html#Extended-Asm

Cheers
Thomas

[edit: wording; forgot to return temp_failure in the code]

pycrc -- a free CRC calculator and C source code generator

Last Edited: Thu. Aug 28, 2008 - 02:20 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If your device is intended to be used for keeping people alive, you're prohibited from making use of Atmel's intellectual property in such a way. It might be possible to negotiate a side-deal with them if the circumstances warrant it. Then again, it might not.

If your medical device is intended for purely diagnostic purposes, you might still be able to proceed.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl:
We use the atmega1281. I dont find
any note in the datasheet about this.

tpircher:
Thank you for this example but i think the best way is to write the complete
test in assembler and link it to the project. I hate the syntax of inline assembler.

lfmorrison:
Its not a device to keeping people alive.
In most cases we use two controllers.
Both controllers monitoring the same critical signals and communicate via spi, twi... interface. If the signals from controller 1 and 2 differ the system goes into a defined error mode.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

We use the atmega1281. I dont find
any note in the datasheet about this.

You're right, that page doesn't seem to be present in the full version of the ATmega640/1280/2560/1281/2561 datasheet. It is present in the summary sheet, on the very last page.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok I have found it :), thank you.