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

Pointer to struct always null?

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



Joined: 14 May 2004
Posts: 330

View user's profile Send private message

Pointer to struct always null?
PostPosted: Sat Jun 05, 2010 1:26 pm     Reply with quote

Hello all,

I am trying to init a ram struct with some pointers to ram, like:
Code:

struct {
void *data[10];
} test = { &onestruct, &otherstruct, 0x300... };

With a few pointers to other structs in ram.

What happen is that data[10] is initialized to NULL and compilation is successful. It does work for functions and constants (0x300 gets loaded correctly). It seems that CCS doesn´t know about its memory map.

Compiler version is 4.107 PIC 18f4680... ram usage is over 70% but it does not help if I place the struct at different addresses.

I can get the addresses from the sym file. Do you know how to do it and avoid to manually allocate each struct at fixed address and filling the table by hand?

Thank you.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Jun 05, 2010 3:23 pm     Reply with quote

You didn't provide a test program, so I made one. It works with the
program shown below. I ran it in MPLAB simulator with vs. 4.106.
It displays this output:
Quote:

onestruct address = 0005
otherstruct address = 0008
0x300 address = 0300


The .SYM file shows the structures are at those addresses:
Quote:

000 @SCRATCH
001 @SCRATCH
001 _RETURN_
002 @SCRATCH
003 @SCRATCH
004 rs232_errors
005-007 onestruct
008-00D otherstruct
00E-021 test
022-023 main.data


Here is the test program:
Code:

#include <18F4680.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

struct
{
int8 a;
int8 b;
int8 c;
}onestruct;

struct
{
int16 x;
int16 y;
int16 z;
}otherstruct;

struct{
void *data[10];
}test = {&onestruct, &otherstruct, 0x300};

//====================================
void main(void)
{
int16 data;

printf("onestruct address = %lx\r", test.data[0]);
printf("otherstruct address = %lx\r", test.data[1]);
printf("0x300 address = %lx\r", test.data[2]);

while(1);
}
 
future



Joined: 14 May 2004
Posts: 330

View user's profile Send private message

PostPosted: Sat Jun 05, 2010 3:53 pm     Reply with quote

Ok, here it is.

Code:
#include <18f4680.h>
#define CLOCKSPEED 40000000
#fuses    H4, PUT, BROWNOUT, BORV46, NOPBADEN, NOMCLR, NOLVP, NOWRT, NOWDT
#zero_ram
#opt      9
#use      delay(clock=CLOCKSPEED, RESTART_WDT)
#case

void _AA (void *arg, char *name) { while (1); }
void _BB (void *arg, char *name) { while (1); }

typedef void (*fptr)(void *arg, char *name);

typedef struct menu_entry_s {
    fptr select;
    char name[20];
    void *value;
} menu_entry_t;

typedef struct {
   menu_entry_t entry[10];
} menu_table_t;

typedef struct menu_s {
   menu_table_t  *menu_data;
   struct menu_s *previous;
   char          top_entry;
   char          current_entry;
   char          screen_entries;
} menu_t;

menu_table_t second_menu_table = {
   { { &_AA, "AA\n", 0xAA },
     { &_BB, "BB\n", 0x55 },
     {    0, "CC\n", 0x5A } }
};
menu_t second_menu = { &second_menu_table };

menu_table_t main_menu_table = {
   { { 0, "C0\n", &second_menu },
     { 0, "T0\n", 0xAA         } }
};
menu_t main_menu = { &main_menu_table };

void main (void) {
   while (1);
}


You will see that &second_menu is NULL.

Everything is in ram at the moment... I tried using the rom qualifier but it always loads FSR and try to get from ram.

I want this to be a menu system, menu_table_t goes into flash and menu_t in ram. This comes later.
future



Joined: 14 May 2004
Posts: 330

View user's profile Send private message

PostPosted: Sun Jun 06, 2010 12:49 pm     Reply with quote

Had a little progress...

I declared char name[20] and filled -> "C0 \n", had to fill with spaces until all 20 positions are used.

After compilation &second_menu = 0x3C1, but the compiler puts 0x3144 in the structure.

I can read the value 0x3144 correctly. If I put 0x3C1 in place of &second_menu all works fine.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jun 06, 2010 12:57 pm     Reply with quote

I couldn't start working on it until just now. You saved me some work. Smile
You did the same thing I would have done - experiment with giving the
compiler what it wants, in order to produce correct output. With CCS
it tends to want things more well defined.
future



Joined: 14 May 2004
Posts: 330

View user's profile Send private message

PostPosted: Sun Jun 06, 2010 1:03 pm     Reply with quote

It works better giving it what it wants... but not fully all right. The compiler still points to the wrong place.

Really weird, printf("%Lx", &second_menu); is perfect...

I did not tell you in my last post that I am declaring the structure as rom struct and inspecting the program memory window.


Last edited by future on Sun Jun 06, 2010 1:10 pm; edited 1 time in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jun 06, 2010 1:04 pm     Reply with quote

OK, I was too hopeful. I'll look at it now.
future



Joined: 14 May 2004
Posts: 330

View user's profile Send private message

PostPosted: Sun Jun 06, 2010 1:34 pm     Reply with quote

Here is the rom test program:

Code:
#include <18f4680.h>
#define CLOCKSPEED 40000000
#fuses    H4, PUT, BROWNOUT, BORV46, NOPBADEN, NOMCLR, NOLVP, NOWRT, NOWDT
#zero_ram
#opt      9
#use      delay(clock=CLOCKSPEED, RESTART_WDT)
#case
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

void _AA (void) { while (1); }
void _BB (void) { while (1); }

typedef void (*fptr)(void);

typedef struct menu_entry_s {
    fptr select;
    char name[10];
    long *value;
} menu_entry_t;

typedef struct {
   menu_entry_t entry[10];
} menu_table_t;

typedef struct menu_s {
   menu_table_t rom *menu_data;
} menu_t;

rom menu_table_t second_menu_table = {
   { { &_AA, "AA\n      ", 0 },
     { &_BB, "BB\n      ", 0 },
     {    0, "CC\n      ", 0 } }
};
menu_t second_menu = { &second_menu_table };

rom menu_table_t main_menu_table = {
   { { 0, "C0\n      ", &second_menu },
     { 0, "T0\n      ", 0xABCD       } }
};
menu_t main_menu = { &main_menu_table };

void main (void) {
    menu_table_t rom *ptr;

    ptr = main_menu.menu_data;

    printf("%Lx\n", &second_menu);              // 0x005 ok
    printf("%Lx\n", (long)ptr->entry[0].value); // 0x136 wrong, but is really in flash
    printf("\n");
    printf("%Lx\n", (long)ptr->entry[1].value); // reads 0xABCD
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jun 06, 2010 2:38 pm     Reply with quote

If I remove all the 'rom' keywords, then it works OK. Do you need
the 'rom' prefix ? What about 'const' ?

Here's the output without 'rom':
Quote:

0091
0091

abcd

The symbol table is:
Quote:

005-090 second_menu_table
091-092 second_menu
093-11E main_menu_table
11F-120 main_menu
121-122 main.ptr
future



Joined: 14 May 2004
Posts: 330

View user's profile Send private message

PostPosted: Sun Jun 06, 2010 2:48 pm     Reply with quote

I think so, how else can I browse 30 different screens? I'd have to hack and switch a lot to make it work.

I could do the inverse, a const table with one pointer to ram space...
future



Joined: 14 May 2004
Posts: 330

View user's profile Send private message

PostPosted: Mon Jun 07, 2010 11:47 am     Reply with quote

I´ve learned from this experience that CCS v4107 is a great tool to code in C like we do in asm, simple and direct stuff.

It can not be used to abstract complex tasks as it behaves very badly with ram and rom pointers.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jun 07, 2010 12:04 pm     Reply with quote

I worked on it a bit more, and I tried to use special methods in the manual such as using __ADDRESS__ as a type qualifier. But I couldn't make it work so far. It might be possible to get it to work with more
experimentation, but to be truthful I don't want to spend more time on
it right now.
sjb



Joined: 13 Apr 2010
Posts: 34
Location: UK

View user's profile Send private message

PostPosted: Mon Jun 07, 2010 12:07 pm     Reply with quote

future wrote:
It can not be used to abstract complex tasks as it behaves very badly with ram and rom pointers.

That's my thoughts too. It seems to make inconsistent choices and I'm not happy enough with its behavior to use any complexity with production code.

I'm sorry that I can't add more, but I'm struggling to find a way to get some code to work, and it looks very much like yours in many ways.
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