Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Mikroc Illegal pointer conversion - Need help

Status
Not open for further replies.

markocrni

Newbie level 4
Joined
Oct 11, 2008
Messages
5
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,307
I receive an Illegal pointer conversion error, with this lines Glcd_Write_Text(menu[from].text, 10, line_cnt, 1);. Any sugestions? THX.

Code:
void start();
unsigned char selected = 0;

// glcd pinout settings
char GLCD_DataPort at PORTD;

sbit GLCD_CS1 at RB0_bit;
sbit GLCD_CS2 at RB1_bit;
sbit GLCD_RS  at RB2_bit;
sbit GLCD_RW  at RB3_bit;
sbit GLCD_EN at RB4_bit;
sbit GLCD_RST at RB5_bit;

sbit GLCD_CS1_Direction at TRISB0_bit;
sbit GLCD_CS2_Direction at TRISB1_bit;
sbit GLCD_RS_Direction at TRISB2_bit;
sbit GLCD_RW_Direction at TRISB3_bit;
sbit GLCD_EN_Direction at TRISB4_bit;
sbit GLCD_RST_Direction at TRISB5_bit;

typedef const struct MenuStructure{
    const char *text;
    unsigned char num_menupoints;
    unsigned char up;
    unsigned char down;
    unsigned char enter;
    void (*fp)(void);
}MenuEntry;

const char menu_000[] = "[Osnovni meni]";         //0
const char menu_001[] = "Opcija 1";               //1
const char menu_002[] = "Opcija 2";               //2
const char menu_003[] = "Opcija 3";               //3
const char menu_004[] = "Opcija 4";               //4
const char menu_005[] = "Opcija 5";               //5
const char menu_006[] = "Opcija 6";               //6
const char menu_007[] = "Opcija 7";               //7
const char menu_008[] = "Opcija 8";               //8
const char menu_009[] = "START";                  //9

const char menu_100[] = "[Opcija 1]";             //10
const char menu_101[] = "Sub opcija1";            //11
const char menu_102[] = "Sub opcija2";            //12
const char menu_103[] = "Sub opcija3";            //13
const char menu_104[] = "Sub opcija4";            //14
const char menu_105[] = "Sub opcija5";            //15
const char menu_106[] = "nazad";                  //16

MenuEntry menu[] = {
    {menu_000, 10, 0, 0, 0, 0},
    {menu_001, 10, 1, 2, 11, 0},
    {menu_002, 10, 1, 3, 2, 0},
    {menu_003, 10, 2, 4, 3, 0},
    {menu_004, 10, 3, 5, 4, 0},
    {menu_005, 10, 4, 6, 5, 0},
    {menu_006, 10, 5, 7, 6, 0},
    {menu_007, 10, 6, 8, 7, 0},
    {menu_008, 10, 7, 9, 8, 0},
    {menu_009, 10, 8, 9, 9, start},
    
    {menu_100, 7, 0, 0, 0, 0},
    {menu_101, 7, 11, 12, 11, 0},
    {menu_102, 7, 11, 13, 12, 0},
    {menu_103, 7, 12, 14, 13, 0},
    {menu_104, 7, 13, 15, 14, 0},
    {menu_105, 7, 14, 16, 15, 0},
    {menu_106, 7, 15, 16, 1, 0},
};

void show_menu(void){
    unsigned char line_cnt = 0;
    unsigned char from = 0;
    unsigned char till = 0;
    unsigned char tmp = 0;
    
    while(till <= selected){
         till += menu[till].num_menupoints;
    }
    from = till - menu[selected].num_menupoints;
    till--;
    
    tmp = from;
    
    if(selected>=(from+2) && selected<=(till-1)){
         from = selected - 2;
         till = from + 3;
         for(from;from<=till;from++){
              Glcd_Write_Text(menu[from].text, 10, line_cnt, 1);
              line_cnt++;
         }
         Glcd_Write_Text(">", 0, 2, 1);
    }
    else{
         if(selected<(from+2)){
              till = from +3;
              for(from;from<=till;from++){
                    Glcd_Write_Text(menu[from].text, 10, line_cnt, 1);
                    line_cnt++;
              } 
              Glcd_Write_Text(">", 0, 2, 1);
         }

         if(selected==till){
              from = till - 3;
              for(from;from<=till;from++){
                    Glcd_Write_Text(menu[from].text, 10, line_cnt, 1);
                    line_cnt++;
              }
              Glcd_Write_Text(">", 0, 3, 1);
         }
    }
}

void browse_menu(void){
     do{
          show_menu();
          if(Button(&PORTA, 0, 5, 1)){
               selected = menu[selected].up;
          }while(RA0_bit);
          if(Button(&PORTA, 3, 5, 1)){
               selected = menu[selected].down;
          }while(RA0_bit);
          if(Button(&PORTA, 2, 5, 1)){
               if(menu[selected].fp != 0){
                     menu[selected].fp();
               }
               selected = menu[selected].enter;
          }while(RA0_bit);
     }while(1);
}

void start(void){
Glcd_Write_Text("Start working", 0, 0, 1);
}

void main(){
  ADCON1 = 0x0F;
  Glcd_Init();                                             // Initialize GLCD
  browse_menu();

}
 

I receive an Illegal pointer conversion error, with this lines Glcd_Write_Text(menu[from].text, 10, line_cnt, 1);. Any sugestions? THX.

Code:
void start();
unsigned char selected = 0;

// glcd pinout settings
char GLCD_DataPort at PORTD;

sbit GLCD_CS1 at RB0_bit;
sbit GLCD_CS2 at RB1_bit;
sbit GLCD_RS  at RB2_bit;
sbit GLCD_RW  at RB3_bit;
sbit GLCD_EN at RB4_bit;
sbit GLCD_RST at RB5_bit;

sbit GLCD_CS1_Direction at TRISB0_bit;
sbit GLCD_CS2_Direction at TRISB1_bit;
sbit GLCD_RS_Direction at TRISB2_bit;
sbit GLCD_RW_Direction at TRISB3_bit;
sbit GLCD_EN_Direction at TRISB4_bit;
sbit GLCD_RST_Direction at TRISB5_bit;

typedef const struct MenuStructure{
    const char *text;
    unsigned char num_menupoints;
    unsigned char up;
    unsigned char down;
    unsigned char enter;
    void (*fp)(void);
}MenuEntry;

const char menu_000[] = "[Osnovni meni]";         //0
const char menu_001[] = "Opcija 1";               //1
const char menu_002[] = "Opcija 2";               //2
const char menu_003[] = "Opcija 3";               //3
const char menu_004[] = "Opcija 4";               //4
const char menu_005[] = "Opcija 5";               //5
const char menu_006[] = "Opcija 6";               //6
const char menu_007[] = "Opcija 7";               //7
const char menu_008[] = "Opcija 8";               //8
const char menu_009[] = "START";                  //9

const char menu_100[] = "[Opcija 1]";             //10
const char menu_101[] = "Sub opcija1";            //11
const char menu_102[] = "Sub opcija2";            //12
const char menu_103[] = "Sub opcija3";            //13
const char menu_104[] = "Sub opcija4";            //14
const char menu_105[] = "Sub opcija5";            //15
const char menu_106[] = "nazad";                  //16

MenuEntry menu[] = {
    {menu_000, 10, 0, 0, 0, 0},
    {menu_001, 10, 1, 2, 11, 0},
    {menu_002, 10, 1, 3, 2, 0},
    {menu_003, 10, 2, 4, 3, 0},
    {menu_004, 10, 3, 5, 4, 0},
    {menu_005, 10, 4, 6, 5, 0},
    {menu_006, 10, 5, 7, 6, 0},
    {menu_007, 10, 6, 8, 7, 0},
    {menu_008, 10, 7, 9, 8, 0},
    {menu_009, 10, 8, 9, 9, start},
    
    {menu_100, 7, 0, 0, 0, 0},
    {menu_101, 7, 11, 12, 11, 0},
    {menu_102, 7, 11, 13, 12, 0},
    {menu_103, 7, 12, 14, 13, 0},
    {menu_104, 7, 13, 15, 14, 0},
    {menu_105, 7, 14, 16, 15, 0},
    {menu_106, 7, 15, 16, 1, 0},
};

void show_menu(void){
    unsigned char line_cnt = 0;
    unsigned char from = 0;
    unsigned char till = 0;
    unsigned char tmp = 0;
    
    while(till <= selected){
         till += menu[till].num_menupoints;
    }
    from = till - menu[selected].num_menupoints;
    till--;
    
    tmp = from;
    
    if(selected>=(from+2) && selected<=(till-1)){
         from = selected - 2;
         till = from + 3;
         for(from;from<=till;from++){
              Glcd_Write_Text(menu[from].text, 10, line_cnt, 1);
              line_cnt++;
         }
         Glcd_Write_Text(">", 0, 2, 1);
    }
    else{
         if(selected<(from+2)){
              till = from +3;
              for(from;from<=till;from++){
                    Glcd_Write_Text(menu[from].text, 10, line_cnt, 1);
                    line_cnt++;
              } 
              Glcd_Write_Text(">", 0, 2, 1);
         }

         if(selected==till){
              from = till - 3;
              for(from;from<=till;from++){
                    Glcd_Write_Text(menu[from].text, 10, line_cnt, 1);
                    line_cnt++;
              }
              Glcd_Write_Text(">", 0, 3, 1);
         }
    }
}

void browse_menu(void){
     do{
          show_menu();
          if(Button(&PORTA, 0, 5, 1)){
               selected = menu[selected].up;
          }while(RA0_bit);
          if(Button(&PORTA, 3, 5, 1)){
               selected = menu[selected].down;
          }while(RA0_bit);
          if(Button(&PORTA, 2, 5, 1)){
               if(menu[selected].fp != 0){
                     menu[selected].fp();
               }
               selected = menu[selected].enter;
          }while(RA0_bit);
     }while(1);
}

void start(void){
Glcd_Write_Text("Start working", 0, 0, 1);
}

void main(){
  ADCON1 = 0x0F;
  Glcd_Init();                                             // Initialize GLCD
  browse_menu();

}

You can only do like
Code:
 Glcd_Write_Text(menu_000[], 10, line_cnt, 1);

If you do like this
Code:
 Glcd_Write_Text(menu[from].text, 10, line_cnt, 1);
menu[from] if from = 0 means {menu_000, 10, 0, 0,0,0} what does {menu_000, 10, 0, 0,0,0}.text mean? you are not passing a string.
 

If you do like this
Code:
 Glcd_Write_Text(menu[from].text, 10, line_cnt, 1);
menu[from] if from = 0 means {menu_000, 10, 0, 0,0,0} what does {menu_000, 10, 0, 0,0,0}.text mean? you are not passing a string.

markocrni is attempting to pass a pointer to a string literal which is what the routine requires.

Reference: MikroC Pro for PIC User Manual, Section: GRAPHIC LCD LIBRARY, Page: 337

Prototype - Glcd_Write_Text
Code:
void Glcd_Write_Text([COLOR="#FF0000"]char *text[/COLOR], unsigned short x_pos, unsigned short page_num, unsigned short color);

@markocrni

Perhaps the declaration qualifier as const is the source of the issue.

Have you attempted to explicitly cast the parameter as char *, instead of the implicit const char *?

Perhaps try:
Code:
Glcd_Write_Text([COLOR="#FF0000"](char *)[/COLOR](menu[from].text), 10, line_cnt, 1);


Out of curiosity, what is the specific PIC you are coding for?

Maybe I'll see if I can compile it here.

BigDog
 
  • Like
Reactions: FvM

    FvM

    Points: 2
    Helpful Answer Positive Rating
I'm not using mikroC, reviewing what's written in the manual related to string constants seems to suggest me that I'm not doing wrong ...

In fact handling of string constants with PIC or other processors that don't allow to access code as data requires some special prerequisites of a compiler. Surely mikroC does it too, but the manual seems to perfectly hide the problem. But unless the compiler copies all constant strings to RAM at startup, some restrictions of string handling and particularly string pointers apply. Because I don't know how mikroC does it, I can't give a solution. A typical scenario (e.g. found with CCS C) is that some basic string functions have built-in support for constant strings and others don't.

You may need to copy constant strings to RAM before passing them to GLCD_write_text. But you should verify first, that the constant record arrays (presuming they are place in code space as well) are working correctly.
 
markocrni is attempting to pass a pointer to a string literal which is what the routine requires.


Perhaps try:
Code:
Glcd_Write_Text([COLOR="#FF0000"](char *)[/COLOR](menu[from].text), 10, line_cnt, 1);


Out of curiosity, what is the specific PIC you are coding for?

Maybe I'll see if I can compile it here.

BigDog

THX BigDog,
I've tried that before I posted problem here.
PICs are 18F4520 and 18F8722.
 

In an optimistic view, mikroC is clearly keeping track of const char * objects and pays attention that they aren't wrongly assigned in place of char *, because dereference would fail.

Then strcpy() will hopefully have support for const char * so you can copy the menu items to a temporary string variable before passing it to GLCD_write_text(). I'm still presuming that const struct MenuStructure works in general, although it's not evident in my view.

P.S.: It's quite interesting how the const char * problem is handled by C18 and Microchip application libraries. They distinguish RAM and ROM character types through all string functions.
 
Last edited:

First let me say that I avoid using the MikroC Compiler like the plague.

When troubleshooting an issue such as this, I never know whether I'm battling an undocumented C extension, intentional noncompliance with C89 and C99 or just one of the many idiosyncrasies of MikroC.

--- that being said, I have managed to verify that this particular issue is known and due, as FvM expressed, to the compiler and library routines limited ability to manage FLASH storage access during runtime.

I verified this fact by removing the type qualifier const from the struct declaration, at which point the code compiled without error. Of course the main drawback is the excessive use of data storage (RAM) resources.

Examples demonstrating a similar issue, were remedied by the use of the FLASH library routines and essentially copying the string literal stored in FLASH to RAM before passing it to a library routine.

The following is a possible workaround, somewhat optimized, version of your code which utilizes the FLASH_Read_N_Bytes() library routine. Staying true to form, MikroC does not offer the FLASH_Read_N_Bytes() for the PIC16F series and not knowing whether you were utilizing a PIC16F or PIC18F in your design, I wrote my own routine for use with the PIC16F series. You'll find it commented out as the compiler does offer the routine for the PIC18F series.

There is really no need to create pointers for each of the messages in advance of defining/initializing the struct array, therefore I removed that section of code and incorporated the string literals into the initialization.

The code compiled without error, only a few pesky warning, sixteen to be exact, due to the initialization of the function pointers to null. Whether or not the code performs as expected is another story, please let me know.

From the resource utilization report, only 77 bytes of RAM used, I would have to say the constant array of structs was successfully loaded into FLASH. A similar report was generated using the PIC16F877A.

Resources used:
0 1144 Used RAM (bytes): 77 (5%) Free RAM (bytes): 1438 (95%) Used RAM (bytes): 77 (5%) Free RAM (bytes): 1438 (95%)
0 1144 Used ROM (bytes): 3173 (10%) Free ROM (bytes): 29595 (90%) Used ROM (bytes): 3173 (10%) Free ROM (bytes): 29595 (90%)



Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
void start();
unsigned char selected = 0;
 
// glcd pinout settings
char GLCD_DataPort at PORTD;
 
sbit GLCD_CS1 at RB0_bit;
sbit GLCD_CS2 at RB1_bit;
sbit GLCD_RS  at RB2_bit;
sbit GLCD_RW  at RB3_bit;
sbit GLCD_EN at RB4_bit;
sbit GLCD_RST at RB5_bit;
 
sbit GLCD_CS1_Direction at TRISB0_bit;
sbit GLCD_CS2_Direction at TRISB1_bit;
sbit GLCD_RS_Direction at TRISB2_bit;
sbit GLCD_RW_Direction at TRISB3_bit;
sbit GLCD_EN_Direction at TRISB4_bit;
sbit GLCD_RST_Direction at TRISB5_bit;
 
typedef struct MenuStructure{
    char text[20];
    unsigned char num_menupoints;
    unsigned char up;
    unsigned char down;
    unsigned char enter;
    void (*fp)(void);
}MenuEntry;
 
const Menu Entry menu[] = {
    {"[Osnovni meni]", 10, 0, 0, 0, 0},
    {"Opcija 1", 10, 1, 2, 11, 0},
    {"Opcija 2", 10, 1, 3, 2, 0},
    {"Opcija 3", 10, 2, 4, 3, 0},
    {"Opcija 4", 10, 3, 5, 4, 0},
    {"Opcija 5", 10, 4, 6, 5, 0},
    {"Opcija 6", 10, 5, 7, 6, 0},
    {"Opcija 7", 10, 6, 8, 7, 0},
    {"Opcija 8", 10, 7, 9, 8, 0},
    {"START", 10, 8, 9, 9, start},
 
    {"[Opcija 1]", 7, 0, 0, 0, 0},
    {"Sub opcija1", 7, 11, 12, 11, 0},
    {"Sub opcija2", 7, 11, 13, 12, 0},
    {"Sub opcija3", 7, 12, 14, 13, 0},
    {"Sub opcija4", 7, 13, 15, 14, 0},
    {"Sub opcija5", 7, 14, 16, 15, 0},
    {"nazad", 7, 15, 16, 1, 0}
};
 
/*
void FLASH_Read_N_Bytes(unsigned address, char* buffer, unsigned int N)
{    
     int i;
     for( i=0; i<N; i++)
     {
         buffer[i] = (char)FLASH_Read(address);
     }
}
*/
 
 
 
 
void show_menu(void){
    unsigned char line_cnt = 0;
    unsigned char from = 0;
    unsigned char till = 0;
 //   unsigned char tmp = 0;
    char message[20];
 
    while(till <= selected){
         till += menu[till].num_menupoints;
    }
    from = till - menu[selected].num_menupoints;
    till--;
 
 //   tmp = from;
 
    if(selected>=(from+2) && selected<=(till-1)){
         from = selected - 2;
         till = from + 3;
         for(from;from<=till;from++){
              FLASH_Read_N_Bytes((long)(menu[from].text), message, 20);
              Glcd_Write_Text(message, 10, line_cnt, 1);
              line_cnt++;
         }
         Glcd_Write_Text(">", 0, 2, 1);
    }
    else{
         if(selected<(from+2)){
              till = from +3;
              for(from;from<=till;from++){
                    FLASH_Read_N_Bytes((long)(menu[from].text), message, 20);
                    Glcd_Write_Text(message, 10, line_cnt, 1);
                    line_cnt++;
              }
              Glcd_Write_Text(">", 0, 2, 1);
         }
 
         if(selected==till){
              from = till - 3;
              for(from;from<=till;from++){
                    FLASH_Read_N_Bytes((long)(menu[from].text), message, 20);
                    Glcd_Write_Text(message, 10, line_cnt, 1);
                    line_cnt++;
              }
              Glcd_Write_Text(">", 0, 3, 1);
         }
    }
}
 
void browse_menu(void){
     do{
          show_menu();
          if(Button(&PORTA, 0, 5, 1)){
               selected = menu[selected].up;
          }while(RA0_bit);
          if(Button(&PORTA, 3, 5, 1)){
               selected = menu[selected].down;
          }while(RA0_bit);
          if(Button(&PORTA, 2, 5, 1)){
               if(menu[selected].fp != 0){
                     menu[selected].fp();
               }
               selected = menu[selected].enter;
          }while(RA0_bit);
     }while(1);
}
 
void start(void){
Glcd_Write_Text("Start working", 0, 0, 1);
}
 
void main(){
  ADCON1 = 0x0F;
  Glcd_Init();                                             // Initialize GLCD
  browse_menu();
 
}



@FvM - I initially attempted to use the strcpy() routine to copy the string literal to a message buffer, however access to FLASH was also NOT supported by the strcpy() routine. Apparently, use of the FLASH library routines furnished by MikroC or of course the writing of your own routines maybe the only options.

I would also caution you in your optimism concerning MikroC's keeping track of const char * objects and paying attention that to whether or not they are wrongly assigned in place of char *. Out of curiosity I removed the const type qualifier form the menu[] initialization, as expected RAM utilization jumped to 553 bytes (37%), however no compiler errors were thrown even though the FLASH_Read_N_Bytes() routines were being passed RAM addresses instead of FLASH addresses, of course this might be due to the explicit casting to type long.

@markcrni - While I certainly applaud your aggressive coding style, I would strongly suggest you consider migrating to a more professional compiler like the Microchip C18. In my opinion you have clearly out grown the limited support and documentation offered by the MikroC compiler and as your coding techniques continue to advance you will undoubtedly encounter even more challenging issues, due in part to the limitations of the MikroC compiler.


BigDog
 
  • Like
Reactions: FvM

    FvM

    Points: 2
    Helpful Answer Positive Rating
I initially attempted to use the strcpy() routine to copy the string literal to a message buffer, however access to FLASH was also NOT supported by the strcpy() routine. Apparently, use of the FLASH library routines furnished by MikroC or of course the writing of your own routines maybe the only options.

I didn't notice yet the Flash_Read_xx routines. Apparently the mikroC manual completely lacks an understandable chapter about the intended way to work with constant strings.

You'll possibly come to the conclusion that C18 doesn't offer more high level string support than mikroC, but everything is straightforward and well explained. Although there's a certain lack of conceptual clarity, CCS C's constant string support seems to clearly outperform mikroC.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top