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





2 Функциональное описание


2.1 Общее описание

Загрузчик объединён с целевым приложением, реализующим основные функции устройства. Загрузчик запускается сразу после сброса контроллера и проводит несколько простых проверок для выбора между переходом к выполнению основного цикла загрузчика или стартом рабочей программы устройства. Если выбрано продолжение работы загрузчика, то устройство опознаётся подсистемой USB управляющего компьютера. В процессе опознания устройство декларирует себя как съёмный носитель данных, после чего управляющий компьютер монтирует в системе новый диск. Пользователь может копировать на этот диск файл в формате S19, вызывая тем самым процесс обновления программной памяти устройства.

Файл в формате S19 - текстовый файл, используемый для хранения содержимого программной памяти устройства. Среда разработки компании Freescale, называемая CodeWarrior, создаёт этот файл автоматически в результате компиляции проекта. Файлы такого формата имеют расширение ".s19" и в дальнейшем будут называться "файл S19".

После завершения передачи файла S19 устройству и окончания процесса обновления программной памяти, устройство перезапускает процедуру опознания нового устройства на шине USB. Файл, находящийся на диске, отражает статус текущей операции.


Рисунок 1. Структурная схема загрузчика
Рисунок 1. Структурная схема загрузчика


2.2 Режимы загрузчика и приложения

Загрузчик запускается сразу после сброса контроллера для выяснения в какой из режимов следует переводить устройство. Запуск загрузчика после сброса очень важен для случаев отсутствия или повреждения целевого приложения. При нормальном развитии событий загрузчик пытается перейти в прикладной режим. Каковой переход производится по вектору пользователя, ячейке памяти, расположенной по определённому адресу и содержащей адрес точки входа, то есть начала целевой программы. Вектор используется для предупреждения "перекрёстного вызова" (см. раздел "4.1 Предупреждение перекрёстных вызовов"). Абсолютный адрес начала программы может меняться в процессе правки и перекомпиляции программы, но вектор - адрес ячейки памяти, в которой хранится адрес начала приложения, - неизменен. Таким образом загрузчик всегда переходит по абсолютному адресу вектора пользователя и оттуда на начало целевой программы.

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

Процедура обновления приложения может быть активирована принудительно в процессе сброса контроллера. Прилагаемые примеры следят за состоянием кнопки и если она нажата в процессе сброса, то загрузчик запускается принудительно, независимо от состояния вектора пользователя. Обозначение кнопки зависит от используемой отладочной платы. Обратитесь к разделу "4.2 Использование загрузчика с отладочными платами" за деталями. Реальные задачи могут потребовать изменения процедуры запуска загрузчика. Сделать это можно модификацией файла "user_entry_xx.c".


2.3 Опознание USB устройств

После того, как загрузчик перешел в режим обновления, он разрешает подсистеме USB контроллера начать обмен с управляющим компьютером. Данное действие запускает процесс опознания нового устройства на шине USB, которое подробно описано в статье "Шина USB и использование стека USB фирмы CMX" (AN3492). В предлагаемом загрузчике используется облегченный стек USB компании Freescale, занимающий очень мало места в памяти. Устройство объявляет себя накопителем данных, посылая управляющей системе соответствующий описатель. Управляющая система монтирует устройство, как новый диск, и использует для обмена BULK режим. Через BULK сеансы обмена передаются SCSI команды для управления тем, что управляющий компьютер считает съёмным накопителем данных.


2.4. Псевдо FAT

Управляющий компьютер, определивший устройство, как накопитель данных, пытается считать FAT - таблицу размещения файлов и выяснить содержимое диска. Загрузчик отвечает на запросы управляющего компьютера, как диск объёмом 1GB с меткой тома - "BOOTLOADER", в корневом каталоге которого располагается файл "READY.TXT". Подкаталоги отсутствуют. В реальности загрузчик не использует какую-либо файловую систему и только имитирует работу диска. Загрузчик может принимать файлы S19, но тот факт, что он лишь имитирует файловую систему, не позволяет ему изменять FAT когда управляющий компьютер пытается это сделать. Содержимое FAT фиксировано и единственное возможное изменение - изменение имени файла в корневом каталоге, отображающего статус загрузчика. Загрузчик игнорирует любые данные, которые пишутся не в корневой каталог "диска". Если данные пишутся в корневой каталог, то предполагается, что идёт запись файла S19. Факт записи на диск запускает процесс разбора формата S19 для получения нового содержимого программной памяти. После сброса контроллера возможна запись только одного файла. После завершения передачи загрузчик должен быть перезапущен, чтобы он мог принять другой файл.


2.5 Разбор записей формата S19

Загрузчик включает в свой состав процедуру разбора файлов в формате S19, позволяющую пересылать их в устройство без предварительной обработки. Пересылаемые загрузчику файлы считаются файлами S19 и после начала приёма файла запускается процесс его разбора. Каждая строка файла проверяется на соответствие формату, проверяется правильность контрольной суммы, принадлежность целевого адреса записи области приложения. Загрузчик проверяет все строки, но игнорирует данные, расположенные вне адресного пространстве целевого приложения. Затем производится запись данных из проверенной строки в программную память. Процесс передачи, проверки и записи прекращается после обнаружения строк с типами " S7 ", " S8 " и " S9 ", знаменующих собой окончание файла. Если все строки были корректными и запись в программную память безошибочной, процедура разбора возвращает признак успешного выполнения и передаёт управление загрузчику. Если же при проверке какой-либо из строк будет зафиксирована ошибка, процедура разбора возвратит содержимое поля адреса сбойной строки.

Примечание.
Процедура разбора формата S19 не привязана к подсистеме USB или программе загрузчика и может применяться в других приложениях. Если требуется другой способ передачи данных, функция " GetUSBchar() " должна быть заменена новой, принимающей символ через другой интерфейс (UART, CAN и т.д.).


2.6 Повторное опознание устройства

После возврата из процедуры разбора формата S19, загрузчик инициирует повторное опознание устройства для обновления "файла" статуса на "диске" (собственно файл статуса обсуждается в разделе "2.7 Статус загрузчика"). Со стороны управляющего компьютера данный процесс виден, как кратковременное отключение съёмного устройства от шины USB. Через несколько секунд после повторного подключения к шине, устройство определяется системой и диск появляется снова. Файл на диске отражает текущей статус загрузчика.

Повторное опознание требуется из-за того, что некоторые операционные системы кэшируют диски и не обновляют информацию о файлах. К примеру, операционная система "Fedora 8" не пишет файл до момента размонтирования диска. После размонтирования устройство получает файл S19, обновляет содержимое программной памяти, после чего повторно опознаётся для отображения статуса. Операционные системы "XP" и "Vista" кэшируют таблицу размещения файлов на диске и не читают её в дальнейшем, что не позволяет обновить файл статуса. Процедура повторного опознания заставляет операционную систему заново считать FAT с диска и отобразить статус загрузчика.


2.7 Статус загрузчика

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

  •  READY.TXT
    загрузчик готов к приёму файла в формате S19.
     
  •  SUCCESS.TXT
    загрузчик успешно завершил процесс обновления программной памяти.
     
  •  FFAILED.TXT
    ошибка операции стирания или записи программной памяти. Данная ошибка возникает при ошибках исполнения соответствующих процедур загрузчика. Обычная причина подобного результата - неправильная настройка тактирования программной памяти, либо выход за допустимый диапазон адресов. Например, адрес не является адресом программной памяти или указывает на защищённую область памяти. Для уточнения конкретных причин следует ставить точку останова на месте формирования сообщения об ошибке в файле "ParseS19.c".
     
  •  SFxxxxxx.TXT
    ошибка при разборе строки файла S19. Ошибка возникает в случае неправильного формата строки, ошибки контрольной суммы или некорректного целевого адреса. Содержимое поля адреса из проблемной строки подставляется в имя файла. Например, в случае ошибки в записи для адреса 0x1234 файл будет называться "SF001234.TXT". При появлении данной ошибки надо проверять файл S19 на правильность формата, адреса и контрольной суммы.
     
  •  STARTED.TXT
    программный файл для корневого каталога "диска" принят и запущена процедура его разбора. Обычно данный файл конечному пользователю не виден, так как устройство запускает повторную процедуру опознания только после успешного или неуспешного завершения процедуры разбора файла S19 или записи программной памяти. Если данный файл виден, то надо запускать отладчик и выяснять причину.
     


2.8 Защита программной памяти

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

Загрузчик использует особенности защиты программной памяти контроллеров фирмы Freescale. Контроллеры данной фирмы имеют специальный энергонезависимый регистр, сохраняющий информацию о защищаемых секторах памяти. В защищаемых секторах располагается загрузчик, в незащищаемых - целевая программа. Энергонезависимые регистры находятся в ведении загрузчика и защищены от изменений. Кроме того, от изменений со стороны целевой программы защищается таблица векторов прерываний.

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

  •  ColdFire V2:
    регистр CFMPROT устанавливается в 0x1 и защищает адреса 0x0000 ... 0x3FFF . Манипуляции с регистром производятся в файле "mcf5225x_vectors.s".
     
  •  ColdFire V1:
    регистр NVPROT устанавливается в 0x7F и защищает адреса 0x0000 ... 0x1FFF . Манипуляции с регистром производится в файле "Bootloader_V1.c".
     
  •  MC9S08:
    регистр NVPROT устанавливается в 0xEA и защищает адреса 0xEC00 ... 0xFFFF . Манипуляции с регистром производится в файле "Bootloader_S08.c".
     

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


2.9. Переадресация таблицы векторов прерываний

Целевое приложение не может изменять таблицу векторов прерываний контроллера, так как она находится в защищённой памяти. По этой причине вектора прерываний переназначаются в память целевой программы, что позволяет этой последней их менять. Факт переадресации таблицы векторов прерываний не позволяет использовать прерывания самому загрузчику.(*) По этой причине для обнаружения событий в модуле USB загрузчик использует опрос флага прерывания.

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

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


2.10. Использование стека и оперативной памяти

Загрузчик взаимодействует с целевой программой только один раз - когда он запускает её, переходя по адресу из вектора пользователя. Целевая программа никогда не вызывает функций загрузчика. Таким образом нет нужды в раздельных областях оперативной памяти для загрузчика и приложения - они могут использовать одну и ту же физическую оперативную память и целевая программа будет иметь доступ ко всему наличному её объёму. Файлы компоновщика настроены так, чтобы загрузчик и целевая программа совместно использовали один объём физической памяти. Всё вышеперечисленное можно сказать и про стек. Таким образом, объём и расположение стека загрузчика и приложения также совпадают.


2.11 Карты распределения памяти

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


2.11.1 Карта памяти загрузчика для ColdFire V2


Таблица 1. Карта памяти загрузчика для MCF52259
 
0x0000_0000...0x0000_03FF Вектора прерываний и исключений
0x0000_0400...0x0000_0417 Регистры доступа и защиты памяти программ
0x0000_0420...0x0000_3FFF Код загрузчика (15 KB)
0x0000_4000...0x0000_400F Вектор пользователя (16 байт)
0x0000_4010...0x0007_FFFF Программная память приложения (496 KB)
0x0008_0000...0x1FFF_FFFF Зарезервировано
0x2000_0000...0x2000_03FF Переназначенные в RAM вектора прерываний
0x2000_0400...0x2000_05FF USB буфера загрузчика или RAM приложения (63 KB)
0x2000_0600...0x2000_F7FF
0x2000_F800...0x2000_FFFF Стек (2 KB)
 


2.11.2 Карта памяти загрузчика для ColdFire V1


Таблица 2. Карта памяти загрузчика для MCF51JM128
 
0x(00)00_0000...0x(00)00_03FF Вектора прерываний и исключений
0x(00)00_0400...0x(00)00_040F Регистры доступа и защиты памяти программ
0x(00)00_0410...0x(00)00_1FFF Код загрузчика (7 KB)
0x(00)00_2000...0x(00)00_21BF Вектора прерываний целевого приложения
0x(00)00_21C0...0x(00)00_21C7 Вектор пользователя (8 байт)
0x(00)00_21C8...0x(00)00_21FF Не используется
0x(00)00_2200...0x(00)01_FFFF Программная память приложения (119 KB)
0x(00)20_0000...0x(00)7F_FFFF Зарезервировано
0x(00)80_0000...0x(00)80_01FF Переназначенные в RAM вектора прерываний
0x(00)80_0200...0x(00)80_06DF USB буфера загрузчика или RAM приложения
0x(00)80_06E0...0x(00)80_3BFF RAM загрузчика или приложения (14.5 KB)
0x(00)80_3C00...0x(00)80_3FFF Стек (1 KB)
 

(*) Примечание переводчика.
Скобки в адресе отражают тот факт, что в 32-разрядном ядре ColdFire V1 пользователь не может управлять 8-ю старшими битами адреса.


2.11.3 Карта памяти загрузчика для MC9S08


Таблица 3. Карта памяти загрузчика для MC9S08JM60
 
0x0000...0x00AF Direct page registers
0x00B0...0x00FF Нулевая страница оперативной памяти
0x0100...0x105F Доступная оперативная память (3.8 KB)
0x1060...0x10AF Стек (80 байт)
0x10B0...0x17FF Программная память приложения (1872 байт)
0x1800...0x185F High page registers
0x1860...0x195F USB BDTs и буфера
0x1960...0xEBA5 Программная память приложения (52.5 KB)
0xEBA6...0xEBFC Таблица векторов прерывания приложения
0xEBFD...0xEBFF Вектор пользователя (3 байта)
0xEC00...0xFFAD Программная память загрузчика (5 KB)
0xFFAE...0xFFBF Регистры доступа и защиты памяти программ
0xFFC0...0xFFFF Таблица векторов контроллера
 


2.12 Использование ресурсов

Таблица 4 показывает используемую загрузчиком память в вариантах для трёх версий вычислительного ядра. В разделе "2.8 Защита программной памяти" обсуждалась защита загрузчика от перезаписи. Объём программной памяти, отводимой под загрузчик, определяется размерами кода и минимально возможным шагом изменения объёма защищаемой памяти, различным для различных версий ядра.


Таблица 4. Используемая загрузчиком защищённая память (килобайты)
 
  Размер кода загрузчика Размер занимаемой памяти
ColdFire_V2 9KB 16KB
ColdFire_V1 7KB 8KB
MC9S08 5KB 5KB
 
ПредпросмотрAttachmentSize
an3927_html.zip258.37 КБ