Sonsivri
 
*
Welcome, Guest. Please login or register.
Did you miss your activation email?
November 24, 2024, 08:53:08 20:53


Login with username, password and session length


Pages: [1]
Print
Author Topic: ARM GCC Strings in Flash  (Read 8578 times)
0 Members and 1 Guest are viewing this topic.
sam_des
Senior Member
****
Offline Offline

Posts: 256

Thank You
-Given: 128
-Receive: 151


« on: June 06, 2017, 09:26:33 09:26 »

Hello,

I am facing problem using strings/array of pointer to strings in flash with gcc. When optimization are off, everything works fine, but with optimizations set to -s, garbage gets displayed on LCD. I can see that value of pointers to strings being passed are wrong although Map file correctly shows that strings as well as arrays of pointer to strings are in "rodata".

Code:
#define MENU_CONFF_STR_COUNT			(12)

 const char g_strMnuPrev[]    = "[ ]Previous Menu";

static const char g_strMnuConf_F_1[] = "[ ]PWD Enable?";
static const char g_strMnuConf_F_2[] = "[ ]System Type";
static const char g_strMnuConf_F_3[]  = "[ ]Set Yr/Mon";
static const char g_strMnuConf_F_4[]  = "[ ]Set Serial";
static const char g_strMnuConf_F_5[]  = "[ ]Set M1";
static const char g_strMnuConf_F_6[] = "[ ]Set M2";
static const char g_strMnuConf_F_7[] = "[ ]Set IP-FSW";
static const char g_strMnuConf_F_8[] = "[ ]Set IP-P1";
static const char g_strMnuConf_F_9[] = "[ ]Set IP-P2";
static const char g_strMnuConf_F_10[] = "[ ]Set TCON";
static const char g_strMnuConf_F_11[] = "[ ]T Calib";
static const char* const g_a_strMnuConfF_P[MENU_CONFF_STR_COUNT] = {
    g_strMnuConf_F_1, g_strMnuConf_F_2 ,g_strMnuConf_F_3, g_strMnuConf_F_4, g_strMnuConf_F_5,
g_strMnuConf_F_6, g_strMnuConf_F_7, g_strMnuConf_F_8, g_strMnuConf_F_9, g_strMnuConf_F_10,
g_strMnuConf_F_11,
g_strMnuPrev
};

// some code using string using function --> void vLCD_WriteStr_P( const char* pStr_P, INT8U x, INT8U y, BOOL fill );
vLCD_WriteStr_P( (const char*)g_strMnuConf_F_10, 0, LCD_ROW_1, TRUE );

// some code using array of pointer to strings -> INT8U ucHandle_Menu( const char* const* mnu_array, INT8U mnu_count )
    for( ;; ) {
        switch( ucHandle_Menu( &g_a_strMnuConfF_P[0], MENU_CONFF_STR_COUNT ) ) {
.....


Also code works perfectly with Keil.
So what am I doing wrong with gcc (Attolic Crossstudio) ? Thanks in advance..

_sam_des
Logged

Never be afraid to do something new. Remember Amateurs built the Ark, Professionals built the Titanic !
bigtoy
Active Member
***
Offline Offline

Posts: 238

Thank You
-Given: 337
-Receive: 297


« Reply #1 on: June 08, 2017, 04:57:40 04:57 »

I don't see a smoking gun, but I have a couple of questions that might help.

1.  In this line:
    vLCD_WriteStr_P( (const char*)g_strMnuConf_F_10, 0, LCD_ROW_1, TRUE );
    why are you casting the first parameter?  g_strMnuConf_F_10 is already defined as a const char [] so it seems the cast should not be required. Were you getting a warning or something that caused you to do the cast?

2. In this line:
    INT8U ucHandle_Menu( const char* const* mnu_array, INT8U mnu_count )
    you are ending up with a pointer to a pointer. From cdecl.org:
    "declare mnu_array as pointer to const pointer to const char"
    Are you sure you want this extra level of pointer redirection?

Logged
sam_des
Senior Member
****
Offline Offline

Posts: 256

Thank You
-Given: 128
-Receive: 151


« Reply #2 on: June 08, 2017, 09:30:12 09:30 »

@bigtoy,
Thanks for the reply.

Quote
In this line:
    vLCD_WriteStr_P( (const char*)g_strMnuConf_F_10, 0, LCD_ROW_1, TRUE );
    why are you casting the first parameter?  g_strMnuConf_F_10 is already defined as a const char [] so it seems the cast should not be required. Were you getting a warning or something that caused you to do the cast?
You are correct, cast is not required for first parameter. I just added it to see if it makes any difference to gcc generated code when I started getting garbage on LCD to be doubly sure about pointer being passed.

Quote
In this line:
    INT8U ucHandle_Menu( const char* const* mnu_array, INT8U mnu_count )
    you are ending up with a pointer to a pointer. From cdecl.org:
    "declare mnu_array as pointer to const pointer to const char"
    Are you sure you want this extra level of pointer redirection?
Yes, again you are correct. Its pointer to array of pointers in flash to strings stored in flash. ucHandleMenu() is called from multiple locations, each caller passing different array of strings, both strings & array of pointers to those strings are in flash...

Strings in Flash...
Code:
static const char g_strMnuConf_F_1[]	= "[ ]PWD Enable?";
static const char g_strMnuConf_F_2[] = "[ ]System Type";
static const char g_strMnuConf_F_3[]  = "[ ]Set Yr/Mon";
static const char g_strMnuConf_F_4[]  = "[ ]Set Serial";
static const char g_strMnuConf_F_5[]  = "[ ]Set M1";
static const char g_strMnuConf_F_6[] = "[ ]Set M2";
static const char g_strMnuConf_F_7[] = "[ ]Set IP-FSW";
static const char g_strMnuConf_F_8[] = "[ ]Set IP-P1";
static const char g_strMnuConf_F_9[] = "[ ]Set IP-P2";
static const char g_strMnuConf_F_10[] = "[ ]Set TCON";
static const char g_strMnuConf_F_11[] = "[ ]T Calib

Array of pointers to above strings also in flash,
Code:
static const char* const g_a_strMnuConfF_P[MENU_CONFF_STR_COUNT] = {
        g_strMnuConf_F_1, g_strMnuConf_F_2 ,g_strMnuConf_F_3, g_strMnuConf_F_4, g_strMnuConf_F_5,
g_strMnuConf_F_6, g_strMnuConf_F_7, g_strMnuConf_F_8, g_strMnuConf_F_9, g_strMnuConf_F_10,
g_strMnuConf_F_11,
g_strMnuPrev
};
I can see in map file that all these strings & array are allocating to rodata.

Issue in both of above cases is, without optimizations with gcc, code works fine, but with optimizations turned on (-s), pointers being passed to vLCD_WriteStr_P() & ucHandle_Menu() are wrong & hence garbage data getting displayed on LCD. With Keil, same code works fine in every level of optimization.
Hope I am able to clarify things up.

Thanks again,
_sam_des
Logged

Never be afraid to do something new. Remember Amateurs built the Ark, Professionals built the Titanic !
bigtoy
Active Member
***
Offline Offline

Posts: 238

Thank You
-Given: 337
-Receive: 297


« Reply #3 on: June 08, 2017, 09:45:25 21:45 »

Hmm. I don't know how easy it is for you to do, but if it were me, I'd try removing a bunch of those "const" statements. At least a little bit. For example for your (pretty simple it seems) vLCD_WriteStr_P() function.  The only thing I can think of is that somewhere it's getting confused in generating those pointers when the optimiser is turned on, and all those const's might have something to do with it. Not that I believe that's your problem (the consts should be OK) but I suspect trying that might lead you to the problem.
Logged
gurksallad
Newbie
*
Offline Offline

Posts: 27

Thank You
-Given: 12
-Receive: 6


« Reply #4 on: October 10, 2019, 08:37:23 20:37 »

@sam_des: Did you solve this? If yes, how did you do it?

I'm currently facing a similiar problem and I'm ready to go bonkers because I cannot track it down.
Logged
sam_des
Senior Member
****
Offline Offline

Posts: 256

Thank You
-Given: 128
-Receive: 151


« Reply #5 on: October 11, 2019, 08:02:34 20:02 »

@sam_des: Did you solve this? If yes, how did you do it?

I'm currently facing a similiar problem and I'm ready to go bonkers because I cannot track it down.
Unfortunately, no. I haven't been able to solve this. Also asked on ST support forums, but no solution.
Also, gave up on CubeMX IDE,as its code-generation for TrueStudio is buggy as hell, especially it just removes the user-defined include paths & files whenever project is regenerated.

Fortunately, I can use keil since I'm using STM32F0 family.

_sam_des
Logged

Never be afraid to do something new. Remember Amateurs built the Ark, Professionals built the Titanic !
Pages: [1]
Print
Jump to:  


DISCLAIMER
WE DONT HOST ANY ILLEGAL FILES ON THE SERVER
USE CONTACT US TO REPORT ILLEGAL FILES
ADMINISTRATORS CANNOT BE HELD RESPONSIBLE FOR USERS POSTS AND LINKS

... Copyright © 2003-2999 Sonsivri.to ...
Powered by SMF 1.1.18 | SMF © 2006-2009, Simple Machines LLC | HarzeM Dilber MC