|
|
View previous topic :: View next topic |
Author |
Message |
future
Joined: 14 May 2004 Posts: 330
|
Pointer to struct always null? |
Posted: Sat Jun 05, 2010 1:26 pm |
|
|
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
|
|
Posted: Sat Jun 05, 2010 3:23 pm |
|
|
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
|
|
Posted: Sat Jun 05, 2010 3:53 pm |
|
|
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
|
|
Posted: Sun Jun 06, 2010 12:49 pm |
|
|
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
|
|
Posted: Sun Jun 06, 2010 12:57 pm |
|
|
I couldn't start working on it until just now. You saved me some work.
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
|
|
Posted: Sun Jun 06, 2010 1:03 pm |
|
|
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
|
|
Posted: Sun Jun 06, 2010 1:04 pm |
|
|
OK, I was too hopeful. I'll look at it now. |
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Sun Jun 06, 2010 1:34 pm |
|
|
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
|
|
Posted: Sun Jun 06, 2010 2:38 pm |
|
|
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':
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
|
|
Posted: Sun Jun 06, 2010 2:48 pm |
|
|
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
|
|
Posted: Mon Jun 07, 2010 11:47 am |
|
|
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
|
|
Posted: Mon Jun 07, 2010 12:04 pm |
|
|
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
|
|
Posted: Mon Jun 07, 2010 12:07 pm |
|
|
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. |
|
|
|
|
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
|