Я столкнулся с проблемой использования строк / массива указателя на строки во флэш-памяти с помощью gcc. Контроллер - STM32F100VBT6, а компилятор - Atollic TrueStudio v9.0.1.
Когда оптимизация отключена, все работает нормально, но если для оптимизации установлено значение -s или что-то еще, на ЖК-дисплее отображается мусор. Я вижу, что значения указателей на передаваемые строки неверны, хотя файл карты правильно показывает, что строки, а также массивы указателей на строки находятся в «родатах». Вот частичный код ...
#define MENU_CONFF_STR_COUNT (12)
static 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 ) ) {
//....code handling switch()
}
}
Точно такой же код отлично работает с Keil. Так что я делаю не так с gcc (Atollic Crossstudio)?
Вот код для vLCD_WriteStr_P (),
void vLCD_WriteStr_P( const char* pStr_P, INT8U x, INT8U y, BOOL fill )
{
char ch;
vLCD_SetXY( x, y );
for( ;; ) {
ch = *pStr_P++;
if ( !ch ) {
break;
}
x++; /* col++ */
vLCD_CmdData( LCD_DATA, ch );
}
if ( fill ) { /* fill rest of the row with 'blanks' */
while( LCD_COL_MAX > x ) {
vLCD_CmdData( LCD_DATA, ' ' );
x++;
}
}
}
Как сказал @P__J__, предоставленный вами код не объясняет ваш тезис. Вы предполагаете, что это повреждаются строки, а позже упоминаете о записи на ЖК-дисплей. Отображение данных на ЖК-дисплее - гораздо более сложная задача (и часто ее части также чувствительны ко времени), чем обработка строк. Лично я бы посоветовал изучить функции, обрабатывающие ЖК-дисплей, вплоть до записи в регистры или области отображения памяти - в зависимости от того, как реализована ваша ЖК-связь.
LCD (HD44780) инициализация в порядке. Если оптимизация gcc отключена, все в порядке, включая отображение строки. При включенной оптимизации указатель deref на строки во флэш-памяти дает искаженное отображение, в то время как строки в ОЗУ снова исправны.
Можете ли вы свернуть программу, чтобы она была как можно меньше, но при этом все еще проявляла эти симптомы? Затем разместите полный источник.
вы не показываете достаточно кода. Обычно такое поведение является признаком неопределенного поведения в вашем коде или нарушения строгих правил псевдонима, что может привести к ненормальному выполнению с включенной оптимизацией.