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 support@ccsinfo.com

ROM structs with self-referencing elements

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



Joined: 13 Jul 2018
Posts: 23

View user's profile Send private message

ROM structs with self-referencing elements
PostPosted: Wed Oct 06, 2021 8:31 am     Reply with quote

I am trying to store some menus in a tree:

Code:

#device CONST=ROM

typedef struct menu {
    uint8_t id;
    char const *text;
    struct menu *children[MAX_CHILDREN];
} menu_t;

which I then use like:

Code:

menu_t submenu = {
    ...
};

const char main_menu_text[MAX_MENU_TEXT] = "Main Menu";
menu_t main_menu = {
    MAIN_MENU_ID,
    main_menu_text,
    {
        &submenu
    }
};

This is working fine.

However my entire menu is constant and so I would like to store the whole thing in ROM, rather than just the text.
What I want to do is change all my menu_t to const menu_t. This compiles but fails when attempting to traverse submenus. I think I need to adjust my struct to store children as pointers to ROM.
This is where I run into problems. If I adjust my struct to:

Code:

typedef struct menu {
    uint8_t id;
    char const *name;
    struct menu const *children[MAX_CHILDREN];
} menu_t;

This no longer compiles, giving me the error

Quote:
Error#43 Expecting a declaration

From other tests, the pattern struct foo const *bar seems to work. It is only when self referencing that it fails to compile.
I have also tried manually calling read_program_memory() to access the submenus, but the child pointers contain RAM addresses (though I'm not sure what they're pointing at) and this fails.
Is it possible to do what I'm attempting here (effectively storing tree nodes in ROM)?

I'm using compiler version 5.101 on a dsPIC33.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Wed Oct 06, 2021 9:15 am     Reply with quote

Certain types of pointer references from inside structures have always had
issues with CCS. I've in the past found that it is actually much safer to
not declare the pointers as being to a structure, but instead as just a large
enough integer. Then explicitly cast the value to being a pointer of the
required type when you use it.
SamMeredith



Joined: 13 Jul 2018
Posts: 23

View user's profile Send private message

PostPosted: Wed Oct 06, 2021 10:07 am     Reply with quote

Thanks, that works.

Code:

typedef struct menu {
    uint8_t id;
    char const *text;
    //struct menu const *children[MAX_CHILDREN];
    int32_t const *children[MAX_CHILDREN];
} menu_t;

and then implicitly casting

Code:

menu_t const *child = menu->children[i];

lets me use the structure the way I wanted.
I couldn't explicitly cast to menu_t const * (compiler error) and casting to menu_t * would truncate the address and break things.
I think this also explains what the non-const struct pointers were doing, truncating the ROM address, and hence why read_program_memory() didn't work.

Makes me wonder what the difference is between the int32_t const * member and struct menu const * member.
Probably beyond my knowledge of the compiler, but I'll trawl through the .lst file tomorrow and see if I can make any sense of it.


Last edited by SamMeredith on Wed Oct 06, 2021 10:24 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Wed Oct 06, 2021 10:23 am     Reply with quote

Key thing in the PIC, is to understand that the ROM and RAM have
two separate address spaces. This makes 'pointers' to ROM, quite
difficult to implement. The compiler tricks that allow this to happen seem
to get confused when the item is inside things like structures, while
the explicit cast forces the correct access to be done.
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