Hello,
I'm trying to display a menu on my device, with str710 mcu. To do that, I create use structs to hold the variables and display them later. My structs look like this:
typedef const struct mMenu_s { int type; char text[3][20]; struct command { int command; int argument; } commands; struct specialline { int een; int twee; int drie; } speciallines; } menutype; typedef struct sMenuTemp { menutype *mCurmenu[20]; int iCurmenu; int iCurmenupos; int iOldmenu; int iOldmenupos; int menuactive; } cmdMenu; extern cmdMenu sMenu;
And to place data in it I use:
cmdMenu sMenu; menutype Backlightmenu[] = { { 1, {"Rood", "Red", "Rot"}, {SET_BACKLIGHT,RED}, {NULL,NULL,NULL} }, { 2, {"Groen", "Green", "Grun"}, {SET_BACKLIGHT,GREEN}, {NULL,NULL,NULL} }, { 3, {"Wit", "White", "Weiss"}, {SET_BACKLIGHT,WHITE}, {NULL,NULL,NULL} }, { NULL } }; sMenu->mCurmenu[BACKLIGHTMENU] = Backlightmenu;
With this method I can let (other) programmers create/delete/edit a menu very easy. So far so good.. All the text, commands, arguments and the rest of variables are stored in the memory OK (checked the memory watch, all OK!). But then.. I wan't to display the texts. Selecting the menu, the menuline, the language and the text is no problem. But, with the displaying, the last line of my struct is getting destroyed.
I've debugged my program, and it seems that the LCD-library caused the problem. It does an integer division, and the assembly calls "__aeabi_idivmod", which is an divide-function. On the first instruction, which is: PUSH {R4-R6,LR}, the data of my struct get destroyed, and it very, very weird values on the place of the struct..
And, the stupid thing.. When I remove the graphic-function, it's all normal. And, it doesn't matter on what memory-location my struct is placed, it happens every time.. It looks like the divide haunts my struct =S.
I'm working with the MDK-Arm 3.70 toolchain, in uVision3. Does anybody have an idea why this happens? Or, even better, the solution? I've tried a lot of other things, but it would be so d*mn easy to build and display my menu like that...
Thank you so very much.
Jay.
*) I've checked for a stack-overrun; not possible.
I'm afraid your word isn't quite good enough to back up this statement, especially since it rather strongly contradicts the evidence you showed. A PUSH instruction writes to data to exactly one place: the stack. That write is hitting data that's not supposed to be part of the stack. The only way that can happen is if the stack pointer register no longer points into the area allocated for the stack. That leaves two possibilities:
1) this PUSH is a stack-overrun in action
2) the stack pointer itself has been corrupted by a previous bug
You'll have to look at your memory map, register and call stack displays to tell these two apart. If the call stack still looks sane, and the stack pointer points near the allocated stack area, case 1) is more likely than 2).
Yes, you're right. It must be stack overrun.. When I disable a few things from my graphic-library (so, the library can skip a lot of functions), the struct stays intact.
I also found this document: infocenter.arm.com/.../index.jsp
It says that structs are always located on the stack. And the stack graphic library places also things on the stack. And because there is no more space, my data (from the struct) gets overwritten by other data.. I think I get it..
But.. With earlier versions of my software I also used a multi-dimensional struct with like 20 fields or something. But that struct was filled in another (very ugly) way. This way to fill my struct is much easier and looks very nice, but here it seems responsible for a stack overrun. Why? Why not with a very, very large struct and all of the functions of the library enabled? Is it because of the pointers? Because it's a pointer-struct? I don't know.... Anybody any idea how to solve it?
Thanks for your help everyone!
It says that structs are always located on the stack.
You're reading too much into that statement. That document talks about variables with automatic storage duration. In less technical terms, that means variables local to some function or other block, which are not marked "static". Your struct is supposedly of static storage duration (it hardly ever makes sense to have a 'const' variable that isn't), so this doesn't apply.
This way to fill my struct is much easier and looks very nice, but here it seems responsible for a stack overrun.
It's not. Whatever the reason for that stack overrun is, the definition of a variable is not it.