My code (RAM-Test) is optimized away.

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

Hi all,

I have this neat little SRAM Test:

  register unsigned char *p_val,*p_sav,i,sav;
  register unsigned char val;
  register signed  char h; 
 
  /* test all locations with 0x55, 0xAA and complement of address value */
      p_val=((unsigned char *)(SRAM_START_ADR));
      sav = *p_val;
      *p_val = 0x55;
      i = *p_val;
      if (i!=0x55) { return TEST_FAIL; }
      *p_val = 0xAA;
      i = *p_val;
      if (i!=0xAA) { return TEST_FAIL; } 
      val = ~((unsigned char)p_val);
      *p_val = val;
      i = *p_val;
      if (i != val) { return TEST_FAIL; } 
      *p_val=sav;
}

(I know, the for loop is missing in the example. :wink: )

When compiling with -O0, everything is ok, but when compiling with i.e. -Os, the asm output is

  ce:	80 e0       	ldi	r24, 0x00	; 0
  d0:	90 e0       	ldi	r25, 0x00	; 0

I know it is because I save the Ram value, change it to 55 and AA and read it, compare it and than write back the saved RamValue. For sure, the compiler will think: "Who the hell wrote this. I will delete all the shit and do nothing!!"
But now, how to tell the compiler that he has to do the write 55 and AA and read and compare stuff to make me happy.
First idea is to put the RAM test into a seperate C-File and give it the compile flag -O0, second is to write the ram-test in Assember or take the -O0 compiled Assemblercode and put it as inline assembler into my c-file?!

Any other suggestions?

Baldrian

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

Make those pointers to 'volatile' locations.

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

volatile will work as Cliff mentions. Presumably you want some output from this RAM test. If you output the results of the RAM test (to a PORT, UART, or even save the results to a IO register on the AVR), then the optimizer will keep the RAM test code since the test code is essential for your program's output.

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

Ok. That works. And is way more easier than my suggestions. Thanks clawson! :oops:
Now, the only problem left, that when reaching the end of RAM, the test fails, because the variables i and val are changed in stack during test, which leads to a test failure when testing that locations. :x

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

I know you used the register qualifier, but you need special syntax to definitively bind a variable to a register. See the avr-libc documentation.

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

kmr wrote:
I know you used the register qualifier, but you need special syntax to definitively bind a variable to a register. See the avr-libc documentation.

OK. Checked the avr-libc:

 volatile register unsigned char *p_val,*p_sav,i asm("r3")
,sav asm("r4");
  volatile register unsigned char val asm("r5");

But what if earlier the compiler allready uses the registers r3,r4 an r5. Will I become trouble? Or how do I have to interpret this sentence in avr-libc: "But the compiler is not able to check wether this register usage conflicts with any predefined register. "

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

The compiler will use up to all available registers. By specifically binding a variable to a register, the compiler will not use that register in that compilation unit. Be careful if you link to another .o file, though. Each file being linked needs to know those registers have been bound to those variables.

Last Edited: Wed. Oct 1, 2008 - 11:40 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would be interested to know whether anyone has ever had a SRAM failure.

I can think of many failure modes for the peripheral special functions ( which generally involve SMOKE ).

In the early days of dynamic RAM, it was not at all uncommon to have sticky bits. Hence these test routines. I doubt that modern chips will fail in this way. Now a comprehensive diagnostic test of every special function would be a lot more interesting ( and difficult ).

David.

p.s. I am bald too !!

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

This is one thing where I wouldn't try to do battle with the C compiler but would put this into a .S file where you had complete control over the asm you write and how the registers are used. Clearly you need everything held in registers if RAM is being fiddled with and yet you then face the dilemma of seemingly pointless code being optimised away if all it appears to do is shuffle some data around.

As for the point in RAM tests - clearly the safety boards in various countries that mandate that certain equipment should be self testing in this kind of way are populated by old bald gits (me too) who remember the days when the cokroaches really did wander about on the magnetic core.

Cliff

Last Edited: Wed. Oct 1, 2008 - 11:46 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
Now a comprehensive diagnosis of every special function would be a lot more interesting ( and difficult).
Atmel surely must run such a comprehensive diagnostic before they release each manufactured AVR to distribution.

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

clawson wrote:
This is one thing where I wouldn't try to do battle with the C compiler but would put this into a .S file where you had complete control over the asm you write and how the registers are used. Clearly you need everything held in registers if RAM is being fiddled with and yet you then face the dilemma of seemingly pointless code being optimised away if all it appears to do is shuffle some data around.
My first thought was that the RAM test program should be in assembly language. For C, it's easy enough to keep the test from being optimized away as you know.
// place test code goes here, jump to appropriate exit
// ...

passed:
  PORTA = 0xAA;
  goto done;

failed:
  PORTA = 0x55;
 
done:
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kmr wrote:
david.prentice wrote:
Now a comprehensive diagnosis of every special function would be a lot more interesting ( and difficult).
Atmel surely must run such a comprehensive diagnostic before they release each manufactured AVR to distribution.

I do not know how seriously each chip is tested. I have always assumed that a manufacturer comprehensively tests a statistical sample. Any problem would reject the whole batch.

Of course it could be that each chip is comprehensively tested. But you still have the possibility of an age-related failure which is why self-diagnostic tests may be performed by the end user.

David.

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

Indeed indeed. But as I stated before in another thread. I have to do this test to match class b compliance. Wether a RAM fault can occur or not, doesn't matter. :roll:

Thanks for the tip with the linking to another .o file. I will take care of it. But I think, I will learn some more asm and write the whole test as inline assember code.

Regards,
Baldrian

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

david.prentice wrote:
I do not know how seriously each chip is tested. I have always assumed that a manufacturer comprehensively tests a statistical sample. Any problem would reject the whole batch.
That sounds reasonable for IC's with very high yield rates. For larger dies, like CPUs, I don't think yield rate is high enough for that to be tenable. Perhaps with optical scanning, though, they can reject nearly all flawed dies so that dies that pass the scanning can be assumed to be electrically correct.
Quote:
Of course it could be that each chip is comprehensively tested. But you still have the possibility of an age-related failure which is why self-diagnostic tests may be performed by the end user.
I agree, a comprehensive diagnostic of an AVR would be a significant challenge for an end-user with little overall gain.

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

Baldrian wrote:
I have to do this test to match class b compliance
Have you seen these this Atmel application note on class b compliance with AVRs?

http://www.atmel.com/dyn/resourc...
http://www.atmel.com/dyn/resourc...

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

Baldrian wrote:

Thanks for the tip with the linking to another .o file. I will take care of it. But I think, I will learn some more asm and write the whole test as inline assember code.

Write your file in regular English i.e. write an S file that links with your project.

"inline" assembler will drive you up the wall.

Good Luck.

David.

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

david.prentice wrote:
I would be interested to know whether anyone has ever had a SRAM failure.

I can think of many failure modes for the peripheral special functions ( which generally involve SMOKE ).

Maybe not applicable to hobbyists, but we had this issue at work just last week. There was a soldering issue on one of the parts on our board, which caused a voltage level to be too low. The card would mostly work, but crash randomly. A full ram test was the only way to detect the failure (without a multimeter and knowing where to look, anyway).

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

kmr wrote:
Baldrian wrote:
I have to do this test to match class b compliance
Have you seen these this Atmel application note on class b compliance with AVRs?

http://www.atmel.com/dyn/resourc...
http://www.atmel.com/dyn/resourc...

Yes. I have the RAM Test from that documents. :D

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

Linenoise wrote:
david.prentice wrote:
I would be interested to know whether anyone has ever had a SRAM failure.

I can think of many failure modes for the peripheral special functions ( which generally involve SMOKE ).

Maybe not applicable to hobbyists, but we had this issue at work just last week. There was a soldering issue on one of the parts on our board, which caused a voltage level to be too low. The card would mostly work, but crash randomly. A full ram test was the only way to detect the failure (without a multimeter and knowing where to look, anyway).

Unless of course you were using external RAM, I do not see how a soldering joint should affect the internal SRAM functionality. It would most likely show up as a PORT or sfr inconsistency.

So this has nothing to do with the AVR, but a lot to do with its external connections.

David.

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

When I write a RAM test I use the strategy "write the whole RAM, then read the whole RAM". I guess it came from the Dark Ages when bits could inadvertently affect one another. Or fade away. Or...

Following this strategy would have also solved the OP's problem without the confusion of "volatile" mixed in. In fact, that's how my current RAM test works.

The other advantage is that you could look for "weak" bits (bits that can be set to 0 or 1 but won't stay there). Write the RAM, go away for a second or two, then read it.

Yes, I've needed to worry about this, but not in commercially produced chips. Well, they were commercially produced, but I was in the company producing them and my test was testing them for the first time!

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

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

This article by Jack Ganssle is a worth a read too ;)

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

jayjay1974 wrote:
This article by Jack Ganssle is a worth a read too ;)

Certainly--but then he gets my hackles up:

Quote:
Don’t even think about writing this sort of code in C. Any high level language will inject too many instructions between those that move the bits up and down. Even in assembly the processor will have to do fetch cycles from wherever the code happens to be, which will slow down the pounding and make it a bit less effective.

Maybe with >>his<< brand of compiler. ;)

To some extent I will agree when chaining a pattern as is described earlier in the article.

We have a real luxury in doing this type of thing on an AVR since the flash instruction fetch isn't on the SRAM bus, and we have lots of registers to work with during the test.

All of my apps use only internal RAM anyway. Though not addressed in the article, if we are going to question the on-board AVR SRAM which is at a very sedate (for nowadays) speed and very short distance (thus avoiding the problems of bus driving and capacitance that Mr. G described) then why would we not question every gate and I/O register and the peripheral subsystems themselves (timers e.g. are critical to "correct" operation of my apps) and ...?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Would it even be possible to test every aspect of an AVR with code only?

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

jayjay1974 wrote:
Would it even be possible to test every aspect of an AVR with code only?
This has been argued more than once. The answer is not really. There's just too much stuff to cover.

Real Processor Manufacturers (tm) such as Atmel have extensive test procedures to prove that a processor is totally sane, and even then they have the ability to use the internal debug chains to feed tests in and out of particular circuits and to partition the the logic blocks.

You at some point need to assume that the processor is sane and to get on with life. Usually the requirement for "proving" the processor is sane comes from FAA, FDA, or other alphabet-soup organizations who remember the Bad Old Days when a single logic chip failure caused insanity in the processor. Your answer is to cover the self-test as best you can (RAM tests aren't hard; neither are CRC checks of Flash) and to move on.

The better approach is to design your code to watch for insane or dangerous behavior and to safely lock the processor in a "safe" mode if it occurs. Watchdog interrupts serve this purpose, but other interrupts to check sanity can do it as well.

Finally, if you are doing something really dangerous with your processor (robots with friggin' lasers comes to mind :D), nothing beats having an external circuit that watches sanity and can yank the processor back in line.

Do a search in this forum on "self-test" and I'm sure you'll find several threads of interest.

Stu (Back home from Austria)

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!