AN3927 Freescale USB Mass Storage Device Bootloader Application Note Rev. 0, 11/2009 (перевод)





5 Устранение неисправностей

Сопровождающее данную статью программное обеспечение было тщательно протестировано с использованием различных сочетаний семейств контроллеров, отладочных плат и операционных систем, указанных в главе "1 Введение". Тем не менее, ниже предлагается список возможных проблем, возникающих при переносе кода на другие устройства.


5.1 Вектор сброса

Если и загрузчик, и приложение отказываются стартовать, то причина может крыться в векторе сброса. Для проверки поставьте контрольную точку в начале процедуры " _Entry() " в файле "usr_entry_xx.c", после чего сбросьте контроллер, нажав предварительно кнопку входа в режим загрузки. Если отладчик остановится на контрольной точке, то вектор сброса в порядке. Если останова не произошло, то следует проверить, что вектор указывает на " _Entry() ". Вектор должен указывать на код загрузчика.


5.2 Вектор пользователя

Если загрузчик работает, как положено, но целевое приложение не запускается, то возможная причина - проблема с вектором пользователя. Для проверки поставьте контрольную точку в процедуре " _Entry() " в файле "usr_entry_xx.c" в месте перехода загрузчика на вектор пользователя. Перезагрузите устройство, нажав предварительно кнопку входа в режим загрузчика, и затем в режиме пошаговой отладки убедитесь, что загрузчик успешно переходит на целевое приложение. Загрузчик должен переходить на вектор пользователя, расположенный по фиксированному абсолютному адресу в программной памяти. По этому адресу должна находиться инструкция " JMP ", указывающая на точку входа целевого приложения.

Если загрузчик выбирает вектор пользователя по неправильному адресу, проверьте корректность задания адреса макросом " USER_ENTRY_ADDRESS " в файле "bootloader_xx.h". Если вектор расположен по правильному адресу, по содержит некорректный адрес точки входа в целевое приложение, следует убедиться, что приложение пользователя его корректно инициализирует. В предлагаемом коде это делается в файле "main.c". Вектор должен корректно загружаться (*) при инициализации приложения. Загрузчик не отвечает за инициализацию вектора пользователя.

(*) Примечание переводчика.
Так написано в оригинале, но на самом деле инициализация вектора пользователя происходит на этапе компоновки приложения в среде CodeWarrior, располагается он в программной памяти и никакой инициализации при запуске приложения не требует. В этом легко убедиться, обратившись к разделу "2.11 Карты распределения памяти".


5.3 Прерывания

Переадресация прерываний очень важна для правильной работы приложения. Если приложение запускается, но отказывается работать, то проблема может заключаться в прерываниях. Это наиболее вероятная причина, если до включения в проект загрузчика приложение работало хорошо. Признаком проблем с прерываниями служит корректное начало работы приложения с последующим неожиданным выходом кода за границы адресов программы. Для проверки надо запретить прерывания и убедиться в пропадании симптома.

В случае проблем с прерываниями возможны два направления проверки. Во-первых, за загрузку векторов прерываний в переадресованной таблице векторов отвечает приложение. Для того, чтобы понять как приложение загружает переадресованную таблицу, прочтите раздел "4.3 Создание нового проекта с загрузчиком".

Во-вторых, убедитесь, что вектора и в самом деле переадресуются. Для контроллеров, допускающих переадресацию в оперативную память, убедитесь, что приложение переустанавливает VBR на оперативную память. Для контроллеров, переадресующих вектора в программную память, убедитесь, что вектора расположенные по стандартным для выбранного контроллера адресам указывают на переадресованные вектора. Для MC9S08 переадресация производится в файле "Redirect_Vectors_S08.c".


5.4 Загрузчик затирает собственный код

После изменения или переноса на другой контроллер в процессе обновления содержимого программной памяти загрузчик может начать перезаписывать собственный код. Признаком такого поведения является "слёт" программы сразу после отработки процедуры стирания программной памяти или корректная работа при первом запуске и авария при последующих.

Возможны две причины. Во-первых, диапазон защищаемых адресов программной памяти не соответствует реальному размеру загрузчика. Проверьте правильность защиты программной памяти, описанную в разделе "2.8 Защита программной памяти".

Во-вторых, возможно наличие перекрёстных вызовов, когда загрузчик вызывает код из области приложения, стираемой в процессе обновления, и перекрёстный вызов порождает проблемы. Обратитесь к разделу "4.1 Предупреждение перекрёстных вызовов", чтобы узнать про перекрёстные вызовы и способы их предупреждения.


5.5 Ошибки перекрытия сегментов при компоновке

При сборке изменённого или перенесённого на другой контроллер проекта можно получить сообщения об ошибках перекрытия сегментов памяти, у которых может быть несколько возможных причин:

  • различные сегменты памяти перекрываются в управляющем файле компоновщика. Следите за возможным перекрытием различных сегментов при изменении карты распределения памяти проекта.

  • код загрузчика, приложения или используемая оперативная память выходят за пределы отведённых им сегментов. Если за отведённые ему пределы выходит код загрузчика, следует изменить объём защищаемой программной памяти сообразно с фактическим размером кода, после чего изменить карту распределения памяти устройства, как описано в разделе "4.7 Перенос загрузчика на другие контроллеры". При обнаружении иных причин ошибки измените карту распределения памяти или перейдите на контроллер с большим её объёмом, как описано в том же разделе.

  • приложение объявляет вектора прерываний. Если приложение объявляет вектора прерываний, то они попадают в стандартную таблицу векторов, организуемую средой CodeWarrior по умолчанию, которая конфликтует с таблицей векторов загрузчика, так как расположена по тем же адресам. Вектора прерываний приложения должны располагаться в переадресованной таблице. Для исправления ошибки переназначте вектора в переадресованную таблицу, как описано в разделе "4.3 Создание нового проекта с загрузчиком". Кроме того, следует убедиться, что приложение не связывает обработчики прерываний с векторами из стандартной таблице в области загрузчика. Подобное связывание получается в результате указания номера вектора прерывания при объявлении процедуры обработчика, как в показанном ниже примере. Обозначение номера вектора приводит к автоматическому заполнению стандартной таблицы векторов адресами объявляемых обработчиков прерываний.

    				interrupt VectorNumber_Vftm2ovf void timer(void) {
    

    Представленный код - пример объявления обработчика прерываний в среде CodeWarrior. Он предписывает компоновщику разместить адрес обработчика в области стандартных векторов прерываний на месте, соответствующем объявленному номеру вектора. В данном случае " VectorNumber_Vftm2ovf " - макро указывающее номер вектора, а " timer() " - имя обработчика. Номер вектора в объявлении должен быть изъят, дабы избежать конфликта с таблицей векторов загрузчика.

  • приложение объявляет вектор сброса, который конфликтует с вектором сброса загрузчика, занимающим тот же адрес памяти. Для исправления данной ошибки следует убедиться, что приложение не пытается присвоить вектору сброса, который должен указывать на код загрузчика, адрес точки входа в приложение. Подобное присвоение включает в себя объявление в файле компоновщика подобное показанному ниже. Приложение, декларирующее вектор сброса, вызывает связывание вектора сброса в стандартной таблице векторов с точкой входа приложения.

    				VECTOR 0 _Startup
    

    Показанный код является примером объявления вектора сброса в PRM-файле компоновщика для MC9S08 в среде CodeWarrior. Данная команда предписывает компоновщику загрузить вектор сброса адресом процедуры " _Startup() ", являющийся в данном случае точкой входа приложения. Подобное объявление вектора сброса следует изъять, чтобы оно не конфликтовало с объявлением вектора сброса загрузчика.

  • опции компиляции. В случае объединения загрузчика с приложением посредством библиотеки возможна ситуация, при которой объектный код загрузчика не поместится в отведённый ему сегмент. Данная ситуация возможна с случае, когда приложение использует меньший уровень оптимизации при компиляции, нежели оригинальный проект загрузчика. Ошибка исправляется изменением уровня оптимизации проекта приложения до состояния, при котором загрузчик начинает укладываться в отведённое ему место, или изменением карты распределения памяти, описанным в разделе "4.7 Перенос загрузчика на другие контроллеры".


5.6 USB диск не появляется в управляющей системе

USB диск должен появляться в системе через несколько секунд после вхождения правильно подключённого устройства в режим загрузки. Если этого не происходит, то, для начала, следует убедиться в корректности подключения и наличии питания устройства. Кроме того, убедиться, что аппаратура устройства сконфигурирована в качестве USB-устройства, подобного заводскому состоянию перемычек отладочной платы. Обновите состояние управляющей системы, чтобы заставить её проверить наличие нового диска. В операционной системе Windows с помощью Менеджера Устройств проверьте, что устройство успешно опознано. Перезагрузите управляющий компьютер. Проверьте факт успешного старта загрузчика, как описано в разделе "5.1 Вектор сброса". Проверьте, что загрузчик не стёр часть собственного кода, как описано в разделе "5.4 Загрузчик затирает собственный код". Если ни один из приведённых советов не помог, воспользуйтесь отладчиком и USB-анализатором для обнаружения проблем в процессе опознания.


5.7 Ошибка до начала записи файла

Результатом успешного опознания устройства является появление в управляющем компьютере съёмного диска, содержащего файл "READY.TXT". Убедитесь в наличии данного файла перед началом записи файла S19 на диск. Наличие файла статуса, сообщающего об ошибке, может быть вызвано настройками операционной системы. Например, компьютеры Macintosh могут пытаться записать файл на съёмный диск после его опознания. Загрузчик ожидает, что файл, записываемый в корневой каталог, имеет формат S19 и начинает процедуру его разбора. Файл другого формата вызовет ошибку при разборе. Данная ошибка исправляется изменением настроек, запрещающих операционной системе самостоятельную запись файлов на съёмные носители.


5.8 Ошибки при стирании/записи программной памяти

На ошибки стирании/записи программной памяти указывает появление файла статуса "FFAILED.TXT" после попытки провести обновление содержимого программной памяти. Данная ошибка возникает при попытке обращения к некорректному адресу программной памяти (в том числе защищённому) или неправильным установкам тактирования программной памяти. Проверьте карту распределения памяти, как описано в разделе "4.7 Перенос загрузчика на другие контроллеры". Кроме того, проверьте установки делителя частоты для программной памяти в процедуре " Bootloader_Main() " в файле "Bootloader_xx.c". В случае сохранения ошибки используйте отладчик для выяснения места возникновения ошибки и проверьте получаемый загрузчиком адрес.


5.9 Перекрёстные вызовы

Перекрёстные вызовы между загрузчиком и приложением очень опасны. Они могут проявляться в виде частичного затирания кода загрузчика или отказа приложения после обновления, особенно, при смене версий. Обратитесь к разделу "4.1 Предупреждение перекрёстных вызовов".



6 Заключение

Предлагаемый вариант загрузчика позволяет существенно облегчить процесс обновления программного обеспечения. Он не зависит от дополнительных драйверов для управляющего компьютера, не нуждается в дополнительных приложениях и не требует от обслуживающего персонала специальных знаний и навыков. Кроме того, он работает с широкой гаммой контроллеров Freescale, а данная статья показывает как включить загрузчик в любое приложение.

ПредпросмотрAttachmentSize
an3927_html.zip258.37 КБ