| Author |
Message |
|
|
Posted: Jun 16, 2011 - 10:49 PM |
|

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? |
|
|
| |
|
|
|
|
|
Posted: Jun 16, 2011 - 10:55 PM |
|

Joined: Oct 07, 2002
Posts: 2059
Location: Denmark
|
|
|
|
|
|
|
Posted: Jun 16, 2011 - 11:16 PM |
|

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
|
|
|
| |
|
|
|
|
|
Posted: Jun 16, 2011 - 11:27 PM |
|

Joined: Oct 07, 2002
Posts: 2059
Location: Denmark
|
|
| make address a char pointer ! (do some C study) |
|
|
| |
|
|
|
|
|
Posted: Jun 17, 2011 - 02:11 AM |
|

Joined: Nov 28, 2004
Posts: 3628
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
|
| |
|
|
|
|
|
Posted: Jun 17, 2011 - 07:28 PM |
|

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.
|
|
|
| |
|
|
|
|
|
Posted: Jun 17, 2011 - 08:00 PM |
|

Joined: Feb 12, 2005
Posts: 16550
Location: Wormshill, England
|
|
Google is your friend.
If you quote any passage that you find that you do not understand, we can help.
David. |
|
|
| |
|
|
|
|
|
Posted: Jun 17, 2011 - 09:16 PM |
|

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?
|
|
|
| |
|
|
|
|
|
Posted: Jun 17, 2011 - 09:42 PM |
|

Joined: Oct 07, 2002
Posts: 2059
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. |
|
|
| |
|
|
|
|
|
Posted: Jun 18, 2011 - 03:17 AM |
|

Joined: Nov 28, 2004
Posts: 3628
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...
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
|
| |
|
|
|
|
|
Posted: Jun 18, 2011 - 03:47 AM |
|

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...
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.
|
|
|
| |
|
|
|
|
|
Posted: Jun 18, 2011 - 02:18 PM |
|


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
|
| |
|
|
|
|
|
Posted: Jun 18, 2011 - 06:52 PM |
|

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.
|
|
|
| |
|
|
|
|
|
Posted: Jun 18, 2011 - 06:56 PM |
|


Joined: Jul 18, 2005
Posts: 62944
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. |
_________________
|
| |
|
|
|
|
|
Posted: Jun 18, 2011 - 08:22 PM |
|

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?
|
|
|
| |
|
|
|
|
|
Posted: Jun 18, 2011 - 08:55 PM |
|

Joined: Dec 16, 2005
Posts: 3096
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 |
|
|
| |
|
|
|
|
|
Posted: Jun 20, 2011 - 05:19 PM |
|

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
|
|
|
| |
|
|
|
|
|
Posted: Jun 28, 2011 - 11:17 AM |
|

Joined: Nov 28, 2004
Posts: 3628
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
|
| |
|
|
|
|
|
Posted: Apr 26, 2012 - 08:30 AM |
|

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 |
|
|
| |
|
|
|
|
|
Posted: Apr 26, 2012 - 08:48 AM |
|


Joined: Mar 27, 2002
Posts: 18760
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
|
|
|
| |
|
|
|
|
|
Posted: Apr 26, 2012 - 09:15 AM |
|

Joined: Dec 16, 2005
Posts: 3096
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 |
|
|
| |
|
|
|
|
|
Posted: Apr 27, 2012 - 02:33 AM |
|

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
|
| |
|
|
|
|
|
Posted: Apr 27, 2012 - 05:05 AM |
|


Joined: Mar 27, 2002
Posts: 18760
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. |
|
|
| |
|
|
|
|
|
Posted: Apr 27, 2012 - 05:26 AM |
|

Joined: Oct 21, 2011
Posts: 19
|
|
Hey, it's not like that (you guys are great, you catch every single word ).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
|
|
|
| |
|
|
|
|
|
Posted: Apr 27, 2012 - 06:07 AM |
|

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
|
|
|
| |
|
|
|
|
|
Posted: Apr 27, 2012 - 08:22 AM |
|

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... |
|
|
| |
|
|
|
|
|
Posted: Apr 27, 2012 - 08:35 AM |
|


Joined: Mar 28, 2001
Posts: 20635
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
|
| |
|
|
|
|
|
Posted: Apr 27, 2012 - 08:43 AM |
|


Joined: Dec 21, 2006
Posts: 1551
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. |
|
|
| |
|
|
|
|
|
Posted: Apr 27, 2012 - 11:18 PM |
|

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! |
|
|
| |
|
|
|
|
|