AVR273: реализация флешки USB на AVR с аппаратным USB Печать
Добавил(а) microsin   

Перевод апноута AVR273: USB Mass Storage Implementation on megaAVR with USB [1], рассказывающий про демонстрационный код устройства USB Mass Storage - обычная флешка, подключаемая через USB. Исходный код и документацию можно скачать по ссылке [2].

Особенности реализации USB Mass Storage:

• В транспортном протоколе используются только bulk-передачи.
• Флешка получается стандартная, т. е. она работает с компьютером PC, на котором установлена любая операционная система (Windows® 98SE или более свежая, Linux® Kernel 2.4 или более свежая, Mac OS® 9/x или более свежая).
• Проект полностью основывается на носителе данных DataFlash (микросхема, запаянная в стартерките STK525), но может быть применен и другой носитель данных (например, память NF, карточка SD/MMC, и т. п.).
• Проект может быть реализован на любом микроконтроллере AVR с аппаратным интерфейсом USB (AVR USB).

Исходный код можно скачать по ссылке [2] (см. папку USB USB Mass Storage).

Прим. переводчика: описанный пример USB Mass Storage используется в реализации U-Disk даташита AVR115 [8]. Кроме того, в библиотеке LUFA также есть готовый проект USB Mass Storage с исходным кодом, который можно скомпилировать на любой микроконтроллер AVR с аппаратным интерфейсом USB (см. [2], папки LUFA-130901\Demos\Device\ClassDriver\MassStorage и LowLevel\MassStorage архива). Проекты из LUFA удобнее тем, что их можно скомпилировать практически под любую макетную плату, имеющуюся на рынке. Все примеры кода из архива [2] можно с успехом запустить на макетных платах AVR-USB162, AVR-USB162MU, userial, AVR-USB32U4 [6].

[1. Введение]

Эпоха floppy-дисков давно закончилась (они малы по объему хранимых данных, медленные и слишком хрупкие). CD-ROM и DVD также неудобны для обмена данными (они обычно с однократной записью, перезаписываемые диски не очень надежны) и плохо подходят для путешествий. Флешки USB (USB Mass Storage class) имеют физические размеры меньше, чем floppy-диск, а емкостью давно превышают CD-ROM.

AVR273-USB-Mass-Storage

Atmel предоставляет полное решение Mass Storage class на микросхемах памяти Atmel DataFlash. Это обеспечивает полнодуплексный перенос данных между устройством USB и компьютером PC. Цель этого даташита - дать описание, как создать USB-приложение, основанное на классе Mass Storage (передачи только bulk), предназначенное для передачи данных между PC и окружением пользователя. Подразумевается, что читатель знаком с библиотекой USB Software Library for AT90USBxxx Microcontrollers [3] (поставляется бесплатно на CD-ROM, и её также можно скачать с сайта Atmel) и со стандартом Mass Storage specification [4].

Прим. переводчика: за разъяснением специфических терминов стандарта USB (энумерация, конечная точка endpoint, polling, request, report, хост USB, bulk, устройство USB и т. д.) лучше обратиться к документу USB in a Nutshell [7].

[2. Требования к аппаратуре]

Приложение firmware для клавиатуры USB требует следующую аппаратуру:

• Отладочную плату с микроконтроллером AVR USB (STK525, AT90USBKey, STK526, или это может быть Ваша собственная плата) и прошитым (желательно) в него загрузчиком (USB bootloader DFU Flip).
• Стандартный кабель USB, если он нужен для подключения к Вашей плате (например, на одной стороне должен быть стандартный коннектор типа A, а на другой коннектор типа Mini B).
• Компьютер, на котором установлена операционная система Windows (98SE, ME, 2000, XP и т. д.), Linux или MAC OS, поддерживающие хост USB стандартов USB 1.1 или USB 2.0.

Firmware флешки USB Вы также можете запустить на макетных платах AVR-USB162, AVR-USB162MU, userial, AVR-USB32U4, если подключите какой-нибудь носитель данных.

[3. Как можно запрограммировать Ваш чип AVR USB]

Для того, чтобы прошить память микроконтроллера, Вы можете использовать следующие методы:

• Интерфейс JTAG, для этого нужен аппаратный отладчик JTAGICE mkII(2).
• Интерфейс ISP (SPI), для этого можно использовать программаторы AVRISP mkII, AVR Dragon (прим. переводчика: и множество других программаторов [5]) и отладчик JTAGICE mkII(2).
• Интерфейс USB, благодаря прошитому в память микроконтроллера (это уже сделано на заводе Atmel) DFU bootloader и программному обеспечению FLIP(1). Этот способ наиболее практичен и удобен.
• Параллельное программирование, для этого нужны программаторы STK®500 или STK600.

Примечания:
(1) Программа-утилита FLIP предоставляется компанией Atmel, чтобы позволить пользователю прошить устройства AVR USB (и другие) через подключение USB, что не требует никакой дополнительной аппаратуры типа отладчиков и программаторов. Прием данных через USB и перепрошивку памяти программ берет на себя бутлоадер DFU, заранее прошитый в память чипа на заводе Atmel.
(2) При использовании JTAGICE MKII будьте осторожны с галочкой "erase before programming" (очистить перед программированием) в утилите программатора AVR Studio®. Если эта галочка установлена, то это приведет к стиранию как программы пользователя, так и к стиранию бутлоадера DFU. Прим. переводчика: при необходимости бутлоадер всегда можно восстановить с помощью ISP-программатора, бинарник бутлоадера можно скачать с сайта Atmel.

Пожалуйста обратитесь к содержимому справки FLIP для того, чтобы узнать, как установить драйвер USB и как запрограммировать микроконтроллер ATmega32U4 через интерфейс USB.

Прим. переводчика: простые указания на русском языке по установке драйвера USB и перепрошивке микроконтроллера через FLIP можно получить из статьи "Макетная плата AVR-USB32U4" [6].

[6. Быстрый старт]

Если используете стартеркит STK525, то установите перемычки для управления питания VCC так, чтобы плата питалась от шины USB.

AVR273-STK525-as-Mass-Storage-example AVR273-STK525-VCC-jumpers

Для стартеркита usbkey не требуется установка никаких перемычек.

AVR273-usbkey-as-Mass-Storage-example

Как только прошили Ваш микроконтроллер файлом ms_df_stk525.a90 (этот файл для STK525) проекта USB Mass Storage [2], Вы можете запустить демонстрацию работы флешки USB. Проверьте, что Ваше устройство USB успешно прошло энумерацию как Mass Storage device (см. скриншот окна Диспетчера Устройств), и теперь Вы может использовать Вашу плату как извлекаемый диск. Например, можно скопировать любые файлы подходящего размера в носитель памяти Вашей платы.

[7. Обзор приложения USB Mass Storage]

В обмене данными через интерфейс USB участвуют хост USB (компьютер PC с запущенно операционной системой) и устройство USB Mass Storage (Ваша макетная плата с подключенным носителем данных и запрограммированным микроконтроллером AVR USB). Обмен данными основан на командах SCSI (Small Computer System Interface), с использованием двух конечных точек типа bulk (одна конечная точка типа IN, другая конечная точка типа OUT) для передачи данных файловой системы и данных состояния. Имеется еще одна конечная точка, endpoint 0 (control endpoint, конечная точка управления, или конечная точка по умолчанию), которая используется для процедуры энумерации, обработки ошибок и определения значения LUN (Logical Unit Number, адрес диска - понятие, относящееся к протоколу SCSI).

Другими словами, приложение Mass Storage состоит из набора команд SCSI, которые отправляет хост USB для управления передачами файлов (и просто для поддержки файловой системы на носителе данных). Класс Mass Storage позволяет одному устройству управлять несколькими юнитами носителя данных одновременно, благодаря наличию адресации через LUN (Logic Unit Number). На рисунке ниже показано, как хост видит устройство Mass Storage.

AVR273-USB-Mass-Storage-Application-Overview

Рис. 7-1. Обзор приложения Mass Storage.

Стандартная процедура энумерации (она происходит одинаково для всех классов устройств USB), выполняется через конечную точку 0 (default
control endpoint, конечная точка управления по умолчанию). Эта процедура состоит в установке набора параметров, отправляемых от устройства USB к хосту USB, чтобы хост мог определить класс устройства USB и загрузить для его поддержки подходящие драйверы. Эти параметры находятся в дескрипторах устройства USB (они называются просто дескрипторами, описателями устройства USB).

Команды SCSI выполняются с использованием обоих конечных точек данных (IN или OUT). Каждая операция SCSI декодируется и передается к подходящему юниту носителя данных (Storage Unit) через набор команд (Read, Write, есть ли носитель данных, защищен ли носитель от записи, и т. п.). Ответ памяти преобразовывается в состояние SCSI перед тем, как он будет обернут в USB CSW (Command Status Wrapper) и отправлен контроллеру хоста USB (USB Host controller).

Так как шина USB по стандарту имеет единственного мастера (хост USB, главное устройство на шине, которое задает обмен данными и управляет им), каждая передача данных по шине USB инициируется хостом USB, с последующим специфичным потоком команд, данных и состояния (Command-Data-Status flow, см. рисунок ниже).

AVR273-Command-Data-Status-Flow

Рис. 7-2. Поток команд, данных и состояния (Command/Data/Status Flow).

CBW (Command Block Wrapper) содержит некую информацию USB, такую как адресуемый LUN, длину команды SCSI, и конечно содержит команду SCSI для памяти. CSW (Command Status Wrapper) содержит информацию состояния SCSI. Если состояние GOOD (в порядке), хост оправит следующую по порядку команду. Если статус отличается от GOOD (FAILED, PHASE ERROR, и проч.), хост запросит дополнительную информацию, касающуюся ошибки (с помощью отправки команды REQUEST SENSE).

На картинке ниже дан обзор решения, предлагаемого Atmel, с использованием носителя данных DataFlash, одно решение для STK525, и два для AT90USBKey. Физические носители могут быть привязаны к тому же самому LUN, и использовать чередование, чтобы уменьшить видимое для пользователя время доступа на запись. Максимальный размер диска на один LUN ограничен стандартом SCSI, используемым операционной системой хоста (Read10/Write10 и Read16/Write16). Read10/Write10 использует информацию о размере, закодированную в 4 байтах (максимальный размер 2 терабайта), и Read16/Write16 в 8 байтах (максимум порядка 8 зеттабайт).

AVR273-Atmel-Mass-Storage-Solution

Рис. 7-3. Структура решения Atmel Mass Storage.

[8. Обзор кода firmware флешки USB Mass Storage]

Как было объяснено в документе [3], все пакеты примеров касательно устройств USB Atmel (клавиатуры, мыши, устройства USB HID, устройства USB CDC и проч.) основаны на одной и той же архитектуре.

AVR273-USB-Mass-Storage-Firmware-Architecture

Рис. 8-1. Архитектура USB Mass Storage Firmware.

Эта секция посвящена только модулю Mass Storage. Чтобы переделать это firmware под свои нужды, Вам нужно всего лишь модифицировать код, работающий с Вашим носителем памяти. Далее идет описание модулей (файлов) и функций, которые можно найти в соответствующем модуле Mass Storage.

8.1 storage_task.c

Этот файл содержит функции для инициализации параметров аппаратуры, используемой в приложении (SPI, микросхемы DataFlash, светодиоды LED), и функции для обработки команд, отправляемых хостом (Command Block Wrapper CBW, Command Status Wrapper CSW).

AVR273-Mass-Storage-task

Рис. 8-2. Задача Mass Storage.

8.1.1 storage_task_init

Эта функция выполняет инициализацию параметров устройства и аппаратных ресурсов.

8.1.2 usb_mass_storage_cbw

Эта функция декодирует CBW (Command Block Wrapper) и сохраняет команду SCSI.

8.1.3 usb_mass_storage_csw

Функция отправляет состояние (CSW: Command Status Wrapper) для последнего CBW.

8.2 stk_525.c / usbkey.c

Этот файл содержит все подпрограммы, касающиеся управления ресурсами платы STK525 (джойстик, потенциометр, термодатчик, светодиоды...). Пользователю не нужно модифицировать этот файл, если он использует плату STK525. Иначе на основе файла stk_525.c. нужно сделать свой собственный файл для управления аппаратными ресурсами Вашей платы.

8.3 Управление носителем данных

Каждый тип памяти, который можно подключить к firmware Atmel, поддерживается соответствующим специальным драйвером памяти (memory driver). Следующие функции должны быть реализованы для того, чтобы USB Mass Storage Device firmware могло выполнять свои функции как извлекаемый диск (флешка). Чтобы поддерживать другой, новый тип памяти для носителя данных, разработчик должен написать memory driver в соответствии с аппаратным интерфейсом используемой памяти. Некоторые функции возвращают только состояние памяти (установлен носитель или нет, защищен ли он от записи, общая емкость, и является ли он извлекаемым). Другие функции используются для физического чтения и записи данных на носителе. Функции read_10 и write_10 открывают память по указанному месту на носителе. Функции usb_read и usb_write обслуживают передачу данных между контроллером USB и памятью носителя данных. Большинство этих функций возвращает байт состояния Ctrl_status, который может содержать в себе:

• CTRL_GOOD: этот статус означает, что может быть отправлена другая команда (PASS).
• CTRL_FAIL: означает ошибку в выполнении команды (FAIL).
• CTRL_NO_PRESENT: носитель памяти отсутствует.
• CTRL_BUSY: текущий носитель памяти не инициализирован или его состояние поменялось (носитель занят, BUSY).

8.3.1 sbc_test_unit_ready

Эта функция возвращает состояние памяти.

AVR273-sbc test_unit_ready

Рис. 8-3. Алгоритм работы функции sbc_test_unit_ready.

8.3.2 sbc_read_capacity

Эта функция возвращает адрес последнего валидного сектора, сохраненный в переменной u32_nb_sector. Размер сектора фиксирован и составляет 512 байт для сохранения совместимости с операционными системами.

Например, для памяти 16 килобайт функция вернет ((16 x 1024)/512)-1) = 31.

AVR273-sbc read_capacity

Рис. 8-4. Алгоритм работы функции sbc_read_capacity.

8.3.3 sbc_read_10

Эта функция устанавливает адрес сектора (addr) и количество читаемых друг за другом секторов (каждый сектор размером 512 байт).

AVR273-sbc read_10

Рис. 8-5. Алгоритм работы функции sbc_read_10.

8.3.4 sbc_write_10

Эта функция устанавливает адрес сектора (addr) и количество записываемых друг за другом секторов (каждый сектор размером 512 байт).

AVR273-sbc write_10

Рис. 8-6. Алгоритм работы функции sbc_write_10.

8.3.5 mem_wr_protect, mem_removal

Функция mem_wr_protect вернет FALSE, если память не защищена от записи, и TRUE если носитель имеет защиту от записи. Функция mem_removal вернет FALSE, если носитель данных неизвлекаемый, и TRUE носитель извлекаемый.

8.4 Как встроить в проект поддержку нового типа памяти (носителя данных)

Интеграция памяти в стек функций USB Mass Storage выполняется через заголовочный файл conf_access.h. Соответствующий LUN сначала должен быть установлен в ENABLE, и должны быть определены соответствующие функции (sbc_test_unit_ready, sbc_read_capacity, sbc_read_10, sbc_write_10, mem_wr_protect, mem_removal).

Стек функций USB Mass Storage поддерживает до 8 разных LUN. В этом примере память DataFlash привязана к LUN_3:

// Активные LUN
#define LUN_0 DISABLE // Виртуальная память, встроенная в чип (FLASH)
#define LUN_1 DISABLE // NF 2 килобайта
#define LUN_2 DISABLE // NF 512 байт
#define LUN_3 ENABLE // микросхемы Data Flash
#define LUN_4 DISABLE
#define LUN_5 DISABLE
#define LUN_6 DISABLE
#define LUN_7 DISABLE
// Определения для LUN 3
#if (LUN_3 == ENABLE)
   #define DF_MEM ENABLE
#else
   #defineDF_MEM DISABLE
#endif
#define LUN_3_INCLUDE "lib_mem\df\df_mem.h"
#define Lun_3_test_unit_ready() df_test_unit_ready()
#define Lun_3_read_capacity(nb_sect) df_read_capacity(nb_sect)
#define Lun_3_wr_protect() df_wr_protect()
#define Lun_3_removal() df_removal()
#define Lun_3_read_10(ad, sec) df_read_10(ad, sec)
#define Lun_3_usb_read() df_usb_read()
#define Lun_3_write_10(ad, sec) df_write_10(ad, sec)
#define Lun_3_usb_write() df_usb_write()

9. Необходимое программное обеспечение компьютера PC

Устройство USB Mass Storage не требует для своей работы никакого дополнительного программного обеспечения. Однако на операционной Windows 98SE нужно установить драйверы, которые поставляются Atmel вместе с пакетом Mass Storage.

[Ссылки]

1. AVR273: USB Mass Storage Implementation on megaAVR with USB site:atmel.com.
2131122AVR270_AVR271_AVR272_AVR273.zip.
3AVR276: USB Software Library for AT90USBxxx Microcontrollers.
4HID Related Specifications site:usb.org.
5Программаторы для AVR.
6Макетная плата AVR-USB32U4.
7USB in a NutShell - путеводитель по стандарту USB.
8. AVR115: сбор данных с использованием Atmel File System.