|
Непонятный эффект компилятора (линкера?) |
|
|
|
Jul 30 2015, 05:24
|
Участник

Группа: Участник
Сообщений: 71
Регистрация: 17-01-12
Пользователь №: 69 604

|
Имеется IAR 6.50 для ARM. Проект выполнен для STM32F103VCT6 с использованием scmRTOS V4.00. В тексте программы имеется объявление константной структуры с инициализацией: Код typedef struct { char *Name; //Отображаемое имя пункта меню unsigned char Type; //Тип отображения величины пункта меню float *Value; //Ссылка на величину пункта меню unsigned char Precision; //Точность для чисел с плавающей запятой unsigned char Flags; //Флаги пункта меню unsigned char Access; //Уровень доступа к пункту меню float MinValue; //Минимально допустимая величина float MaxValue; //Максимально допустимая величина float DefaultValue; //Величина по умолчанию unsigned short UpMenuItem; //Индекс пункта меню вверх unsigned short DownMenuItem; //Индекс пункта меню вниз unsigned short LeftMenuItem; //Индекс пункта меню влево unsigned short RightMenuItem; //Индекс пункта меню вправо TMenuVariable *MenuVar; //Указатель на переменные величины меню void (*ShowSubroutine)(void *ItemPtr); //Указатель на программу, которая выполняется при отображении величины (передаётся указатель на пункт меню) void (*EditSubroutine)(void *ItemPtr,float NewValue); //Указатель на программу, которая выполняется при изменении величины (передаётся указатель на пункт меню) unsigned char ValueLength; //Количество позиций, отведённое на величину пункта меню unsigned short Index; //Индекс пункта внутри меню } TMenuItem;
const TMenuItem TestMenuItems[] = { /* Name - Type - Value - Precis - Flags - Access - MinValue - MaxValue - DefValuePtr - UpItem - DownItem - LeftItem - RightItem - Var - ShowSubrout - EditSubrout - ValueLength - GroupItem */
{"АЦП",mt_WithoutValue,NULL,0,0,al_Operator,0.0,0.0,0.0,NULL,2,428,66,&MenuTestVariable[0],NULL,NULL,0,1}, //Пункт меню "АЦП" {"АЦП 1",mt_FloatValue,&ADCChannels[0].Value,3,0,al_Operator,0.0,0.0,0.0,1,NULL,65,3,&MenuTestVariable[1],NULL,NULL,6,2}, //Канал АЦП 1 {"АЦП 2",mt_FloatValue,&ADCChannels[1].Value,3,0,al_Operator,0.0,0.0,0.0,1,NULL,2,4,&MenuTestVariable[2],NULL,NULL,6,3}, //Канал АЦП 2
...
{"АЦП 64",mt_FloatValue,&ADCChannels[63].Value,3,0,al_Operator,0.0,0.0,0.0,1,NULL,64,2,&MenuTestVariable[64],NULL,NULL,6,65}, //Канал АЦП 64 }; Оптимизация отключена. Компилируется без ошибок. В файле *.map упоминание об этой структуре отсутствует. Но это только часть таблицы. Добавляю остальное. Опять компилирую. Появляется в файле *.map, но ложится а область ОЗУ (длина таблицы 0x5890 байт). Пытаюсь поставить перед объявлением и инициализацией прагму: #pragma location=0x08000800 Теперь ложится в память согласно прагме, но после загрузки при попытке выполнения "улетает". Что делать и кто виноват?
Сообщение отредактировал Herz - Jul 30 2015, 09:43
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 14)
|
Jul 30 2015, 06:17
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (Вячик13 @ Jul 30 2015, 08:24)  Оптимизация отключена. Никогда, никогда не отключайте опттмизацию, тем более в попытках застаивить работать. Это верный путь в анус. Зато включайте ВСЕ предупреждения компилятора. QUOTE В файле *.map упоминание об этой структуре отсутствует. Значит она никому НЕ нужна, но предупреждения у Вас явно подавлены, посему и представляется чудесным ее отсутствие. QUOTE Но это только часть таблицы. Добавляю остальное. Опять компилирую. Появляется в файле *.map, Значит в "остальном" появилось что-то кому-то нужное. QUOTE но ложится а область ОЗУ (длина таблицы 0x5890 байт). Значит структура не может быть проинициализирована константами на на этапе компиляци QUOTE Теперь ложится в память согласно прагме, но после загрузки при попытке выполнения "улетает". Ну разместили принудительно во Flash, но запись как была так и есть, вот и полетели...
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jul 30 2015, 06:38
|
Участник

Группа: Участник
Сообщений: 71
Регистрация: 17-01-12
Пользователь №: 69 604

|
Ну хорошо, "структура не может быть проинициализирована константами на на этапе компиляции". А как? Каким образом можно сделать так, чтобы на выходе получить то же самое?
Сообщение отредактировал Herz - Jul 30 2015, 09:44
Причина редактирования: Избыточное цитирование
|
|
|
|
|
Jul 30 2015, 06:45
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (Вячик13 @ Jul 30 2015, 09:38)  Каким образом можно сделать... Вы Автор, Вам виднее. Для просветления - оставьте от всего этого ОДНУ строчку и смотрите, что-бы: 1) на нее были ссылки; 2) все, что в структуре было известно на этапе компиляции. Все.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jul 30 2015, 08:05
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Вячик13 @ Jul 30 2015, 08:24)  Появляется в файле *.map, но ложится а область ОЗУ (длина таблицы 0x5890 байт) Ненаказуемо. Совсем. По стандарту const только заставляет компилятор запрещать запись в такую переменную. Вы просите переменную - она есть. Попробуйте в нее записать - получите по рукам. Все остальные оптимизации вы запретили компилятору лично. На что же вы обижаетесь? Включите оптимизацию и отлаживайте конечный код, zltigo вам совершенно правильно пишет. Он только не прав по поводу причин, заставляющих размещать константы в ОЗУ. По этому поводу вы его не слушайте, вы сюда слушайте, причины я описал выше. Включите оптимизацию - получите ваш массив во флеше.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jul 30 2015, 09:21
|

Местный
  
Группа: Свой
Сообщений: 327
Регистрация: 24-06-06
Из: Томск
Пользователь №: 18 328

|
Цитата(AHTOXA @ Jul 30 2015, 14:40)  Я бы в первую очередь заменил char *Name; //Отображаемое имя пункта меню на char const* Name; Не-а. Вот так: char const* const Name; Хотя нет. Можно и без второго const. Сдается мне, что проблема в указателях на функцию. Скорее всего реализации функций в другом файле или ниже по тексту. Соответственно компилятор на момент заполнения структуры не знает их адреса.
|
|
|
|
|
Jul 30 2015, 09:37
|
Участник

Группа: Участник
Сообщений: 71
Регистрация: 17-01-12
Пользователь №: 69 604

|
Цитата(Сергей Борщ @ Jul 30 2015, 11:05)  Ненаказуемо. Совсем. По стандарту const только заставляет компилятор запрещать запись в такую переменную. Вы просите переменную - она есть. Попробуйте в нее записать - получите по рукам. Все остальные оптимизации вы запретили компилятору лично. На что же вы обижаетесь? Включите оптимизацию и отлаживайте конечный код, zltigo вам совершенно правильно пишет. Он только не прав по поводу причин, заставляющих размещать константы в ОЗУ. По этому поводу вы его не слушайте, вы сюда слушайте, причины я описал выше. Включите оптимизацию - получите ваш массив во флеше. Включил оптимизацию (пробовал и средний уровень и высокий). Не помогло. Цитата(shreck @ Jul 30 2015, 12:21)  Не-а. Вот так: char const* const Name; Хотя нет. Можно и без второго const.
Сдается мне, что проблема в указателях на функцию. Скорее всего реализации функций в другом файле или ниже по тексту. Соответственно компилятор на момент заполнения структуры не знает их адреса. Так я же объявил их равными NULL.
|
|
|
|
|
Jul 30 2015, 10:23
|
Участник

Группа: Участник
Сообщений: 71
Регистрация: 17-01-12
Пользователь №: 69 604

|
Цитата(shreck @ Jul 30 2015, 12:44)  А ADCChannels, MenuTestVariable определены в этом же файле? MenuTestVariable в том же файле прямо перед таблицей, а ADCChannels в main.cpp, но по команде оболочки "Go to Definition" переходит к определению правильно.
|
|
|
|
|
Jul 30 2015, 10:52
|
Участник

Группа: Участник
Сообщений: 71
Регистрация: 17-01-12
Пользователь №: 69 604

|
Цитата(shreck @ Jul 30 2015, 13:32)  Ну вот и ответ на вопрос почему не во флешь, а в ОЗУ находится объект. А возможности навигации по коду у редактора здесь вообще не причем. Перенёс и ADCChannels в тот же файл - не помогло.
|
|
|
|
|
Jul 30 2015, 11:19
|
Участник

Группа: Участник
Сообщений: 71
Регистрация: 17-01-12
Пользователь №: 69 604

|
Цитата(shreck @ Jul 30 2015, 13:58)  Значит есть что-то еще, о чем не знает компилятор на момент построения таблицы. Собственно первые ответы поясняют все что нужно. А без нормально представленного кода указать конкретное место затруднительно. Понял, спасибо. Вполне возможно. Сейчас начну перелопачивать таблицу построчно, постепенно добавляя данные.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|