CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

rom struct forward declaration

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
darkrush



Joined: 29 Sep 2011
Posts: 18
Location: Colombia

View user's profile Send private message

rom struct forward declaration
PostPosted: Wed Nov 06, 2013 10:52 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Nov 06, 2013 4:38 pm     Reply with quote

Post a test program instead of code fragments.
darkrush



Joined: 29 Sep 2011
Posts: 18
Location: Colombia

View user's profile Send private message

PostPosted: Wed Nov 06, 2013 6:09 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Nov 06, 2013 8:29 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Nov 06, 2013 9:48 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Nov 07, 2013 12:10 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Nov 07, 2013 4:06 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Nov 07, 2013 9:02 am     Reply with quote

@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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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