|
|
View previous topic :: View next topic |
Author |
Message |
darkrush
Joined: 29 Sep 2011 Posts: 18 Location: Colombia
|
rom struct forward declaration |
Posted: Wed Nov 06, 2013 10:52 am |
|
|
Hello,
I'm working on a menu struct stored in ROM.
I have successfully accessed the menu struct in ROM, however when I have to overload the menus I have to use "extern" which messes up the address of the menus.
This is the menu struct:
Code: |
typedef void (*fPtr)(void);
typedef struct{
char menuType;
char menuText[30];
int32 menuSelection; //address to a submenu else is NULL
fPtr functionSelectionPtr; //points to a command or function to execute else is NULL
}MENU;
|
Menus:
Code: |
extern ROM MENU mainMenu [];
extern ROM MENU currentDataMenu[];
ROM MENU subMenu[]={
{MENU_BACKSUBMENU,"",mainMenu,NULL},
{MENU_SUBMENU,"SubElement 1 ",NULL,NULL},
{MENU_SUBMENU,"SubElement 2 ",NULL,NULL},
{MENU_SUBMENU,"SubElement 3 ",NULL,NULL},
{MENU_SUBMENU,"SubElement 4 ",NULL,NULL},
{MENU_END,"",NULL,NULL}
};
ROM MENU mainMenu[]={
{MENU_MAIN,"",NULL,NULL},
{MENU_SUBMENU,"Element 1 ",subMenu,NULL},
{MENU_SUBMENU,"Element 2 ",NULL,NULL},
{MENU_SUBMENU,"Element 3 ",NULL,NULL},
{MENU_SUBMENU,"Element 4 ",NULL,NULL},
{MENU_END,"",NULL,NULL}
};
|
To access the menus I load the array to a rom pointer and then load the current menu into ram.
Code: |
ROM MENU *currentMenu;
MENU ramMenu;
currentMenu = mainMenu; //address 129424
ramMenu = currentMenu[1]//ramMenu.menuSelection has 129610 that is subMenu address
//change to subMenu
currentMenu = ramMenu.menuSelection //address 129610 (subMenu)
ramMenu = currentMenu[0]//ramMenu.menuSelection has 995 and should have 129424 to point back to mainMenu
|
So when I try to go back, in this case, to the mainMenu the address is wrong.
Is there a way to use forward declaration without using extern?, I suspect the compiler doesn't work well with it.
I'm using compiler 4.140 version.
PIC18F87K90.
Any help would be greatly appreciated.
Best Regards. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Nov 06, 2013 4:38 pm |
|
|
Post a test program instead of code fragments. |
|
|
darkrush
Joined: 29 Sep 2011 Posts: 18 Location: Colombia
|
|
Posted: Wed Nov 06, 2013 6:09 pm |
|
|
This is a functional code.
config.c
Code: |
#include <18F87K90.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES PUT
#FUSES NOBROWNOUT //No brownout reset
#FUSES ECCPE //ECCP1 (P1B/P1C) is multiplexed onto RE6 and RE5, CCP6 onto RE6 and CCP7 onto RE5
#FUSES MCLR //Master Clear pin enabled
#FUSES PROTECT
#FUSES NODEBUG
#use delay(clock=64000000)
#use rs232(baud=115200, uart1)//xmit=PIN_C6,rcv=PIN_C7
#byte OSCCON=getenv("SFR:OSCCON")
#bit PLLEN=getenv("BIT:PLLEN")
|
menu.h
Code: |
#ifndef MENU_H
#define MENU_H
// Typedef a function pointer.
typedef void (*fPtr)(void);
struct MENUOpt{
char menuType;
char menuText[30];
int32 menuSelection; //points to a submenu else is NULL
fPtr functionSelectionPtr; //points to a command or function to execute else is NULL
};
//Menu types
#define MENU_END 0
#define MENU_FUNCTION 1
#define MENU_SUBMENU 2
#define MENU_BACKSUBMENU 3
#define MENU_MAIN 4
extern ROM struct MENUOpt mainMenu[];
extern ROM struct MENUOpt subMenu[];
#endif
|
menu.c
Code: |
#include "menu.h"
#include <stdio.h>
ROM struct MENUOpt *currentMenu;
struct MENUOpt ramMenu;
ROM struct MENUOpt subMenu[]={
{MENU_BACKSUBMENU,"",mainMenu,NULL},
{MENU_SUBMENU,"SubElement 1 ",NULL,NULL},
{MENU_SUBMENU,"SubElement 2 ",NULL,NULL},
{MENU_SUBMENU,"SubElement 3 ",NULL,NULL},
{MENU_SUBMENU,"SubElement 4 ",NULL,NULL},
{MENU_END,"",NULL,NULL}
};
ROM struct MENUOpt mainMenu[]={
{MENU_MAIN,"",NULL,NULL},
{MENU_SUBMENU,"Element 1 ",subMenu,NULL},
{MENU_SUBMENU,"Element 2 ",NULL,NULL},
{MENU_SUBMENU,"Element 3 ",NULL,NULL},
{MENU_SUBMENU,"Element 4 ",NULL,NULL},
{MENU_END,"",NULL,NULL}
};
|
main.c
Code: |
#include "config.c"
#include "menu.c"
void main(void)
{
OSCCON = 0x74; //0b01110100 - 16MHz Internal oscillator
PLLEN = TRUE;
printf("Init\r\n");
currentMenu = mainMenu;
printf("currentMenu - mainMenu %Lu\r\n", currentMenu);
printf("mainMenu %Lu\r\n", mainMenu);
printf("&mainMenu[0] %Lu\r\n", &mainMenu[0]);
ramMenu = currentMenu[1]; // loading MENU_SUBMENU,"Element 1 ",subMenu,NULL
printf("subMenu from mainMenu %Lu\r\n", ramMenu.menuSelection); //submenu address
printf("subMenu %Lu\r\n", subMenu);
printf("&subMenu[0] %Lu\r\n", &subMenu[0]);
printf("subMenu Text: %s\r\n", ramMenu.menuText); //we are in submenu
//load submenu into current menu
currentMenu = ramMenu.menuSelection;
ramMenu = currentMenu[0]; //loading {MENU_BACKSUBMENU,"",mainMenu,NULL}
printf("currentMenu - subMenu %Lu\r\n", currentMenu);
printf("mainMenu from subMenu %Lu\r\n", ramMenu.menuSelection); //this fails
while(TRUE){
}
}
|
thank you for your help.
Regards
Last edited by darkrush on Thu Nov 07, 2013 8:53 am; edited 3 times in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Nov 06, 2013 8:29 pm |
|
|
In your first post you had this:
Quote: | typedef struct{
char menuType;
char menuText[30];
int32 menuSelection; //address to a submenu else is NULL
fPtr functionSelectionPtr; //points to a command or function to execute else is NULL
}MENU; |
But in your next post, you removed the typedef and changed it to "MENUStr":
Quote: |
struct MENUStr{
char menuType;
char menuText[30];
int32 menuSelection; //points to a submenu else is NULL
fPtr functionSelectionPtr; //points to a command or function to execute else is NULL
};
|
But farther down in the code, you declare an array of datatype "MENU"
but that type is never declared.
Quote: |
ROM MENU subMenu[]={
{MENU_BACKSUBMENU,"",mainMenu,NULL},
{MENU_SUBMENU,"SubElement 1 ",NULL,NULL},
{MENU_SUBMENU,"SubElement 2 ",NULL,NULL},
{MENU_SUBMENU,"SubElement 3 ",NULL,NULL},
{MENU_SUBMENU,"SubElement 4 ",NULL,NULL},
{MENU_END,"",NULL,NULL}
};
|
In other words, it doesn't compile.
Before we go any further, read dyeatman's comment in this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=37284
Also read Ttelmah's comments in this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=33017 |
|
|
darkrush
Joined: 29 Sep 2011 Posts: 18 Location: Colombia
|
|
Posted: Wed Nov 06, 2013 9:48 pm |
|
|
Thank you for your reply PCM programmer.
I edited the post, I have done many tests and was trying to put an small functional code that I made those mistakes.
I was looking at the links and understood that the problem I'm facing is this:
- I don't need to forward declare an struct, rather forward declare variable created with the typedef struct that is defined.
- The struct has an element (menuSelection) that has the address of the MENU it points to. I tried using char* and a MENU* but the number it returned was a 16bit one and the real address is greater than that (129424 in the example in the first post), so I used an int32 and it worked just fine.
- However, it doesn't work well when I overload the menus. In the code I have mainMenu and subMenu. An item of mainMenu points to subMenu and subMenu points back to mainMenu, but I can't point to a MENU that I haven't defined yet, so I used "extern" but as a result, the address of the overloaded menu (the one that has not been declared yet) is not loaded properly into menuSelection as I put it in the first post.
Regards |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Nov 07, 2013 12:10 am |
|
|
I don't know, I still can't get it to compile. It gives many errors.
So I can't investigate the address problem. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Thu Nov 07, 2013 4:06 am |
|
|
PICs have a Harvard architecture with completely separate program and data memories with their own, different and incompatible, widths and address spaces. This imposes some important limitations on some data structures, especially data that is held in ROM, i.e. in program memory.
Essentially all addresses to program memory, including to constants marked as ROM, have to be resolvable at compile time. Also you cannot have fully functional function pointers. So, constructing a menu table in the way you're trying to, especially one with function pointers, while tempting and quite normal in many Cs, is not going to work in CCS C, and probably not on any PIC C. Expecting that menu in RAM is going to be compatible with menus declared in ROM is asking for trouble. What you are trying to do will work with one flat address space for code and data, but won't work on a PIC or other processor, including some DSPs, with separate memory spaces.
Instead of using pointers to menu items, you are probably going to have to use indexes into the menu item arrays. Instead of function pointers, you're probably going to have to use selectors for a switch that calls the relevant functions. |
|
|
darkrush
Joined: 29 Sep 2011 Posts: 18 Location: Colombia
|
|
Posted: Thu Nov 07, 2013 9:02 am |
|
|
@PCM programmer, I apologize, I compiled pointing to another project, I edited, compiled and tested again, it should work now.
@RF_Developer It's true, I was figuring that ROM and RAM addressing doesn't work well if it's not in a single memory space and decided to use an array with the indexes to the menu items.
Thank you for your replies.
Regards |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|