Posted by abcminiuser: Wed. Feb 4, 2009 - 09:38 AM
1
2
3
4
5
Total votes: 0
Sure, that'll work just fine. What isn't working for you? Remember that in C a zero byte is treated as a null-terminator -- if you have junk data in the first 10 bytes of the string, chances are one might be a terminator which will stop any display of the buffer contents before the contents of the EEPROM read string is reached.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
if you have junk data in the first 10 bytes of the string, chances are one might be a terminator which will stop any display of the buffer contents before the contents of the EEPROM read string is reached.
Hello guys, I have been programming AVRs using ASM for quite sometime already, and I am currently into learning C, and stumbling in loads of programming problems at that, especially regarding EEPROM.
I have declared/initialized my array like this:
uint8_t EEMEM memory[16][14];
And a snippet of my code is like this:
u16 i, j;
output[0] = target;
for (i=1, j=0 ; i<=16 ; i++, j++)
{
output[i] = eeprom_read_byte(&memory[target][j]);
}
output[18] = '\0';
USART_printstream(output); // prints the whole array of string
Posted by laktronics: Fri. Mar 13, 2009 - 06:18 AM
1
2
3
4
5
Total votes: 0
Hi,
While on this topic, if a programmer is designed to look for EEPROM and USERMEM just above the maximum flash code address for the device, only one hex file need be generated for code and data, instead of multiple files. In that case can GCC support placement of data outside the flash address area? What will be your comments on such a scheme?
With regards,
Laktronics
Your post should really be in the GCC forum but to do what you suggest would either need a different handling for each size of AVR or the data would have to be placed after the largest (256K) device but this then faces problems when 512K AVRs arrive. Also the programmer software would need to know about this split so all the various programmers (Ponyprog, avrdude, AVR Studio, etc, etc) would need to be updated to recognise where code ends and EEPROM data begins.
Anyway, what's the problem with using two files (which make a very definite split and can easily be handled by any programming software) ?
PS By the way if you just modify the rule that generates the .hex to not do the "-R .eeprom" then that data will be written into the .hex file alongside the code flash data (but at an address offset of 0x810000). The problem you'll face (because your programming software won't understand this) is that it will say "code image is too large for device" when you try to program it as it thinks you have code stretching out to 8MB+ (that offset picked so it would be bigger than the largest AVR might ever get)
Posted by laktronics: Sat. Mar 14, 2009 - 03:20 AM
1
2
3
4
5
Total votes: 0
Hello Clawson,
Thank you for your reply. Yes, you are right, I should post this question in the GCC Forum to hear their point of view.
I have posted in this forum to get a feedback from users on this scheme of initialising the EEPROM and USER Memory while programming. PIC ICs for example use such a scheme to embed EEPROM data within the main code so that users need not have to worry about handling two or more files (including USER MEM if available), in Assembly language. Also, Atmel's 89S8252 places its EEPROM address immediately after the Flash address only while programming. It helps much in documentation if number of files to be handled are few. Further, the device programming software need to open only one file during programming, thus saving some programming time.
As far as the device programming software is concerned, it is always aware of the chip specific memory map so that any data placed just above the flash address of the specific device in the hex file can be mapped on to the EEPROM/USER MEM area. So, it is not necessary to keep the data at the end of the flash address of the highest end AVR device.
Moving the EEPROM data to address just above the flash address in assembly can easily be done using ORG and DB/DW Directives.
Also, being a programmer specific architecture, there is no need to modify any of the existing programmer designs.
Thanking you once again for your valuable comments,
With regards,
Laktronics
As far as the device programming software is concerned, it is always aware of the chip specific memory map so that any data placed just above the flash address of the specific device in the hex file can be mapped on to the EEPROM/USER MEM area.
That maybe true of PIC programming software - presumably because it was done like this from day one. I'm afraid your idea kind of missed the boat for AVR where there are just too many different programming programs in existence now for them all to be updated to recognise this code/EPPROM split thing. Else what happens when someone uses a toolchain that builds combined .hex files but tries to feed it to programming software that does not uderstand the split? If Intel .hex contained an embedded version number then programmers could reject files they don't "understand" but that's not the case.
Probably the best hope would be to develop/use programming software that could interpret the ELF format. Clearly all the binary data is in that file and the various sections could be pulled out and programmed appropriately. Given that the source of avrdude is open I guess it would be the best base for developing something like that.
firstly i would like to thank Dean for this tutorial. Though, for a beginner like me, there will always be tons of question. Here it goes;
1. Ali_dehbidi wrote :
Quote:
but i think the max endurance is 100,000 Write/Erase Cycles
I respectfully agree with Endurance is 100,000 Write/Erase Cycles, but doubtful with the 'max'. As i read from the Atmega48/88/168 User guide stating
Quote:
The EEPROM has an endurance of at least 100,000 write/erase cycles
2. i read earlier regarding the performance question. So if i want to have a high performance, does it mean that i would strive for low usage of RAM and possibly low fetch-time?
3. referring to the BOD, if i understand fully from what is discussed previously, does it means that i only need to set my BOD fuse bit with the threshold voltage desired? Then this will protect malfunction of my EEPROM, what is the min voltage value of the EEPROM before it goes crazy? :)
Posted by hayashi_leo: Wed. May 6, 2009 - 08:05 PM
1
2
3
4
5
Total votes: 0
note if global interrupts are enabled; you must disable them "cli();" before performing a read; and enable them afterwards; otherwise the mcu will go into reset.
note if global interrupts are enabled; you must disable them "cli();" before performing a read; and enable them afterwards; otherwise the mcu will go into reset.
Is this correct, or is this handled by the eeprom.h functions?
int (*f2_ptr)(int) = NULL;
int result;
f2_ptr=(int*)eeprom_read_word(&mydata[0].f_ptr);
result = f2_ptr(332);
Should the (int*) be (unsigned int*).
I get various compiler errors on the same line:
warning: passing argument 1 of 'eeprom_read_word' from incompatible pointer type
warning: assignment from incompatible pointer type
This keeps the "complexity" of the function pointer type definition in one place and replaces uses of it with the easily digestible 'f_ptr_type' (which you might have your own name for). As I suggested in another thread, splitting the declaration and the definition of mydata[] so it can be easily made extern is further helped by typedef'ing the struct {}
So it's destination pointer is given as void *. The reason for this is that the authors of eeprom_read_block() cannot possibly know what the given pointer might be pointing at. You could do:
In the first the first parameter is a pointer to char, in the second a pointer to int, in the third a pointer to long and in the fourth a pointer to a 12 byte struct.
So when the type that a pointer variable is pointing at may not be known the C language allows for "void *" which kind of means "this could be pointing at anything".
The typecast is simply to tell the compiler to interpret the pointers as "void *" at the moment the eeprom_read_block() line is being compiled so they will match the defined paramater type given in the prototype.
I write in the EEPROM :
char tex1[20] = "12.05 BedTi 130";
when i read it i want to use only the 130 value to comapre it with another value if (something) then display a message on lcd. If anyone can tell me how to read only the 130?
I use AVR studio 4 , GCC compiler.
If the string will always be the same length, then just read characters 12 through 14. If it might change, read the entire string and just look at the last three characters. To get it from a string to a number (if this is what you want), use atoi().
Well did you realise that 4 in your itoa() is asking for the conversion to be made in base 4? So 3020 means 0 units, 2 lots of 4^1, 0 lots of 4^2 and 3 lots of 4^3. IOW 8 + (3 * 64). Which, if I got my sums right is 200 in decimal. You may want to try ",10" rather than ",4" ;-)
Ok.
I am so embarrassed now!!!
Somehow I thought 4 was the size of s!
Thank you very much. I ate 6 hours trying to figure out what was going on!
Thanks again.
Posted by JohanEkdahl: Mon. Sep 14, 2009 - 06:07 PM
1
2
3
4
5
Total votes: 0
You are welcome to locate the thread "The Stupid Things We Do" in the OT Forum and contribute to it, just as we have. Everyone does Really Stupid Things [tm], so don't be too embarrassed. :D
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]
hi all
i'm working with STK500 and Atmega128 microcontroller.
i'm newbie in C programming.Currently i try to make a program that when a character is receive from a microcontroller, it will write the received character into the EEPROM. Start from address 0 and increment this address location for the next character.Upon finishing writing 1 character into the EEPROM, i also want to read previous written character and transmit to the PC for verifications that the characters written to the EEPROM is correct.Below is my coding:
Posted by JohanEkdahl: Fri. Dec 4, 2009 - 10:27 AM
1
2
3
4
5
Total votes: 0
Dahlia!
1) Rather than adding yet another subject to this thread, you would have been better off starting your own thread, and
2) I suspect no-one is going to bother to look at your code the way it iss presented right now. All indentation is lost as you have just pasted it as normal text. Do this: i)Click the edit button for your message, ii)mark the source code, iii) click the "Code" button, and finally iv) click the submit button. Your code should now be shown with all textual structure (as indentations etc) intact. Now people might gete interested in looking at your code.
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]
My problem is that numeric data, that I write into the EEPROM, like the 'num' variable above, remains in the eeprom after resetting the device, however strings doesn't.
I write a string into the EEPROM, I can read it back, but after resetting the device, it simply disappears, reading it results in an empty string "".
Posted by abcminiuser: Sat. Jan 16, 2010 - 05:16 AM
1
2
3
4
5
Total votes: 0
You need to read/write one more byte to EEPROM than there are characters in the string -- there's a hidden 0x00 byte at the end of each string which terminates it. Without the terminator, your string routines will become confused.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
Posted by abcminiuser: Sat. Jan 16, 2010 - 05:49 AM
1
2
3
4
5
Total votes: 0
Ah:
(const void*)&string
This is casting the address of the string pointer to a const void pointer, rather than reinterpreting the pointer's destination type. You are writing the pointer value itself (plus a bunch of other garbage beyond it) to the EEPROM and reading it back, rather than the actual string contents like you desire.
Change the casts to remove the address operator:
(const void*)string
In the read and write calls.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
This is casting the address of the string pointer to a const void pointer, rather than reinterpreting the pointer's destination type. You are writing the pointer value itself (plus a bunch of other garbage beyond it) to the EEPROM and reading it back, rather than the actual string contents like you desire.
Change the casts to remove the address operator:
(const void*)string
In the read and write calls.
- Dean :twisted:
Thanks for your great help, i've figured out the above code works great with static strings , regardless of what I write at the length field. (I even get the whole string back, if i set length smaller than the length of the string!)
This is a command line parser, I'm getting a parameter, tokenize it along the spaces, and I'd like to store the second token into EEPROM. The 4 lines at the bottom work great, I can read the string back after reboot. The 4 lines above that, doesn't. I can read it back perfectly, but after a reboot, the string disappears.
Maybe the problem is that the token parts[1] is not zero-terminated?
Posted by abcminiuser: Sat. Jan 16, 2010 - 06:36 AM
1
2
3
4
5
Total votes: 0
Quote:
(I even get the whole string back, if i set length smaller than the length of the string!)
That is because you are initializing the string at the start of the routine - that way, even if you read back zero bytes, you still end up with the correct original string. If you try to copy the string into a separate buffer, you'll see that it will fail miserably. The EEPROM routines won't automatically NULL terminate your read strings -- it's assumed that you take care of that.
Note that this method:
uint8_t* string = "hello";
And this method:
uint8_t string[] = "hello";
Have slightly different meanings, but the latter is usually better from a code perspective (mostly because other buffers you declare with fixed sizes retain the same syntax).
If the strings are not null-terminated, strlen() will return an invalid result and you'll get garbage back.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
If the strings are not null-terminated, strlen() will return an invalid result and you'll get garbage back.
- Dean :twisted:
Well, then it's clearly not the case here, because the value of ee_rdr1_len is always correct.
I wonder what's the difference between "parts[1]" and "string". From the perspective of the eeprom_write_block function, they're just pointers, I think.
Posted by abcminiuser: Sat. Jan 16, 2010 - 07:03 AM
1
2
3
4
5
Total votes: 0
(const void*)&parts[1]
You're doing it again - remove the "&" sign. In this case, you've got a pointer-to-a-pointer-to-a-char, or interpreted in a different way, an array of strings. When you use the array notation parts[1], you are dereferencing the double pointer once, leaving you with a pointer to the desired string. You need to pass that pointer to the EEPROM functions directly rather than passing it's address.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
You're doing it again - remove the "&" sign. In this case, you've got a pointer-to-a-pointer-to-a-char, or interpreted in a different way, an array of strings. When you use the array notation parts[1], you are dereferencing the double pointer once, leaving you with a pointer to the desired string. You need to pass that pointer to the EEPROM functions directly rather than passing it's address.
- Dean :twisted:
If I remove the & sign, it stops working, this way I can't read it back at all. If & is there, I can at least read it back until reboot.
Posted by abcminiuser: Sat. Jan 16, 2010 - 11:49 AM
1
2
3
4
5
Total votes: 0
The more I read, the less it makes sense. Your parts variable is an array of pointers to char - but you're not actually allocating space for the strings. What you want is something like:
char parts[15][15];
Which will make parts an array of arrays. What you have now is causing the controller to store many bytes into an unallocated space, which is very bad.
Which forces Test2 to have a stack allocation of 10 bytes, so we can safely copy strings of up to 9 bytes (the tenth byte is the null terminator) without issue.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
The more I read, the less it makes sense. Your parts variable is an array of pointers to char - but you're not actually allocating space for the strings. What you want is something like:
char parts[15][15];
Which will make parts an array of arrays. What you have now is causing the controller to store many bytes into an unallocated space, which is very bad.
Which forces Test2 to have a stack allocation of 10 bytes, so we can safely copy strings of up to 9 bytes (the tenth byte is the null terminator) without issue.
- Dean :twisted:
Dean, thank very much! I've corrected my code, and everything works perfectly.
Can anyone help me out with a multidimensional array. I have the following array:
I would like to read elements out individually. I know I can't do:
...so would it be something like:
Thanks in advance
- Log in or register to post comments
Top- Log in or register to post comments
Topof course, thanks.
- Log in or register to post comments
TopHello,
I'm wondering if i can read data from the eeprom into a buffer, with a specific start position in the buffer?
Something like this: (not working)
What I'm trying to do is to read the word "test" into the sram_buffer, with a 10 bytes offset. Is it possible to do such things?
Thank you in advance,
/D
- Log in or register to post comments
TopSure, that'll work just fine. What isn't working for you? Remember that in C a zero byte is treated as a null-terminator -- if you have junk data in the first 10 bytes of the string, chances are one might be a terminator which will stop any display of the buffer contents before the contents of the EEPROM read string is reached.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
- Log in or register to post comments
TopAaaahh... Spot on! Thanks!
- Log in or register to post comments
TopHello guys, I have been programming AVRs using ASM for quite sometime already, and I am currently into learning C, and stumbling in loads of programming problems at that, especially regarding EEPROM.
I have declared/initialized my array like this:
And a snippet of my code is like this:
Problem is, the program can't get over the
part. So it just hangs.
I'm kinda noob at C, so any ideas? TIA! :)
- Log in or register to post comments
TopHi,
While on this topic, if a programmer is designed to look for EEPROM and USERMEM just above the maximum flash code address for the device, only one hex file need be generated for code and data, instead of multiple files. In that case can GCC support placement of data outside the flash address area? What will be your comments on such a scheme?
With regards,
Laktronics
- Log in or register to post comments
TopYour post should really be in the GCC forum but to do what you suggest would either need a different handling for each size of AVR or the data would have to be placed after the largest (256K) device but this then faces problems when 512K AVRs arrive. Also the programmer software would need to know about this split so all the various programmers (Ponyprog, avrdude, AVR Studio, etc, etc) would need to be updated to recognise where code ends and EEPROM data begins.
Anyway, what's the problem with using two files (which make a very definite split and can easily be handled by any programming software) ?
PS By the way if you just modify the rule that generates the .hex to not do the "-R .eeprom" then that data will be written into the .hex file alongside the code flash data (but at an address offset of 0x810000). The problem you'll face (because your programming software won't understand this) is that it will say "code image is too large for device" when you try to program it as it thinks you have code stretching out to 8MB+ (that offset picked so it would be bigger than the largest AVR might ever get)
- Log in or register to post comments
TopHello Clawson,
Thank you for your reply. Yes, you are right, I should post this question in the GCC Forum to hear their point of view.
I have posted in this forum to get a feedback from users on this scheme of initialising the EEPROM and USER Memory while programming. PIC ICs for example use such a scheme to embed EEPROM data within the main code so that users need not have to worry about handling two or more files (including USER MEM if available), in Assembly language. Also, Atmel's 89S8252 places its EEPROM address immediately after the Flash address only while programming. It helps much in documentation if number of files to be handled are few. Further, the device programming software need to open only one file during programming, thus saving some programming time.
As far as the device programming software is concerned, it is always aware of the chip specific memory map so that any data placed just above the flash address of the specific device in the hex file can be mapped on to the EEPROM/USER MEM area. So, it is not necessary to keep the data at the end of the flash address of the highest end AVR device.
Moving the EEPROM data to address just above the flash address in assembly can easily be done using ORG and DB/DW Directives.
Also, being a programmer specific architecture, there is no need to modify any of the existing programmer designs.
Thanking you once again for your valuable comments,
With regards,
Laktronics
- Log in or register to post comments
TopThat maybe true of PIC programming software - presumably because it was done like this from day one. I'm afraid your idea kind of missed the boat for AVR where there are just too many different programming programs in existence now for them all to be updated to recognise this code/EPPROM split thing. Else what happens when someone uses a toolchain that builds combined .hex files but tries to feed it to programming software that does not uderstand the split? If Intel .hex contained an embedded version number then programmers could reject files they don't "understand" but that's not the case.
Probably the best hope would be to develop/use programming software that could interpret the ELF format. Clearly all the binary data is in that file and the various sections could be pulled out and programmed appropriately. Given that the source of avrdude is open I guess it would be the best base for developing something like that.
Cliff
- Log in or register to post comments
TopHi,
firstly i would like to thank Dean for this tutorial. Though, for a beginner like me, there will always be tons of question. Here it goes;
1. Ali_dehbidi wrote :
I respectfully agree with Endurance is 100,000 Write/Erase Cycles, but doubtful with the 'max'. As i read from the Atmega48/88/168 User guide stating
2. i read earlier regarding the performance question. So if i want to have a high performance, does it mean that i would strive for low usage of RAM and possibly low fetch-time?
3. referring to the BOD, if i understand fully from what is discussed previously, does it means that i only need to set my BOD fuse bit with the threshold voltage desired? Then this will protect malfunction of my EEPROM, what is the min voltage value of the EEPROM before it goes crazy? :)
Regards,
Nicholas
- Log in or register to post comments
TopThis an useful tutorial for me :D
Thanks a lot :)
ArcticSoul
Industrial Electronic Engineering, College Student
- Log in or register to post comments
Topnote if global interrupts are enabled; you must disable them "cli();" before performing a read; and enable them afterwards; otherwise the mcu will go into reset.
- Log in or register to post comments
TopHow would one go about reading and writing a floating point variable from/to EEPROM?
- Log in or register to post comments
Top(actually sizeof(f) is 4 as 32 bit IEEE754 floats are used)
- Log in or register to post comments
Top- Log in or register to post comments
TopLet's say you have stored a function pointer, or a structure containing a function pointer in EEMEM. How do you pull it out and call the function?
struct mystruct{
char text;
int (*f_ptr)(int);
};
..
..
struct mystruct mydata[] EEMEM = {
{1, &f1},
{2, &f2}
}
int (*f2_ptr)(int) = NULL;
int result;
f2_ptr=(int*)eeprom_read_word(&mydata[0].f_ptr);
result = f2_ptr(332);
Should the (int*) be (unsigned int*).
I get various compiler errors on the same line:
warning: passing argument 1 of 'eeprom_read_word' from incompatible pointer type
warning: assignment from incompatible pointer type
- Log in or register to post comments
Topsplit63,
Do yourself a favour and get into the habit of typedef'in things as it'll make your code simpler to read:
Put that into a shared .h, then in a .c file:
This keeps the "complexity" of the function pointer type definition in one place and replaces uses of it with the easily digestible 'f_ptr_type' (which you might have your own name for). As I suggested in another thread, splitting the declaration and the definition of mydata[] so it can be easily made extern is further helped by typedef'ing the struct {}
Cliff
- Log in or register to post comments
Topfrom a much earlier post on page 1:
Can someone explain why the (void*) cast is necessary and what it does in this case?
I found that in the case of characters, I have not needed this. But when I tried this for a float, I had to add the (void*).
char temp[10];
eeprom_read_block(&temp,&EEVar, 10);
- Log in or register to post comments
TopWell start by looking at avr/eeprom.h where the prototype for eeprom_read_block is:
So it's destination pointer is given as void *. The reason for this is that the authors of eeprom_read_block() cannot possibly know what the given pointer might be pointing at. You could do:
In the first the first parameter is a pointer to char, in the second a pointer to int, in the third a pointer to long and in the fourth a pointer to a 12 byte struct.
So when the type that a pointer variable is pointing at may not be known the C language allows for "void *" which kind of means "this could be pointing at anything".
The typecast is simply to tell the compiler to interpret the pointers as "void *" at the moment the eeprom_read_block() line is being compiled so they will match the defined paramater type given in the prototype.
Cliff
- Log in or register to post comments
TopHi, this is my first post here and I'm trying to use the EEPROM with GCC.
Shouldn't be the last line:
or
since the arrays are already the addresses the '&' operators need to be avoided.
Please correct me if I am wrong.
Cheers
- Log in or register to post comments
TopIn the case of using the array name it doesn't matter if you use & or not.
- Log in or register to post comments
TopHello!
I write in the EEPROM :
char tex1[20] = "12.05 BedTi 130";
when i read it i want to use only the 130 value to comapre it with another value if (something) then display a message on lcd. If anyone can tell me how to read only the 130?
I use AVR studio 4 , GCC compiler.
Thank you in advance,
- Log in or register to post comments
TopIf the string will always be the same length, then just read characters 12 through 14. If it might change, read the entire string and just look at the last three characters. To get it from a string to a number (if this is what you want), use atoi().
Regards,
Steve A.
The Board helps those that help themselves.
- Log in or register to post comments
Topplz give me some example code to write data in EEPROM using "void eeprom_write_word (uint16_t *addr, uint16_t value)" :oops: :oops:
- Log in or register to post comments
Top- Log in or register to post comments
TopNice tutorial!
- Log in or register to post comments
TopHi, i think you made an error in your code...
-edit- wh00ps, &array_name is the same as &array_name[0], so it's okay, sorry :)
- Log in or register to post comments
TopSuggest you take a look at the generated code both with and without the '&' - notice anything?
- Log in or register to post comments
TopWhat about negative numbers?
- Log in or register to post comments
TopJust store retrieve as uchar/uint then cast the signed interpretation onto them
- Log in or register to post comments
Topsorry for this but I am stuck.
Here is my code
s is always "3020"
What is going wrong with my code?
- Log in or register to post comments
TopWell did you realise that 4 in your itoa() is asking for the conversion to be made in base 4? So 3020 means 0 units, 2 lots of 4^1, 0 lots of 4^2 and 3 lots of 4^3. IOW 8 + (3 * 64). Which, if I got my sums right is 200 in decimal. You may want to try ",10" rather than ",4" ;-)
- Log in or register to post comments
TopOk.
I am so embarrassed now!!!
Somehow I thought 4 was the size of s!
Thank you very much. I ate 6 hours trying to figure out what was going on!
Thanks again.
- Log in or register to post comments
TopYou are welcome to locate the thread "The Stupid Things We Do" in the OT Forum and contribute to it, just as we have. Everyone does Really Stupid Things [tm], so don't be too embarrassed. :D
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]
- Log in or register to post comments
Tophi all
i'm working with STK500 and Atmega128 microcontroller.
i'm newbie in C programming.Currently i try to make a program that when a character is receive from a microcontroller, it will write the received character into the EEPROM. Start from address 0 and increment this address location for the next character.Upon finishing writing 1 character into the EEPROM, i also want to read previous written character and transmit to the PC for verifications that the characters written to the EEPROM is correct.Below is my coding:
When i try this,it give me unknown data.i hope anybody can help me with this.Sorry for my bad english
Rgrd
Dahlia
- Log in or register to post comments
TopDahlia!
1) Rather than adding yet another subject to this thread, you would have been better off starting your own thread, and
2) I suspect no-one is going to bother to look at your code the way it iss presented right now. All indentation is lost as you have just pasted it as normal text. Do this: i)Click the edit button for your message, ii)mark the source code, iii) click the "Code" button, and finally iv) click the submit button. Your code should now be shown with all textual structure (as indentations etc) intact. Now people might gete interested in looking at your code.
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]
- Log in or register to post comments
Topok.i will do that.thanks..
- Log in or register to post comments
TopHi everyone!
I'm a newbie here, sorry for the dumb question...
I use EEPROM in avr-gcc to store data like this:
My problem is that numeric data, that I write into the EEPROM, like the 'num' variable above, remains in the eeprom after resetting the device, however strings doesn't.
I write a string into the EEPROM, I can read it back, but after resetting the device, it simply disappears, reading it results in an empty string "".
Could you give me any hints on this? Thanks.
Peter
- Log in or register to post comments
TopYou need to read/write one more byte to EEPROM than there are characters in the string -- there's a hidden 0x00 byte at the end of each string which terminates it. Without the terminator, your string routines will become confused.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
- Log in or register to post comments
TopAh:
This is casting the address of the string pointer to a const void pointer, rather than reinterpreting the pointer's destination type. You are writing the pointer value itself (plus a bunch of other garbage beyond it) to the EEPROM and reading it back, rather than the actual string contents like you desire.
Change the casts to remove the address operator:
In the read and write calls.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
- Log in or register to post comments
TopThanks for your great help, i've figured out the above code works great with static strings , regardless of what I write at the length field. (I even get the whole string back, if i set length smaller than the length of the string!)
Here's the full code I'm working on:
This is a command line parser, I'm getting a parameter, tokenize it along the spaces, and I'd like to store the second token into EEPROM. The 4 lines at the bottom work great, I can read the string back after reboot. The 4 lines above that, doesn't. I can read it back perfectly, but after a reboot, the string disappears.
Maybe the problem is that the token parts[1] is not zero-terminated?
Peter
- Log in or register to post comments
TopThat is because you are initializing the string at the start of the routine - that way, even if you read back zero bytes, you still end up with the correct original string. If you try to copy the string into a separate buffer, you'll see that it will fail miserably. The EEPROM routines won't automatically NULL terminate your read strings -- it's assumed that you take care of that.
Note that this method:
And this method:
Have slightly different meanings, but the latter is usually better from a code perspective (mostly because other buffers you declare with fixed sizes retain the same syntax).
If the strings are not null-terminated, strlen() will return an invalid result and you'll get garbage back.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
- Log in or register to post comments
TopWell, then it's clearly not the case here, because the value of ee_rdr1_len is always correct.
I wonder what's the difference between "parts[1]" and "string". From the perspective of the eeprom_write_block function, they're just pointers, I think.
Peter
- Log in or register to post comments
TopYou're doing it again - remove the "&" sign. In this case, you've got a pointer-to-a-pointer-to-a-char, or interpreted in a different way, an array of strings. When you use the array notation parts[1], you are dereferencing the double pointer once, leaving you with a pointer to the desired string. You need to pass that pointer to the EEPROM functions directly rather than passing it's address.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
- Log in or register to post comments
TopIf I remove the & sign, it stops working, this way I can't read it back at all. If & is there, I can at least read it back until reboot.
Peter
- Log in or register to post comments
TopThe more I read, the less it makes sense. Your parts variable is an array of pointers to char - but you're not actually allocating space for the strings. What you want is something like:
Which will make parts an array of arrays. What you have now is causing the controller to store many bytes into an unallocated space, which is very bad.
Take this example:
Here we have Test2, a raw pointer to unallocated space, and so *any* writes to it's destination will cause data corruption.
A corrected sample would be:
Which forces Test2 to have a stack allocation of 10 bytes, so we can safely copy strings of up to 9 bytes (the tenth byte is the null terminator) without issue.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
- Log in or register to post comments
TopDean, thank very much! I've corrected my code, and everything works perfectly.
regards,
Peter
- Log in or register to post comments
TopExcellent guide.
The freaks owes you a bundle!
- Log in or register to post comments
TopPages