|
IAR + SAM7S, Как узнать размер свободной SRAM? |
|
|
|
Nov 12 2007, 13:36
|

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

|
Цитата(KAlex @ Nov 12 2007, 15:27)  А как сказать IAR-у, что этот массив надо линковать последним. Явно указав его имя в списке для линкера последним. Конкретика зависит от версии IAR - у 4.x и 5.x линкеры разные. Если 4.x то например в XCL файле добавляем: Код -D_HEAP_RTOS_SIZE=1000 // 4Kb - Dummy minimal space for My Memory Manager -Z(DATA)HEAP_RTOS+_HEAP_RTOS_SIZE=RAMSTART-RAMEND // For My memory manager Ну а дальше: Код extern ulong RAMEND; extern ulong RAMSTART; #pragma segment="HEAP_RTOS"
printf( "\tRAM use:%lu Heap:%8X Size:%lu\r", (ulong)(__segment_begin( "HEAP_RTOS" ))-(ulong)&RAMSTART, __segment_begin( "HEAP_RTOS" ), (ulong)&RAMEND - (ulong)(__segment_begin( "HEAP_RTOS" )) + 1 );
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Nov 18 2007, 12:34
|

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

|
Цитата(Kitsok @ Nov 18 2007, 10:16)  копируем прошивку в heap, в heap-же копируем функцию записи во флеш, делаем необходимые проверки и передаем управление на эту функцию. И незадолго до конца работы этой функции пропадает питание. Устройство можно возвращать изготовителю. Было несколько обсуждений на эту тему. Вкратце - загрузчик должен находиться в том же сегменте, что и вектора и получать управление при включении питания. А дальше решать - передавать управление основной программе или делать апгрейд.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Nov 18 2007, 19:32
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Цитата(Сергей Борщ @ Nov 18 2007, 15:34)  И незадолго до конца работы этой функции пропадает питание. Устройство можно возвращать изготовителю. Было несколько обсуждений на эту тему. Вкратце - загрузчик должен находиться в том же сегменте, что и вектора и получать управление при включении питания. А дальше решать - передавать управление основной программе или делать апгрейд. Спасибо за ссылку, почитаю. С опасением полностью согласен. Причина, по которой я не горю желанием писать полноценный бутлоадер (для поиска: загрузчик, bootloader, бутлодырь  ) - необходимо реализовать весь стек USB - других интерфейсов у устройства попросту нет...
|
|
|
|
|
Nov 19 2007, 13:13
|

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

|
Цитата(Kitsok @ Nov 18 2007, 21:32)  необходимо реализовать весь стек USB - других интерфейсов у устройства попросту нет... А ОЗУ внешнее? Внутреннего-то не хватит, чтобы всю прошивку в heap поместить. Для прошивки достаточно держать в ОЗУ функцию из нескольких команд Код __ramfunc __arm void FlashCommand_RAM(uint32_t command) { AT91C_BASE_MC->MC_FCR = command; while(!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY)); } Возможно имеет смысл ее держать в ОЗУ постоянно. Все остальное может жить в защищенном от стирания секторе флеш. Может имеет смысл при приеме прошивки складывать ее в свободную область флеш, а загрузчик будет копировать из этой области в рабочие адреса? Тогда сбои питания не страшны - одна из копий прошивки всегда будет целой, а сам копировщик вообще нестираемым.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Nov 20 2007, 10:52
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Цитата(Сергей Борщ @ Nov 19 2007, 16:13)  А ОЗУ внешнее? Внутреннего-то не хватит, чтобы всю прошивку в heap поместить. Для прошивки достаточно держать в ОЗУ функцию из нескольких команд Код __ramfunc __arm void FlashCommand_RAM(uint32_t command) { AT91C_BASE_MC->MC_FCR = command; while(!(AT91C_BASE_MC->MC_FSR & AT91C_MC_FRDY)); } Возможно имеет смысл ее держать в ОЗУ постоянно. Все остальное может жить в защищенном от стирания секторе флеш. Может имеет смысл при приеме прошивки складывать ее в свободную область флеш, а загрузчик будет копировать из этой области в рабочие адреса? Тогда сбои питания не страшны - одна из копий прошивки всегда будет целой, а сам копировщик вообще нестираемым. ОЗУ встроенное, SAM7S256, но прошивка ограничивается размером в 16 кб, больше мне и не надо. Рассматриваю возможность дописывания аппликухи и организации dual firmware. А вот глупый вопрос - можно ли работая из флеша писать другие сектора этого флеша, или обязательно копировать себя в RAM и запускаться оттуда? Потому как если можно, то изменения будут касаться исключительно проверки версии и CRC с дальнейшей передачей управления. Хотя криво это все, по-хорошему, надо бутлоадер писать а-ля SAM-BA и не выпендриваться.
|
|
|
|
|
Nov 20 2007, 12:30
|

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

|
Цитата(Kitsok @ Nov 20 2007, 12:52)  А вот глупый вопрос - можно ли работая из флеша писать другие сектора этого флеша, или обязательно копировать себя в RAM и запускаться оттуда? Все, кроме приведенной мной выше функции может работать из флеша. На время выполнения этой функции флеш блокируется (поэтому либо запрещайте прерывания, либо переносите обработчики и вектора в ОЗУ). Цитата(Kitsok @ Nov 20 2007, 12:52)  Хотя криво это все, по-хорошему, надо бутлоадер писать а-ля SAM-BA и не выпендриваться. Тем более что в USB есть (специальный класс?) возможность загрузки firmware. У атмела в апликухах кажется что-то было. Может и не так страшно?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Nov 21 2007, 12:22
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Цитата(_dem @ Nov 21 2007, 00:21)  Учитывая небольшой размер вашей прошивки, я бы вообще порекомендовал вам после запуска копировать прошивку в RAM и делать REMAP - и работайте с флешем когда и как вам хочется. Естественно, прошивка должна быть слинкована с правильными адресами (работа из RAM). А копирование можно сделать в cstartup на ассемблере. Про флеш понятно. Про ремап - нет, буду по второму кругу доку читать, но пока не понятно. В частности: Ресетится контроллер, передается управление по адресу 0x0, который мемори контроллером транслируется в 0x00100000 (флеш). Выполняется там что-то, копируется что-то из флеша в страницу памяти по адресу 0x00200000(РАМ). Потом мы ставим бит remap, следующая инструкция откуда возьмется - из RAM или из FLASH? Еще одна непонятка - как нужно настроить компилятор, куда что линковать? Получается что для бутлоадера нужно прописывать файл линкеру, что мы "живем" по адресам 0x00100000? Тогда после ресета pc=0, первая инструкция - переход по реальному адресу. Ну а приложение нужно размещать по адресу 0x00, и в бутлоадере делать копирование флеша в память, ремап и передачу управления на 0x00. Правильно?
|
|
|
|
|
Nov 21 2007, 14:20
|

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

|
Цитата(Kitsok @ Nov 21 2007, 14:22)  Ресетится контроллер, передается управление по адресу 0x0, который мемори контроллером транслируется в 0x00100000 (флеш). Выполняется там что-то, копируется что-то из флеша в страницу памяти по адресу 0x00200000(РАМ). Потом мы ставим бит remap, следующая инструкция откуда возьмется - из RAM или из FLASH? Давайте представим это так: есть три области - с нуля, с 0x00100000 (флеш), и с 0x00200000(ОЗУ). Если РС указывает на вторую область, программа исполняется из флеш. Если на третью - из ОЗУ. Если на первую - то зависит от ремапа. Т.е. в первой области мы имеем "зеркало" второй или третьей. Поэтому в момент ремапа программа должна исполняться из второй или третьей (она может вообще всегда исполняться из второй или третьей, а в нулевую попадать только по исключениям, чтобы считать вектор). Это в SAM7. В LPC несколько иначе - там "отражается" только область 0x40 байт на вектора. Поэтому ответ такой - из следующего адреса. А что окажется по этому адресу - зависит от адреса (если вторая область - флеш, если третья - ОЗУ) и ремапа(если первая) Цитата(Kitsok @ Nov 21 2007, 14:22)  Еще одна непонятка - как нужно настроить компилятор, куда что линковать? Получается что для бутлоадера нужно прописывать файл линкеру, что мы "живем" по адресам 0x00100000? Тогда после ресета pc=0, первая инструкция - переход по реальному адресу. Ну а приложение нужно размещать по адресу 0x00, и в бутлоадере делать копирование флеша в память, ремап и передачу управления на 0x00. Правильно? Почти. У меня так: загрузчик живет по адресам 0x00100000 - 0x00100FFF (нулевой сектор флеш), файл SAM7_boot.xcl. Приложение живет вслед за загрузчиком, начиная с 0x00101000 (первый сектор флеш и далее), файл SAM7S64_boot_app.xcl. При включении питания или сбросе флеш отражена на нулевые адреса, на месте векторов оказываются вектора загрузчика, из вектора ресета считывается переход на загрузчик в адреса 0x00100000 - 0x00100FFF. Загрузчик получает управление. Если надо передать управление приложению, то загрузчик берет вектора приложения из адресов 0x00101000-0x0010103F, копирует их в озу по адресам 0x00200000-0x0020003F (эта область зарезервирована и в загрузчике и в приложении, чтобы там не оказались какие-либо данные). Загрузчик (работая в адресах 0x00100000 - 0x00100FFF) запрещает прерывания и делает ремап. При этом ОЗУ отражается на нулевые адреса и в области векторов оказываются скопированные в 0x00200000-0x0020003F вектора приложения. Загрузчик передает управление на нулевой адрес, т.е. на вектор ресет приложения. Из вектора считывается команда перехода на cstartup приложения, в адреса 0x00101040....
Прикрепленные файлы
boot.zip ( 1.51 килобайт )
Кол-во скачиваний: 38
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Nov 21 2007, 14:43
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Цитата(Сергей Борщ @ Nov 21 2007, 17:20)  У меня так: загрузчик живет по адресам 0x00100000 - 0x00100FFF (нулевой сектор флеш), файл SAM7_boot.xcl. Приложение живет вслед за загрузчиком, начиная с 0x00101000 (первый сектор флеш и далее), файл SAM7S64_boot_app.xcl. При включении питания или сбросе флеш отражена на нулевые адреса, на месте векторов оказываются вектора загрузчика, из вектора ресета считывается переход на загрузчик в адреса 0x00100000 - 0x00100FFF. Загрузчик получает управление. Если надо передать управление приложению, то загрузчик берет вектора приложения из адресов 0x00101000-0x0010103F, копирует их в озу по адресам 0x00200000-0x0020003F (эта область зарезервирована и в загрузчике и в приложении, чтобы там не оказались какие-либо данные). Загрузчик (работая в адресах 0x00100000 - 0x00100FFF) запрещает прерывания и делает ремап. При этом ОЗУ отражается на нулевые адреса и в области векторов оказываются скопированные в 0x00200000-0x0020003F вектора приложения. Загрузчик передает управление на нулевой адрес, т.е. на вектор ресет приложения. Из вектора считывается команда перехода на cstartup приложения, в адреса 0x00101040.... Ну, собственно, именно такой механизм я и имел в виду. Разница лишь в том, что я зачем-то (может, для скорости?  ) предложил копировать все приложение из флеша в память, а потом - remap. Важно то, что после ресета у нас pc=0, а следующая инструкция уже выполняется из диапазона 0x00100000-... Или, другими словами, таблица векторов (которую мы копируем) "живет" всегда по адресам из 0x000000-0x000003F, а переводит всегда на реальные адреса во флеше. Ну или в RAM, если копировать приложение. Спасибо большое всем! Похоже, до меня доперло
|
|
|
|
|
Nov 21 2007, 22:55
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Цитата(Kitsok @ Nov 21 2007, 17:43)  Похоже, до меня доперло  ... не до конца. Приложение у нас живет начиная с адреса 0x00101000-..., соответственно вектора его лежат в 0x00101000-0x00100103F, а дальше - само приложение, вплоть до 0x0010FFFF После ремапа эти адреса будут отражены на 0x0000 1000-0x0000FFFF. В загрузчике мы скопировали 0x00101000-0x0010103F в 0x00100000-0x0010003F, и, если в xlc так и указано, у нас все пучком. Но после ремапа остается дыра 0x00000040-0x00000FFF? Вариант - собирать приложение по адресам 0x00000000, бутлоадером копировать приложение в RAM целиком и делать ремап. Но криво опять... Что-то я не догоняю?
|
|
|
|
|
Nov 22 2007, 11:35
|

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

|
Цитата(Kitsok @ Nov 22 2007, 00:55)  ... не до конца.
Приложение у нас живет начиная с адреса 0x00101000-..., соответственно вектора его лежат в 0x00101000-0x00100103F, а дальше - само приложение, вплоть до 0x0010FFFF
После ремапа эти адреса будут отражены на 0x00001000-0x0000FFFF. Нет. Перед ремапом в нулевые адреса отражена область 0x00 100000... т.е. на месте векторов (0x00000000-0x0000003F) отражены вектора загрузчика (0x00100000-0x0010003F), дальше отражен загрузчик и приложение (но это не принципиально). После ремапа на нулевые адреса отражается область 0x00 200000..., т.е. RAM, а туда перед ремапом загрузчик копирует вектора приложения. Загрузчик и приложение остаются на своем месте по адресам во флеш.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|