Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Некоторые непонятки
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
SasaVitebsk
Ребята, выручайте. Немного непонимаю.

Имеется объявление:
Код
typedef const struct
{
  const int32_t            *Index;                // Указатель на редактируемый параметр/ смещение для каналов
  const uint16_t        Ch;                    // 0/ Указатель на канал
  const uint8_t            fSignEn;            // Отображение знака числа
  const uint8_t            LenDig;                // Число цифр в числе (0 - гашение незначащих нулей)
  const uint8_t            DigAfterDot;        // Число цифр после точки (0 - точки нет)
  const uint8_t            DigType;            // Тип результирующего числа (0 - int8, 1 - int16, 2 - int32, 3 - float)
  const uint16_t        typeEditing;        // возможножность редактирования
  void                    (*savefunc)(void);    // Указатель на функцию записи редактируемых параметров
  const char* const        NameUnits;            // наименование единиц измерения
} DigEditing_t;


Имеется строка
const char* const strSec = "сек.";

Объявлена структура
Код
//***************************************************************
// @@ 12. Настройки работы подсветки прибора
DigEditing_t dgeLightTime =                // Меню "Настройки подсветки"
{
  (int32_t *)&LightTime,                        // Время работы подсветки прибора
  0, 0,                                            // прямой, неотображать знак
  3, 0,                                            // два знака, нет запятой
  0,                                            // int8
  ALLEDIT, SaveGlobalSetting,                    // Редактировать можно без пароля, сохранять
  strSec                                        // "сек."
};


IAR 6.40.2 даёт сообщение об ошибке на строке
strSec // "сек."


Error[Pe028]: expression must have a constant value E:\work\IAR C Proect\tm3\Source\MonoMenu\lcd_work.c 432

Что он от меня хочет?
GCC компилит.


demiurg_spb
а так:
Код
const char strSec[] = "сек.";

typedef struct
{
  uint8_t        fSignEn;
  uint8_t        LenDig;
  uint8_t        DigAfterDot;
  ...
  const char* NameUnits;
} DigEditing_t;

const DigEditing_t x =
{
    .NameUnits = strSec
};

У вас ИМХО использовалась не очень правильная идея - в typedef засунут квалификатор const, как для самого типа, так и для поля (я всё лишнее почистил).
Так обычно не принято делать ибо одно поле не может быть константным а другое нет -
вся структура должна целиком лечь либо в data секцию либо в секцию rodata и это задаётся при определении переменной или константы данного типа, как в моём примере в 4-ой от конца строке объявлена констаната типа DigEditing_t.
SasaVitebsk
Там проект уже под сотню файлов...
Изначально так и было. Я его в QT писал. QT понимает даже если непосредственно пишешь "сек.". IAR не помещал структуру во флэш если не указываешь что поля константы. С этого всё и понеслось. Кроме того, при размещении в структуре требует либо явного указания длины либо указателя ... Да я уже всё и не помню ...
Ладно. Я это обхожу ч/з указатель, но вообще-то непонятно

demiurg_spb
ИМХО мой пример будет всегда повторяемо и ожидаемо компилится абсолютно любым стандартным с99 и с11 компилятором.
Чтобы его и плюсы переварили нужно отказаться от инициализации полей структуры по имени - не велика потеря.

+ ещё заметил
Код
  (const int32_t *)&LightTime,                        - у вас не хватало const

+
ALLEDIT должно быть либо задефайнено, либо enum (в общем не const int ALLEDIT = 33;).
SasaVitebsk
Если будет посвободнее со временем, то надо будет собрать простенький проект и поэкспериментировать. А то на этом шашкой махать не хочется. Я несколько вариантов проверил - всё не то. Немного непонятно. В QT всё подряд проканывает. Хотя там не видно, для него это всё данные. А мне хотелось бы максимально во флэш закинуть.
Хотя я уже и сам не верю, что будет посвободее со временем. sad.gif Даже отдохнуть, толком нет времени. На любимую рыбалку съездить ... crying.gif
chernenko
Чтобы не множить темы задам вопрос тут.

Столкнулся с такой ситуацией. Хочу понять причину.

Есть IAR EWARM KikcStart версия 7.x на рабочем компе. Собрал прошивку все нормально и отлично работает. Пришел домой поставил 7.40 License компилирую тот же проект - не влезает. При тех же настройках прошивка увеличилась на 5к. Благо это загрузчик и поэтому память доступная линкеру была ограничена.

Начал в .map искать кто съел. Нахожу
Код
__Heap_Handler  = DLMalloc

dl7M_tlf.a: [3]
    dlmalloc.o                  5 456

__iar_dlcalloc          0x00001509   0x3e  Code  Gb  dlmalloc.o [3]
__iar_dlfree            0x00000ff9  0x510  Code  Gb  dlmalloc.o [3]
__iar_dlmalloc          0x00000d39  0x2b4  Code  Gb  dlmalloc.o [3]


В одном месте делаю calloc и free.

Убрал их и размер прошивки сразу вернулся к тому же размеру который был получен на рабочем ПК но с применением calloc и free.
Завтра посмотрю что в .map на рабочем компе.
Что это и почему один и тот же проект с одними и теме же настройками на разных версиях IAR дали такой разный результат?
Я в итоге конечно нашел вариант как уйти от calloc в этом месте, но хотелось бы разобраться.
Xenia
У вас модель памяти какая?
Похоже на то, что не Small, а Large, поскольку malloc замещен dlmalloc'ом.
Альтернативный "dlmalloc package" быстрее работает, но велик по объему.
Поставьте Small, и тогда альтернативный менеджер пямяти отключится. Или вручную определите
#define _DLIB_INCLUDE_DLMALLOC_ALTERNATIVE 0
Почитайте, что в комментариях написано:
CODE
/*
* Include dlmalloc as an alternative heap manager in product.
*
* Typically, an application will use a "malloc" heap manager that is
* relatively small but not that efficient. An application can
* optionally use the "dlmalloc" package, which provides a more
* effective "malloc" heap manager, if it is included in the product
* and supported by the settings.
*
* See the product documentation on how to use it, and whether or not
* it is included in the product.
*/
#ifndef _DLIB_INCLUDE_DLMALLOC_ALTERNATIVE
/* size_t/ptrdiff_t must be a 4 bytes unsigned integer. */
#if _DLIB_SMALL_TARGET_INTERNAL || __SIZE_T_MAX__ < 0xfffffffful
#define _DLIB_INCLUDE_DLMALLOC_ALTERNATIVE 0
#else
#define _DLIB_INCLUDE_DLMALLOC_ALTERNATIVE 1
#endif
#endif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.