Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
dolphin@gmx.com
PostPosted: Jun 16, 2011 - 10:49 PM
Wannabe


Joined: Oct 09, 2010
Posts: 74


I AM TRYING TO FILL the FIRST 10 BYTES OF RAM location with some default value(0xaa). But while debugging , in the memory view it is loading like AA 00 AA 00 AA 00..


#include <avr/io.h>

int main()
{
volatile unsigned int *address = (volatile unsigned int*)(0x0060);
unsigned int count = 0;
while(count<=10)
{
*(volatile unsigned int*)(address) = 0xaa;
address++;
count++;

}
}
It is supposed to be AA AA AA AA ..
I use stk500. Any help to understand why?

Is there any other way to use section directives?
 
 View user's profile Send private message  
Reply with quote Back to top
sparrow2
PostPosted: Jun 16, 2011 - 10:55 PM
Raving lunatic


Joined: Oct 07, 2002
Posts: 2011
Location: Denmark

int is 16 bit not 8 bit
 
 View user's profile Send private message  
Reply with quote Back to top
dolphin@gmx.com
PostPosted: Jun 16, 2011 - 11:16 PM
Wannabe


Joined: Oct 09, 2010
Posts: 74


thanks. I want to fill all my sram locations with aa.
The sram address is 16 bit.How to do that?
sparrow2 wrote:
int is 16 bit not 8 bit
 
 View user's profile Send private message  
Reply with quote Back to top
sparrow2
PostPosted: Jun 16, 2011 - 11:27 PM
Raving lunatic


Joined: Oct 07, 2002
Posts: 2011
Location: Denmark

make address a char pointer ! (do some C study)
 
 View user's profile Send private message  
Reply with quote Back to top
indianajones11
PostPosted: Jun 17, 2011 - 02:11 AM
Raving lunatic


Joined: Nov 28, 2004
Posts: 3551
Location: San Diego, Ca

I'd have used memset() for this. It's a std. C library function, google for it or RTM for compiler.

_________________
1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1
 
 View user's profile Send private message  
Reply with quote Back to top
dolphin@gmx.com
PostPosted: Jun 17, 2011 - 07:28 PM
Wannabe


Joined: Oct 09, 2010
Posts: 74


could you please post me some example or link?
indianajones11 wrote:
I'd have used memset() for this. It's a std. C library function, google for it or RTM for compiler.
 
 View user's profile Send private message  
Reply with quote Back to top
david.prentice
PostPosted: Jun 17, 2011 - 08:00 PM
10k+ Postman


Joined: Feb 12, 2005
Posts: 16254
Location: Wormshill, England

Google is your friend.

If you quote any passage that you find that you do not understand, we can help.

David.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
dolphin@gmx.com
PostPosted: Jun 17, 2011 - 09:16 PM
Wannabe


Joined: Oct 09, 2010
Posts: 74


sparrow2 wrote:
make address a char pointer ! (do some C study)


Here is my implementation for filling the sram from(0x0060 to 0x025f)
Code:

int main()
{
    volatile unsigned char *address = (volatile unsigned char*)0x0060;
volatile unsigned short count = 0;   

   while (count < 512)
   {

      (*(volatile unsigned char*)address)  = 0xa;
      count++;
      address++;
      

   }
   
}

How to do we make sure it is exiting properly?
I tried to use memory view , but i see some values in the bottom of the sram .
Last 6 bytes looks like.
0c 0a 02 5f 00 2b
Is this correct? Any pointers to confirm that ther is no stack overflow?
 
 View user's profile Send private message  
Reply with quote Back to top
sparrow2
PostPosted: Jun 17, 2011 - 09:42 PM
Raving lunatic


Joined: Oct 07, 2002
Posts: 2011
Location: Denmark

Before you get to main your program run some code (normaly called cstartup) where the basic things like stack setup, clear memory etc. get done. If you want some special RAM pattern you should make the changes to that file.
 
 View user's profile Send private message  
Reply with quote Back to top
indianajones11
PostPosted: Jun 18, 2011 - 03:17 AM
Raving lunatic


Joined: Nov 28, 2004
Posts: 3551
Location: San Diego, Ca

In your OP you want to fill 1st 10 places and in last code you fill entire ram with the pattern. What do you want to do ? Why are you worrying about those 6 bytes ? I thought you were setting up to monitor the stack, but then... Question

You need a while(1); at the end of the code and why you're asking about overflow, NOTHING happens after you fill ram. These are all things you really should know. Slow down and STUDY a good ( embedded ) C book.

_________________
1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1
 
 View user's profile Send private message  
Reply with quote Back to top
dolphin@gmx.com
PostPosted: Jun 18, 2011 - 03:47 AM
Wannabe


Joined: Oct 09, 2010
Posts: 74


I want to fill the entire RAM with 0xa. First I tried to fill the 10 bytes. Then I filled the entire ram. Next I am going to implement some code, to monitor the stack. This is what I am trying to do.

I worry about those 6 bytes, because When I am filling up my entire RAM WITH 0xa, how those 6 bytes are different.

indianajones11 wrote:
In your OP you want to fill 1st 10 places and in last code you fill entire ram with the pattern. What do you want to do ? Why are you worrying about those 6 bytes ? I thought you were setting up to monitor the stack, but then... Question

You need a while(1); at the end of the code and why you're asking about overflow, NOTHING happens after you fill ram. These are all things you really should know. Slow down and STUDY a good ( embedded ) C book.
 
 View user's profile Send private message  
Reply with quote Back to top
jaksel
PostPosted: Jun 18, 2011 - 02:18 PM
Hangaround


Joined: Aug 21, 2005
Posts: 305
Location: Stockholm, Sweden

dolphin@gmx.com wrote:
I worry about those 6 bytes, because When I am filling up my entire RAM WITH 0xa, how those 6 bytes are different.
Maybe because the local variables in your main() function are allocated on the stack...?

And with that in mind, maybe you realize it's not such a good idea to corrupt the entire stack contents in your main() function? As already mentioned, you should do that in your C startup code.

_________________
/Jakob Selbing
 
 View user's profile Send private message  
Reply with quote Back to top
dolphin@gmx.com
PostPosted: Jun 18, 2011 - 06:52 PM
Wannabe


Joined: Oct 09, 2010
Posts: 74


Thanks. you are correct. I am working on that.
jaksel wrote:
dolphin@gmx.com wrote:
I worry about those 6 bytes, because When I am filling up my entire RAM WITH 0xa, how those 6 bytes are different.
Maybe because the local variables in your main() function are allocated on the stack...?

And with that in mind, maybe you realize it's not such a good idea to corrupt the entire stack contents in your main() function? As already mentioned, you should do that in your C startup code.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jun 18, 2011 - 06:56 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62209
Location: (using avr-gcc in) Finchingfield, Essex, England

I've posted a flood SRAM routine before now that I placed in .init3 (so it's before the data and bss loops in .init4). The compiler will generally put the for() index in a register not on the stack but you obviously MUST check this or force register binding for it.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
dolphin@gmx.com
PostPosted: Jun 18, 2011 - 08:22 PM
Wannabe


Joined: Oct 09, 2010
Posts: 74


clawson wrote:
I've posted a flood SRAM routine before now that I placed in .init3 (so it's before the data and bss loops in .init4). The compiler will generally put the for() index in a register not on the stack but you obviously MUST check this or force register binding for it.
Code:
   .section .init1,"ax",@progbits

   LDI R27, 0X02 ;upper ram address high byte
   ldI R26,0x5f ;upper ram address low byte
   ldi R25,0X00 ;lower  ram address high  byte
   ldi R24,0X60 ;lower ram address low byte
   LDI R16,0xAA ; VALUE TO BE COPIED

loop:
   st x,r16   ; STORE 0XAA VALUE IN RAM LOCATION
   sbiw r26,1 ;DECREMENT THE RAM ADDRESS
   cp r26,r24  ;COMPARE THE LOW BYTES OF THE RAM  END AND STARTING  ADRDRESS
   cpc r27,r25 ;COMPARE THE HIGH BYTES OF THE RAM END AND STARTING  ADRDRESS THROUGH THE CARRY
   brne loop ;   loop continues untill it becomes equal


This is my assembly routine to fill the ram  with 0xaa before the main starts.
My main() is just empty. I viewed the memory , it seems like my first location is 0xff(0x0060), last 2 locations of 00 35. Why is that?  Any help?
 
 View user's profile Send private message  
Reply with quote Back to top
wek
PostPosted: Jun 18, 2011 - 08:55 PM
Raving lunatic


Joined: Dec 16, 2005
Posts: 3086
Location: Bratislava, Slovakia

dolphin@gmx.com wrote:
last 2 locations of 00 35. Why is that?

Because there is a call to main(), so that's the return address pushed to stack.

dolphin@gmx.com wrote:
first location is 0xff(0x0060),
Because your loop exits before you write to this address. Use BRSH (BRCC) instead of BRNE.

JW
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
dolphin@gmx.com
PostPosted: Jun 20, 2011 - 05:19 PM
Wannabe


Joined: Oct 09, 2010
Posts: 74


Thanks to you.
wek wrote:
dolphin@gmx.com wrote:
last 2 locations of 00 35. Why is that?

Because there is a call to main(), so that's the return address pushed to stack.

dolphin@gmx.com wrote:
first location is 0xff(0x0060),
Because your loop exits before you write to this address. Use BRSH (BRCC) instead of BRNE.

JW
 
 View user's profile Send private message  
Reply with quote Back to top
indianajones11
PostPosted: Jun 28, 2011 - 11:17 AM
Raving lunatic


Joined: Nov 28, 2004
Posts: 3551
Location: San Diego, Ca

You can shorten it a bit by doing this in your fill loop :

Code:
*address++ = 0xaa;
++count;

_________________
1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1
 
 View user's profile Send private message  
Reply with quote Back to top
beautiful_day
PostPosted: Apr 26, 2012 - 08:30 AM
Newbie


Joined: Oct 21, 2011
Posts: 19


Hello everybody,

I am trying to do the same thing (filling RAM with a pattern 0xAA). In fact, am taking classes and this is a project...I am not asking for the solution so please don't get offended (don't really know whether this is THE solution). I don't know Assembly language & while looking for help I landed here. So my questions are related to this code:

Code:
.section .init1,"ax",@progbits

   LDI R27, 0X02 ;upper ram address high byte
   ldI R26,0x5f ;upper ram address low byte
   ldi R25,0X00 ;lower  ram address high  byte
   ldi R24,0X60 ;lower ram address low byte
   LDI R16,0xAA ; VALUE TO BE COPIED

loop:
   st x,r16   ; STORE 0XAA VALUE IN RAM LOCATION
   sbiw r26,1 ;DECREMENT THE RAM ADDRESS
   cp r26,r24  ;COMPARE THE LOW BYTES OF THE RAM  END AND STARTING  ADRDRESS
   cpc r27,r25 ;COMPARE THE HIGH BYTES OF THE RAM END AND STARTING  ADRDRESS THROUGH THE CARRY
   brne loop ;   loop continues untill it becomes equal


1. I understand that in assembly language we need to write data to registers and then work with those registers. But why these registers only (R27, R26, R24, R25, R16)? When I see the datasheet for Atmega2560, R26-R31 registers are X,Y,Z-register Low/high Byte registers.

2. Why do we need to use X,Y,Z-register Low/high Byte registers and why those values (0X02, 0x5f, 0X00, 0X60) in the above code? Why are we not using other registers like R0, R1...,etc?

3. How this code fills RAM with 0xaa when it's using only 4-5 registers?

Any response, help or criticism are welcome.

Thanks
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Apr 26, 2012 - 08:48 AM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18513
Location: Lund, Sweden

Herte are some cluse:

See the comments to the right of the instructions?

E.g.
Code:
   st x, r16

stores the value in register r16 in the RAM cell whose address is in register x. Register x is an alias for the 8-bit register r27:r26. It is effectively a 16 bit register.

And
Code:
   sbiw r26,1

subtracts the value 1 from the registers r27:r26 (read it out as "subtract immediate from word", where "word" means a 16-bit value (i.e r27:r26).

In order to interpret the code bove, instruction by instruction, you need to get your hands on a document from Atmel entiteled "AVR Instruction Set Manual" or something very similar. It sould be accessible at Atmels site - go to any 8-bit AVR device page and then select the "Documents" tab and scroll through it to fins the document.

The details on why sometimes you need to use the register name x and sometimes the register names r27, r26 is in that document.

In some sort of pseudocode, this is what happens:

Code:
r27:r26 = 0x025f
r25:r24 = 0x0060
r16 = 0xaa
do
   ram[x] = r16
   x = x - 1
while r27:r26 <> r25:r24
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
wek
PostPosted: Apr 26, 2012 - 09:15 AM
Raving lunatic


Joined: Dec 16, 2005
Posts: 3086
Location: Bratislava, Slovakia

Stepping through the code in a simulator (such as in AVRStudio) may be very instructive, too; although it may take some effort to set it up.

Johan (or others): is there any truly step-by-step guide for this?

JW
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
beautiful_day
PostPosted: Apr 27, 2012 - 02:33 AM
Newbie


Joined: Oct 21, 2011
Posts: 19


Thanks, your reply was very helpful. But I still have some doubts.

1. r26,r27 is X-low/high byte register (so is it true that r24,25 are also low/high byte; r22,r23 - low/high & so on..) [sorry, if it sounds silly but that's what I feel from the code]

2. Couldn't understand the values given to r24...r27. But if I want to fill RAM with 0xAA from 0x21ff-0x200 then is this code correct?

Code:

.section .init0,"ax",@progbits

LDI r27;          CLEAR X HIGH BYTE
LDI r26, 0x21FF;  SET X LOW BYTE TO 0X21FF LOCATION
LDI r25;          CLEAR HIGH BYTE
LDI r24, 0X200;   SET LOW BYTE TO 0X200 LOCATION
LDI r16, 0XAA;    VALUE TO BE STORED

LOOP:
ST X, r16;
SBIW r26,1;    DECREMENT LOCATION BY 1
CP r26,r24;    COMPARE LOW BYTES
CPC r27, r25;  COMPARE HIGH BYTE WITH CARRY
BRNE LOOP;     BRANCH IF r27 & r25 ARE NOT EQUAL


Can I write:
Code:
ST X, r16;
SBIW r26,1;    DECREMENT LOCATION BY 1


as

Code:
ST X-, r16;


3. r16 register is used to set the value 0xAA (just like we use a variable in C), instead we can use r0, r1..or r15. Am I correct?


Thanks once again



JohanEkdahl wrote:
Herte are some cluse:



Last edited by beautiful_day on Apr 27, 2012 - 05:28 AM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Apr 27, 2012 - 05:05 AM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18513
Location: Lund, Sweden

Quote:

that's what I feel from the code

You can feel all you like. If you want facts then download the AVR Instruction Set document and use it.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
beautiful_day
PostPosted: Apr 27, 2012 - 05:26 AM
Newbie


Joined: Oct 21, 2011
Posts: 19


Hey, it's not like that (you guys are great, you catch every single word Smile).I downloaded the manual and read it...but I couldn't find or may be couldn't get it into my head correctly, that's why I said that. The manual is still open, am compiling the code and trying to solve errors & warning..if you don't believe..here are some of them after compiling the exact code written above(by me):

Code:
../RamInit.S: Assembler messages:
../RamInit.S:3: Error: `,' required
../RamInit.S:3: Error: garbage at end of line
../RamInit.S:4: Warning: constant out of 8-bit range: 8703
../RamInit.S:5: Error: `,' required
../RamInit.S:5: Error: garbage at end of line
../RamInit.S:6: Warning: constant out of 8-bit range: 512
 
 View user's profile Send private message  
Reply with quote Back to top
beautiful_day
PostPosted: Apr 27, 2012 - 06:07 AM
Newbie


Joined: Oct 21, 2011
Posts: 19


At least I got rid of the messages with this:

Code:
.section .init0,"ax",@progbits

clr r27;          CLEAR X HIGH BYTE
LDS r26, 0x21FF;  SET X LOW BYTE TO 0X21FF LOCATION
clr r25;          CLEAR HIGH BYTE
LDS r24, 0x200;   SET LOW BYTE TO 0X200 LOCATION
LDI r16, 0XAA;    VALUE TO BE STORED
 
 View user's profile Send private message  
Reply with quote Back to top
beautiful_day
PostPosted: Apr 27, 2012 - 08:22 AM
Newbie


Joined: Oct 21, 2011
Posts: 19


Hello,

I am debugging the program and watching the memory & registers. The program does fill 0xAA but at the wrong places (from 78-60). I don't understand why? The start & end address that I've given is 0x200-0x21FF respectively.

Somebody please point out my mistake...
 
 View user's profile Send private message  
Reply with quote Back to top
js
PostPosted: Apr 27, 2012 - 08:35 AM
10k+ Postman


Joined: Mar 28, 2001
Posts: 20311
Location: Sydney, Australia (Gum trees, Koalas and Kangaroos, No Edelweiss)

Code:
LDS r26, 0x21FF;  SET X LOW BYTE TO 0X21FF LOCATION
You CANNOT put a 16 bit value into a 8 bit register, that is loading r26 FROM address 0x21FF
Code:
LDS r24, 0x200;   SET LOW BYTE TO 0X200 LOCATION
same thing here

_________________
John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
SprinterSB
PostPosted: Apr 27, 2012 - 08:43 AM
Posting Freak


Joined: Dec 21, 2006
Posts: 1483
Location: Saar-Lor-Lux

You can use the code from here:
http://www.rn-wissen.de/index.php/Speic ... -Verbrauch

Code:
#include <avr/io.h> // RAMEND

#define MASK 0xaa

// !!! Never call this function, it is part of .init-Code
void __attribute__ ((naked, used, section(".init3"))) init_mem (void);
void init_mem (void)
{
   //  Use inline assembler so it works even with optimization turned off
   __asm volatile (
      "ldi r30, lo8 (__heap_start)"  "\n\t"
      "ldi r31, hi8 (__heap_start)"  "\n\t"
      "ldi r24, %0"                  "\n\t"
      "ldi r25, hi8 (%1)"            "\n"
      "0:"                           "\n\t"
      "st  Z+,  r24"                 "\n\t"
      "cpi r30, lo8 (%1)"            "\n\t"
      "cpc r31, r25"                 "\n\t"
      "brlo 0b"
         :
         : "n" (MASK), "n" (RAMEND+1)
   );
}
If you want a different start, use a different start address. The example above uses __heap_start which starts after static data.

For the start of RAM, you can use __data_start which is defined in the linker script, just like __heap_start.

I'd discourage to write this in C for several obvious reasons like, e.g. not overriding the return address of the worker.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
beautiful_day
PostPosted: Apr 27, 2012 - 11:18 PM
Newbie


Joined: Oct 21, 2011
Posts: 19


js wrote:
Code:
LDS r26, 0x21FF;  SET X LOW BYTE TO 0X21FF LOCATION
You CANNOT put a 16 bit value into a 8 bit register, that is loading r26 FROM address 0x21FF
Code:
LDS r24, 0x200;   SET LOW BYTE TO 0X200 LOCATION
same thing here


Thanks so much, it was very helpful (also understood why the values for R24...R27 were like that). Got the desired output.

Thanks everybody!
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits