go_away

Author Topic: ATMEGA 32A memory locations  (Read 3637 times)

0 Members and 1 Guest are viewing this topic.

Offline AsellithTopic starter

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 648
  • Helpful? 9
  • "I'm a leaf on the wind. Watch how I soar"
    • CorSec Engineering
ATMEGA 32A memory locations
« on: January 18, 2010, 06:58:18 PM »
I'm having a bit of trouble figuring something out so I thought I would post here while I continue my googling. I am working on the OSCAR module code. I have a ton of data flying around in interrupts and am trying to figure out where I can put it all. I'm assuming that if I declare a variable and try to load data into it from the interrupt I will have trouble. So I thought well I guess I'll have to define a range of memory to use for data storage. How do I prevent the locations from being used by other sections of code (unless I need them) and how do I read/write directly to a memory address in C?  Also where can I find valid address to use inside memory?

Jonathan Bowen
CorSec Engineering
www.corseceng.com

Offline TrickyNekro

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 1,208
  • Helpful? 15
  • Hardware and Firmware Designer
    • The Hellinic Robots Portal
Re: ATMEGA 32A memory locations
« Reply #1 on: January 18, 2010, 08:54:53 PM »
Why do you need to do this? Can't you define a global variable...
I haven't tried interrupts in C but... As far as I know, and as hated as they are...
Global variables have a purpose of being... At least this is how I was doing it in Basic...
Haven't tried interrupts in C, at least for now...
For whom the interrupts toll...

Offline AsellithTopic starter

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 648
  • Helpful? 9
  • "I'm a leaf on the wind. Watch how I soar"
    • CorSec Engineering
Re: ATMEGA 32A memory locations
« Reply #2 on: January 18, 2010, 11:03:33 PM »
I'm not sure if globals are guaranteed to work. I had a project on an Z8 Encore! that would loss values in its global variables because of interrupts. somewhere in the code it was changing the memory location assigned to it. Of course that was a different controller and a different compiler.
Jonathan Bowen
CorSec Engineering
www.corseceng.com

Offline TrickyNekro

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 1,208
  • Helpful? 15
  • Hardware and Firmware Designer
    • The Hellinic Robots Portal
Re: ATMEGA 32A memory locations
« Reply #3 on: January 20, 2010, 01:27:24 PM »
I don't thing that happens with atmegas or attinies... really, I had no problem...
I even was updating on interrupt some variables...
Are you sure you defined the variables on the main program and not a subroutine or so???

Give it a run, and get some posts on your concerns at AVR freaks.
It's the best place if you looking for answers...
For whom the interrupts toll...

Offline AsellithTopic starter

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 648
  • Helpful? 9
  • "I'm a leaf on the wind. Watch how I soar"
    • CorSec Engineering
Re: ATMEGA 32A memory locations
« Reply #4 on: January 20, 2010, 03:36:00 PM »
just checking does a global in a seperate .c file still have scope in the main program? If I build a library for the I2C stuff and access those variable in the main program in a main.c file does the scope work?
Jonathan Bowen
CorSec Engineering
www.corseceng.com

Offline TrickyNekro

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 1,208
  • Helpful? 15
  • Hardware and Firmware Designer
    • The Hellinic Robots Portal
Re: ATMEGA 32A memory locations
« Reply #5 on: January 20, 2010, 03:42:28 PM »
And why to do this. You usually define globals at the start of the program, separate .c / .h doesn't matter really...
What are you trying to do exactly, maybe that will help me understand better...
I'm no C expert for sure, I can only give a try...

Best Regards, Lefteris
Greece
For whom the interrupts toll...

Offline rgcustodio

  • Robot Overlord
  • ****
  • Posts: 217
  • Helpful? 0
  • Use "Search" and ye might find answers!
Re: ATMEGA 32A memory locations
« Reply #6 on: January 20, 2010, 04:46:32 PM »
When a global variable name is defined in one C file it will be accessible to other modules (or sources code) linked to it. If you define it "static" the global variable will only be known within the file it was declared (i.e. static long int _gValue;)

Global variables will not work properly if you have separate "threads of execution" because there might be a possible race condition (i.e. one part of the program is accessing the global variable, while the other part is trying to update the variable, does the code accessing the variable get the correct value?). For simple applications, globals will (should) work.

just checking does a global in a seperate .c file still have scope in the main program? If I build a library for the I2C stuff and access those variable in the main program in a main.c file does the scope work?
The best thing one can do when it's raining is to let it rain. - H. W. Longfellow

understanding is the path to enlightenment

Offline AsellithTopic starter

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 648
  • Helpful? 9
  • "I'm a leaf on the wind. Watch how I soar"
    • CorSec Engineering
Re: ATMEGA 32A memory locations
« Reply #7 on: January 20, 2010, 08:36:15 PM »
I need to pass a lot of data around as data is shifted in and out in my I2C code. However in the background I still need to be updating distance data from at least 3 sensors probably more. What I wanted to do was assign a memory region for my various sets of data. For instance I would pass an array of lets say 10 previous values for each of the sensors. into memory. Then just keep rotating the data in and out of those memory locations. Then the I2C module gets a call to read the last entry from sensor 3. Well then my code just pulls that data from the first memory location assigned to sensor 2s data array.

On the flip side if the master calls for the last 10 entries on sensor 2 it can easily take the entire array. My concern is like rgcustodio said is that if I am writing to sensor 2s array and the interrupt steps in it will take a garbage array with who knows what in it because sensor 2 was taking a reading at that time.

In any case I will need to make some sort of variable change to indicate when a sensor starts updating its array and when it is not using it. So maybe it will work with globals but because I only have an ISP mk2 it will be hard to debug without stepping through the code one line at a time. The I2C bus operation requires a lot of simple interrupt actions each time communication is initalized. So anther problem will come about when I have the array being feed out on I2C and mid way through the program tries to take control. Maybe I can make globals work.

T minus 10 days to finish the project for the contest :(
Jonathan Bowen
CorSec Engineering
www.corseceng.com

Offline hopslink

  • Robot Overlord
  • ****
  • Posts: 202
  • Helpful? 14
Re: ATMEGA 32A memory locations
« Reply #8 on: January 21, 2010, 02:22:38 AM »
Quote
...My concern is like rgcustodio said is that if I am writing to sensor 2s array and the interrupt steps in it will take a garbage array with who knows what in it because sensor 2 was taking a reading at that time.

In any case I will need to make some sort of variable change to indicate when a sensor starts updating its array and when it is not using it....
Don't forget you can avert such race conditions by temporarily disabling interrupts as you write data to your array. This is probably simpler with less code overhead than having access flags.

Also this may be of use >LINKY< if you are using the optimizer when compiling - see volatile.

Offline guncha

  • Jr. Member
  • **
  • Posts: 40
  • Helpful? 0
Re: ATMEGA 32A memory locations
« Reply #9 on: January 21, 2010, 05:09:36 AM »
You know, pointers in C can point to another variable.

Like this:
Code: [Select]
int *ptr = &someothervariable;
But did you know that you can point it pretty much anywhere ? A la..
Code: [Select]
int *ptr = 0x345678;
And this is how you access memory directly.

Offline AsellithTopic starter

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 648
  • Helpful? 9
  • "I'm a leaf on the wind. Watch how I soar"
    • CorSec Engineering
Re: ATMEGA 32A memory locations
« Reply #10 on: January 21, 2010, 08:16:58 AM »
I was going to use pointers but my concern is how do I stop the program from using that location to store data from something else?

Enabling and disabling interrupts might work fine if I use them sparingly. My concern is a standard I2C interrupt sequence in the AVR is at least 4 interrupts in a row and could be many more because each data byte sent has a single interrupt. the code is not that intensive but I have to check the status register every time to see what to do and then execute the command. Whenever the interrupt flag is active for the I2C hardware it stops ALL bus traffic until you deal with it. So I just have to be careful. Of course using a flag I'll need to send a NACK back and then have the master try again.
Jonathan Bowen
CorSec Engineering
www.corseceng.com

Offline guncha

  • Jr. Member
  • **
  • Posts: 40
  • Helpful? 0
Re: ATMEGA 32A memory locations
« Reply #11 on: January 21, 2010, 08:34:24 AM »
Well, you could always use malloc to grab a piece of memory. They have it ported for AVR, but it might take up too much program space (especially if you don't use it elsewere). A global array would do the trick just fine.

Offline rgcustodio

  • Robot Overlord
  • ****
  • Posts: 217
  • Helpful? 0
  • Use "Search" and ye might find answers!
Re: ATMEGA 32A memory locations
« Reply #12 on: January 21, 2010, 09:23:31 AM »
Quote
I was going to use pointers but my concern is how do I stop the program from using that location to store data from something else?
This is frequently done in embedded system.
Local and global variables are pre-allocated, so whatever is left is for heap and stack usage. Dynamic memory allocator (malloc) use the heap. The stack gets used, for example when you call a function with parameters.  In most implementations, heap grows up, and stack grows down. In systems with very limited memory, there is a very big possibility of the stack getting smashed or the stack colliding with the heap. If you overwrite the stack weird things happen ;-)


The image here shows what I'm trying to explain (pictures speak louder than words):
http://www.nongnu.org/avr-libc/user-manual/malloc.html

The main item now is knowing where your heap starts. The gcc toolsuite provides a tool to determine this, objdump (maybe avr-objdump in your case). Compute the end of the bss segment (initialized data segment) by using the offset and segment size returned by objdump. Use a few bytes (4-bytes perhaps) before and after your memory as "guards", write fixed data on them ie 0xfefefefe. This will help in debugging if you are touching the memory area you reserved. If the guard bytes changes value, you know you've written over it. So checking all your code which write to this specific memory location will be a good place to start debugging.

Quote
My concern is a standard I2C interrupt sequence in the AVR is at least 4 interrupts in a row and
Then, why not use a polling I2C routines instead?
Your main program is relying on the data from I2C and it has to wait for all data to valid. If you do polling, after the I2C routine is executed you are already guaranteed of correct data. Less hassle and might actually be faster.
« Last Edit: January 21, 2010, 09:27:41 AM by rgcustodio »
The best thing one can do when it's raining is to let it rain. - H. W. Longfellow

understanding is the path to enlightenment

Offline AsellithTopic starter

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 648
  • Helpful? 9
  • "I'm a leaf on the wind. Watch how I soar"
    • CorSec Engineering
Re: ATMEGA 32A memory locations
« Reply #13 on: January 21, 2010, 10:26:02 AM »
Does the AVR Support polling? I am using the ATMEG32A. I just read through the description of the TWI (I2C) hardware and the examples of software. I just don't think the I2C hardware on the ATMEGA series is that good. As it is I have read reports of bus contention with multimaster systems. I am not even looking into that till I get a slave master relationship working.

According to the data sheet the TWINT flag gets set and fires off an interrupt at every stage of the transmission. I don't have to do much in software besides check the status register and do error checking. Or in the case of when data is sent I need to put it some where or set some variables to allow it to issue commands to the modules. such as send me last reading from sensor 1 or the last 10 readings from all sensors.
Jonathan Bowen
CorSec Engineering
www.corseceng.com

Offline hopslink

  • Robot Overlord
  • ****
  • Posts: 202
  • Helpful? 14
Re: ATMEGA 32A memory locations
« Reply #14 on: January 21, 2010, 02:23:08 PM »
To do polling you would clear the TWIE bit so that TWINT does not fire an interrupt when it is set. You then read/poll TWINT yourself to see if it is set, and deal with the results when it is. The code will be the same but now it is part of your main routine and not an interrupt.



 

Offline AsellithTopic starter

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 648
  • Helpful? 9
  • "I'm a leaf on the wind. Watch how I soar"
    • CorSec Engineering
Re: ATMEGA 32A memory locations
« Reply #15 on: January 21, 2010, 03:47:50 PM »
Polling might work but its gonna be a pain. I'm gonna have to watch the port like crazy. It will increase my bus usage time and lower my transfer rates which is fine now but plans are to have complex modules with several talking to each other and the master controller. So with several distance sensors talking to motor controls to avoid objects and something like a GPS mapping running in the background there might be a ton of data some of it critical moving around. I guess I'll cross those bridges when I come to them.

Edit: did a lot of pseudo code last night and I guess polling will not be as bad as I thought. After looking at the datasheet again I think it will be fast enough I'll just have to stop taking sensor readings when the I2C bus goes active till it finishes but that shouldn't be a big deal unless the bot is moving super fast and needs object avoidance data like crazy but thats not a situation the module will need to be designed for.
« Last Edit: January 22, 2010, 07:17:30 AM by Asellith »
Jonathan Bowen
CorSec Engineering
www.corseceng.com

 


Get Your Ad Here