Перейти к содержанию
    

Доступ к переменной по абсолютному адресу IAR

Всем привет.

Помогите разобраться с размещением/чтением структуры из флэш по абсолютному адресу.

Задача получить доступ к структуре из основной программы, размещенной бутлоадером. (короче, основная программа хочет знать версию бутлоадера)

Итак по порядку

 

// 1. Определена структура

typedef struct {
  uint8_t  major;
  uint8_t  minor;
} fw_version_t;

 

// 2. Объявлена переменная

#pragma location = "FW_INFO"
__root const fw_version_t app_version = 
{
  .major   = 2,
  .minor   = 8,
};

 

// 3. В линкере определена область FW_INFO

/* Размер секции для хранения структуры c информацией о версии прошивки, она размещается перед контрольной суммой прошивки*/
define symbol __FW_INFO_size__  = 4;
define symbol __FW_INFO_start__ = __CRC32_addr__ - __FW_INFO_size__;
define symbol __FW_INFO_end__   = __CRC32_addr__;


define region FW_INFO_region = mem:[from __FW_INFO_start__ to __FW_INFO_end__];
place in FW_INFO_region { readonly section FW_INFO };

 

// 4. После прошивки переменную вижу во флэш

В *.map следующая запись "P3":  place in [from 0x807'fff8 to 0x807'fffc] { ro section FW_INFO };

1961754355_flash.PNG.a5a570d061d6204da53d9a77e3843228.PNG

// 5. Объявляю переменную по абсолютному с абсолютным адресом указанным в map файле.

__no_init fw_version_t mainApp_fw_info @ 0x0807fff8;

 

 

----------------------------------------------------------------------------------------------------

Но в результате в структуре оказываются не те значения, которые ожидались.

в mainApp_fw_info.major читается 0xff из 0x0807fff8

в mainApp_fw_info.minor читается 0xff из 0x0807fff9

 

Я так понимаю, неправильно разместил структуру или её читаю.

Подскажите, что сделал не так?

 

 

 

 

 

 

Изменено пользователем simark1979

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 часа назад, simark1979 сказал:

В *.map следующая запись "P3":  place in [from 0x807'fff8 to 0x807'fffc] { ro section FW_INFO };

1961754355_flash.PNG.a5a570d061d6204da53d9a77e3843228.PNG

// 5. Объявляю переменную по абсолютному с абсолютным адресом указанным в map файле.

__no_init fw_version_t mainApp_fw_info @ 0x0807fff8;

----------------------------------------------------------------------------------------------------

Но в результате в структуре оказываются не те значения, которые ожидались.

в mainApp_fw_info.major читается 0xff из 0x0807fff8

в mainApp_fw_info.minor читается 0xff из 0x0807fff9

Не очень понятно - а чего Вы ожидали? Сами же картинку привели на которой у вас по этому адресу 0xFF, 0xFF. Поэтому они и читаются. Что не так?

Очевидно, что app_version у Вас находится не по адресу 0x0807FFF8, а по 0x0807FFFA.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 hours ago, jcxz said:

Очевидно, что app_version у Вас находится не по адресу 0x0807FFF8, а по 0x0807FFFA.

Сейчас обнаружил, дело в том, что пока я сейчас я кладу и читаю из одной и той же программы (для простоты отладки)

Прикол в том, что если я пытаюсь вычитать её по другому адресу, допустим так

__no_init fw_version_t mainApp_fw_info @ 0x0807fffa;

линкер переменную запихивает по другому адресу. (Обратите внимание данные сместились, в переменной опять лежат ff, но пока не смотрел откуда они туда попадают.

1094697036_flash2.PNG.5fcc0401cdacb360cb4ae61b1ff6acb4.PNG

То ли это нельзя делать из одной и той же программы, то ли я что-то не понимаю.

Я то думал, что адрес в __no_init fw_version_t mainApp_fw_info @ 0x0807fffa; влияет только на адрес чтения, а оказывается и на адрес размещения тоже, несмотря на спецификатор __no_init

 

 

 

 

Изменено пользователем simark1979

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, simark1979 сказал:

Я то думал, что адрес в __no_init fw_version_t mainApp_fw_info @ 0x0807fffa; влияет только на адрес чтения, а оказывается и на адрес размещения тоже, несмотря на спецификатор __no_init

__no_init обычно используется для объявления неинициализируемых переменных в ОЗУ. Не стоит использовать её для const-объектов flash. Ваши объявления - неверные. имхо.

Например у меня что-то похожее делается так:

.cpp:

extern "C" char const codeSignature[];
__root char const codeSignature[] @ ".codeSignature" =
  "DATE=XX.03.2022;" "TIME=XX:XX:XX.XX;"
  "TARGET=" concat(FIRMWARE_TARGET_STR_, FIRMWARE_TARGET) ";"
  "VERSION=" TO_STRING(VERSION_FIRMWARE);

.h:

extern "C" char const codeSignature[];
...
struct CodeHead {
  u8 const *codetail;
  u8 const *codeSignature;
};
extern "C" CodeHead const codehead;

.asm:

               SECTION  .codeheadExt:CONST:ROOT(0)

               PUBLIC   codehead
               EXTERN   codeSignature
               SECTION  .codehead:CONST:ROOT(2)
codehead       DC32     codetail
               DC32     codeSignature

.icf:

define region FLASHC_regionC = mem:[from 0x08040000 to 0x0817FFFF]; //PMU/FLASH (cached)
define block IMAGE_HEAD with fixed order {section .intvec, section .checksum, section .codehead, section .intvecTail, section .codeSignature};
place in FLASHC_regionC {ro, first block IMAGE_HEAD, last section .codetail, ...};

где FLASHC_regionC - регион для образа программы во флешь.

Обратите внимание как объявлены codeSignature и codehead.

Прибивание гвоздями к абсолютным адресам каких-то переменных/констант в исходниках/хидерах - плохая практика. Наступите на грабли (или уже наступили). Для размещения объектов в памяти в IAR служит .icf-файл. Его и надо использовать. Как можно заметить - у меня нет ни одного абсолютного адреса вне пределов .icf-файла.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 hours ago, jcxz said:

__no_init обычно используется для объявления неинициализируемых переменных в ОЗУ. Не стоит использовать её для const-объектов flash. Ваши объявления - неверные. имхо.

.......................

.......................


define region FLASHC_regionC = mem:[from 0x08040000 to 0x0817FFFF]; //PMU/FLASH (cached)
define block IMAGE_HEAD with fixed order {section .intvec, section .checksum, section .codehead, section .intvecTail, section .codeSignature};
place in FLASHC_regionC {ro, first block IMAGE_HEAD, last section .codetail, ...};

где FLASHC_regionC - регион для образа программы во флешь.

Обратите внимание как объявлены codeSignature и codehead.

Прибивание гвоздями к абсолютным адресам каких-то переменных/констант в исходниках/хидерах - плохая практика. Наступите на грабли (или уже наступили). Для размещения объектов в памяти в IAR служит .icf-файл. Его и надо использовать. Как можно заметить - у меня нет ни одного абсолютного адреса вне пределов .icf-файла.

Я извиняюсь, возможно не совсем четко сформулировал проблему.
Задача ведь не только в том, чтобы правильно разместить по адресу, но и вычитать 
С размещением переменных я Вас понял, размещаем в именованной секции.
Подскажите как теперь её вычитать.
А как вычитать теперь её?

Изменено пользователем simark1979

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

30 минут назад, simark1979 сказал:

Подскажите как теперь её вычитать.
А как вычитать теперь её?

Там же есть объявления для .h/.cpp. Что там непонятно? Вы си знаете?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, jcxz said:

Там же есть объявления для .h/.cpp. Что там непонятно? Вы си знаете?

Извините, с телефона не разглядел. Конечно знаю)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...