Программирование Файловые системы IAR EW ARM: как сделать USB Mass Storage Device на основе MMC/SD Tue, March 19 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

IAR EW ARM: как сделать USB Mass Storage Device на основе MMC/SD Печать
Добавил(а) microsin   

В этом примере я использовал отладочную плату Olimex SAM7-EX256 с микроконтроллером AT91SAM7X256. Карточка SD была на 512 мегабайт (хотя подходят и другие карточки MMC и SD). Использовался пример usb-device-massstorage-project от IAR и модули из библиотеки EFSL (для работы с карточкой SD/MMC по последовательному интерфейсу SPI), см. ссылки [2].

1. Берем за основу проект usb-device-massstorage-project из примеров IAR (находится в папке $TOOLKIT_DIR$\examples\Atmel\at91sam7x-ek\usb-device-massstorage-project\, или c:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\examples\Atmel\at91sam7x-ek\usb-device-massstorage-project\), копируем его в отдельную папку, добиваемся нормальной компиляции (правкой соответствующих опций и файлов, см. [6]).  Предположим, это будет папка c:\asm\MSD-MMC\. Компилировать надо для конфигурации проекта at91sam7x256_sram (поскольку в качестве памяти у нас пока выступает flash микроконтроллера). Проверяем, что наше устройство USB Mass Storage Device (далее просто MSD) работает - пробуем его отформатировать, читать и писать (MSD должно получиться размером 34 килобайта).

2. Теперь займемся подключением карточки SD. К картам SD/MMC можно обращаться через последовательный интерфейс, который реализован в карточке. В микроконтроллере этому интерфейсу соответствует SPI (в моем примере используется SPI0). Карточка запитывается от напряжения 3.3 вольт. При подключении к микроконтроллеру карточка работает под управлением микроконтроллера, т. е. в терминах SPI карточка является slave, а микроконтроллер - master. Используются следующие сигналы и питание:
1. CD - выход микроконтроллера, выборка карточки, активный сигнал 0. В моем примере это ножка 21 AT91SAM7X256, порт PA13, аппаратная выборка slave-устройства SPI0_NPSC1.
2. CMD - выход микроконтроллера, сигнал данных, поступающих в карточку. Подключен к ножке 25 AT91SAM7X256, порт PA17, сигнал MOSI интерфейса SPI0.
3. GND
4. +3.3V
5. CLK - выход микроконтроллера, тактовый сигнал, поступающий на карточку. Подключен к ножке 26 AT91SAM7X256, порт PA18, сигнал SPCK интерфейса SPI0.
6. GND
7. DAT0 - вход микроконтроллера, поток данных, поступающий от карточки. Подключен к ножке 24 AT91SAM7X256, порт PA16, сигнал MISO интерфейса SPI0.
8. Не используется, подключен нагрузочный pullup-резистор 100 к на +3.3V.
9. Не используется, подключен нагрузочный pullup-резистор 100 к на +3.3V.
    На плате Olimex все уже подключено, остается только запрограммировать микроконтроллер.

MMC_SD02.JPG MMC_SD01.JPG


конт.

сигнал
описание
Вариант подключения
 к SPI0, PIOA, периферия A
1 ~CS выборка карты (режим DAT3 не используется) PA13
2 MOSI данные, приходящие на вход карты PA17
3 GND минус питания карты, сигнальная земля  
4 VCC плюс питания карты, от 2.7 до 3.6 вольт, самый лучший вариант 3 вольта  
5 SCK такты данных, поступающие на вход карты PA18
6 GND минус питания карты, сигнальная земля  
7 MISO данные, уходящие с выхода карты (DAT0) PA16
8   не используется (DAT1)  
9   не используется (DAT2)  

3. Добавляем программную поддержку работы с карточкой.
- добавляем в проект файлы MEDmmc.c и MEDmmc.h. Их надо записать в папку at91lib\memories, и файл MEDmmc.c добавить в группу проекта at91lib\memories.
- добавляем в корень папки проекта папку efsl с её файлами, и настраиваем в опциях проекта пути до неё.
- делаем в проекте группу efsl и туда помещаем файлы efsl\sd.c и efsl\at91_spi.c.

4. В опциях проекта удаляем макроопределение sram и добавляем макроопределения at91sam7x256 (если его нет), MMC_MEDIA, OlimexDBG и NOTRACE (Project -> Options... -> C/C++ Compiler -> Preprocessor -> Defined symbols: (one per line)). Макрос MMC_MEDIA понадобится, чтобы включить поддержку SD/MMC. Макрос OlimexDBG нужен, чтобы мигал индикационный светодиод, который можно подключить к ножке 66 AT91SAM7X256 (порт PB21). Макрос NOTRACE нужен, чтобы отключить вывод в DBGU сообщений протокола USB, иначе наше MSD будет работать очень медленно.

5. Включаем поддержку пользовательского сброса. Этот шаг необязателен - если его не сделать, то вызов RSTC_SetUserResetEnable делать не надо. Добавляем в проект группу at91lib\peripherials\rstc и туда помещаем файл rstc.c.

6. Добавляем/правим в main:

#include < rstc/rstc.h>
#include < memories/MEDmmc.h>
...

//Порт PB21, ножка 66 - используется для
// тестирования программ как выход.

#define PIN_PB21_TEST66 {1 << 21, \
                         AT91C_BASE_PIOB, \
                         AT91C_ID_PIOB, \
                         PIO_OUTPUT_0, \
                         PIO_DEFAULT}
const Pin outPB21_66 = PIN_PB21_TEST66;
void LED (unsigned char on)
{
    on ? PIO_Set(&outPB21_66) : PIO_Clear(&outPB21_66);
}

volatile AT91PS_RSTC pRSTC = AT91C_BASE_RSTC;

...

int main()
{
    //разрешаем сброс от кнопки (если это Вам нужно)
    RSTC_SetUserResetEnable(pRSTC, 1);
    //запускаем вывод отладочных сообщений через DBGU
    #ifdef NOTRACE
    const Pin pinsDbgu[] = {PINS_DBGU};
    PIO_Configure(pinsDbgu, PIO_LISTSIZE(pinsDbgu));
    DBGU_Configure(DBGU_STANDARD, 115200, BOARD_MCK);
    #else
    trace_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK);
    #endif
    printf("-- USB Device Mass Storage Project 1.4 --\n\r");
    // If they are present, configure Vbus & Wake-up pins
    PIO_InitializeInterrupts(0);
    //тестовая ножка, управляющая светодиодом LED
    PIO_Configure(&outPB21_66, 1);

    WAKEUP_CONFIGURE();
    ...

    // Flash (only when NOT running in flash)
    #if defined(AT91C_BASE_EFC) && !defined(flash) && defined(FLASH_MEDIA)
        trace_LOG(trace_INFO, "LUN Flash\n\r");
        if (numMedias == 0)
        {
            FLA_Initialize(&(medias[numMedias]),
                           AT91C_BASE_EFC);
            LUN_Init(&(luns[numMedias]),
                     &(medias[numMedias]),
                     buffer,
                     30*1024, 34*1024, BLOCK_SIZE);
            numMedias++;
 
            // Install handler for flash interrupt
            AIC_ConfigureIT(AT91C_ID_SYS,
                            AT91C_AIC_PRIOR_LOWEST,
                            ISR_Media);
            AIC_EnableIT(AT91C_ID_SYS);
        }
    #endif
    #if defined(MMC_MEDIA)
        trace_LOG(trace_INFO, "LUN mmc\n\r");
        if (numMedias == 0)
        {
            MMC_Initialize(&(medias[numMedias]),
                           AT91C_BASE_SPI0);
            LUN_Init(&(luns[numMedias]),
                     &(medias[numMedias]),
                     buffer,
                     0, medias[numMedias].size, BLOCK_SIZE);
            numMedias++;
        }
    #endif
  ASSERT(numMedias > 0, "Error: No media defined.\n\r");
...

}

Это все! Теперь у Вас доступно USB Mass Storage Device на карточках SD/MMC, которое работает как обычная флешка. Правда, скорость у неё в разы меньше. Я пробовал разные карточки - MMC на 16 мегабайт и SD на 512 мегабайт, и получил скорость чтения 336 кбайт/сек, а скорость записи 180 кбайт/сек. Протокол приема-передачи на карточку через SPI сильно грузит AT91SAM7X256, поэтому для увеличения скорости желательно убрать все фоновые задачи из главного цикла main, а также все ненужные прерывания.

[Ссылки]

1. Готовый проект MSD-MMC можно скачать здесь.
2. Сайт EFSL.
3. IAR EW ARM: работа с файловой системой FAT на карточках SD/MMC.
4. Библиотека EFSL.
5. Другая популярная реализации файловой системы для микроконтроллеров - Petit FAT File System Module. См. также FatFs Generic FAT File System Module, как использовать SD/MMC.
6. IAR EW ARM: как перенести проект в другую папку.

 

Добавить комментарий


Защитный код
Обновить

Top of Page