Муфты электромонтажные от производителя Fucon
РадиоЛоцман - Все об электронике

Использование SD-карт в малых встраиваемых системах. Часть 1

Журнал РАДИОЛОЦМАН, ноябрь 2013

Михаил Русских

Приводится краткая информация о SD-картах, даются основы принципа работы шины SD, поясняется порядок использования драйвера stm324xg_eval_sdio_sd, предназначенного для упрощения связи микроконтроллеров семейства STM32 с SD-картами

Технология правильного хранения аккумуляторов и батареек по рекомендациям FANSO и EVE Energy

Некоторые встраиваемые системы должны иметь возможность хранения больших объемов информации. Например, регистраторы различных физических величин и параметров (ток, напряжение, температура, географические координаты) должны сохранять полученные с датчиков показания на определенном носителе, который впоследствии можно было бы извлечь из устройства и подключить к компьютеру для просмотра данных в удобном для пользователя виде. Для решения такой задачи наиболее очевидным кажется использование USB флеш-накопителей. Они широко распространены на рынке и позволяют хранить большие объемы информации. Но для некоторых малых встраиваемых систем первостепенным фактором является компактность, и габариты этих накопителей могут оказаться чрезмерными. Кроме того, не все микроконтроллеры оснащены модулем USB, и разработчик системы может довольно долго разбираться с USB-стеком, что может увеличить время работы над проектом. В связи с этим хорошей альтернативой USB является использование SD-карт, которые очень компактны и позволяют обмениваться данными с помощью распространенного интерфейса SPI или специального интерфейса для SD-карт.

Карты памяти SD (Secure Digital) разработаны, в основном, для применения в портативных устройствах. Сегодня на рынке существует большое количество моделей, предоставляемых такими компаниями как SanDisc, Toshiba, Panasonic, и способных записывать с зависящей от класса скоростью данные объемом от 8 МБ до 2 ТБ. SD-карты, в отличие от MMC-карт, помимо обычной области хранения данных имеют специальную защищенную область, которая недоступна обычному пользователю. Для того чтобы устройство смогло прочитать записанную на SD-карту информацию в виде файлов, эта карта должна иметь определенную файловую систему. Наиболее предпочтительной в данном случае является система FAT, поскольку количество циклов записи/чтения для SD-карт ограничено, а системы вроде NTFS и ext являются журналируемыми, то есть предполагающими частые опросы.

Использование SD-карт в малых встраиваемых системах
 
Рисунок 1. Расположение и нумерация выводов SD-карт.

Передача и прием данных осуществляется по интерфейсу SPI или по шине SD. На Рисунке 1 показано расположение выводов SD-карт различных типов, а в Таблице 1 представлено функциональное назначение этих выводов.

Таблица 1. Функциональное назначение выводов SD-карт
Интерфейс SPI
DO
 
 
CS
DI
SCLK
UПИТ
GND
Не исп.
Интерфейс SD
DAT0
DAT1
DAT2
DAT3
CMD
CLK
UПИТ
GND
Не исп.
Карты SDC
7
8
9
1
2
5
4
3, 6
 
Карты miniSD
7
8
9
1
2
5
4
3, 6
10, 11
Карты microSD
7
8
1
2
3
5
4
6
 

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

Передача данных по шине SD

Связь с SD-картой осуществляется по 6 информационным линиям: 4 линиям данных (DAT0, DAT1, DAT2, DAT3), линии синхронизации (CLK), линии передачи команд (CMD). При подключении к контроллеру линии данных и линия передачи команд должны быть подтянуты к питанию, как показано на Рисунке 2.

Использование SD-карт в малых встраиваемых системах
 
Рисунок 2. Подключение SD-карты к микроконтроллеру.

Запись и чтение данных выполняются поблочно. Обычно блок состоит из 512 байтов. Передача данных и служебной информации основана на модели взаимодействия «команда-ответ». Перед передачей или приемом данных хост-контроллер должен отправить соответствующую команду по линии CMD. По этой же линии от SD-карты должен прийти ответ, после которого может быть осуществлено требуемое действие. Стандарт SD поддерживает присутствие нескольких ведомых на шине, в таком случае хост-контроллер может посылать команды широковещательно. Команда имеет четкую структуру, состоящую из 48 бит: 1 стартовый бит, 1 бит передачи (установлен в 1), 6 бит для индекса команды, 32 бита для аргумента, 7 бит для контрольной суммы и 1 стоповый бит. Ответ может иметь такую же 48-битную структуру (в этом случае бит передачи установлен в 0) или состоять из 136 битов (т. н. формат длинного ответа): 1 стартовый бит, 1 бит передачи (установлен в 0), 6 зарезервированных битов, 127 битов содержимого регистров CID (Card Identifiction Register) или CSD (Card Specific Data Register) и контрольной суммы, 1 стоповый бит.

В начале работы с картой хост-контроллер перезагружает карту с помощью команд GO_IDLE_STATE (CMD0) и IO_RW_DIRECT (CMD52). Полный список команд с описанием можно найти в [1] (приложение A). После перезагрузки карта восстановит свои настройки по умолчанию, и ее адрес будет равен RCA = 0x0001. Если к хосту подключено несколько карт, то с помощью команды SET_RELATIVE_ADDR (CMD3) он задает каждой карте собственный адрес. Также в начале работы выполняется проверка поданного на карту напряжения. Напряжение карты должно быть в строго установленном диапазоне от 2.7 до 3.6 В. В связи с этим хост-контроллер с помощью команды SEND_OP_COND (CMD1 или ACMD41) обязан узнать текущее напряжение на карте и прекратить с ней работу, если оно не входит в требуемый диапазон. Таков общий принцип инициализации карты, для выполнения которой, в зависимости от типа карты (MMC, SD, SD I/O), могут использоваться другие команды и выполняться дополнительные шаги, поэтому при реализации низкоуровневого интерфейса нужно внимательно прочитать документацию на карту и изучить команды CMD.

Во время записи хост передает карте один или несколько блоков, используя команду WRITE_BLOCK (CMD24) или WRITE_MULTIPLE_BLOCK (CMD25), соответственно, при этом в конце каждого блока хост записывает контрольную сумму. Карта, запись данных для которой разрешена, всегда будет в состоянии принять блок(и), но если контрольная сумма не совпадет, то карта сообщит об ошибке и не запишет текущий блок в свою память, а в случае пакетной передачи следующие блоки будут проигнорированы.

Передать информацию хосту, то есть выполнить чтение, также можно одним блоком с помощью команды READ_SINGLE_BLOCK (CMD17) или пакетом из нескольких блоков с помощью команды READ_MULTIPLE_BLOCK (CMD18). В случае пакетной передачи хост может прервать чтение в любое время, отправив команду STOP_TRANSMISSION (CMD12). Если в ходе передачи нескольких блоков внутренний контроллер карты зафиксирует ошибку, то он остановит передачу данных хост-контроллеру, но оставит карту в режиме передачи данных. В таком случае хосту придется принудительно завершить чтение с помощью команды CMD12, при этом в ответе на эту команду карта сообщит об ошибке чтения.

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

Драйвер stm324xg_eval_sdio_sd

Этот драйвер представляет собой библиотеку функций, с помощью которых можно реализовать высокоуровневый интерфейс для обмена данными с SD-картой. Драйвер поставляется для работы с отладочной платой STM324VG [2] (UtilitiesSTM32_EVALSTM3240_41_G_EVAL), но после изменения функций, связывающих эту библиотеку с низкоуровневым интерфейсом SDIO он может функционировать со многими микроконтроллерами семейства STM32, в составе которых имеется модуль SDIO. Из предыдущего предложения следует, что к проекту должны быть подключены файлы из стандартной библиотеки Standard Peripheral Library, обеспечивающие функционирование модуля SDIO на низком уровне. Например, для микроконтроллеров серии STM32F4xx это будут файлы stm32f4xx_sdio.c и stm32f4xx_sdio.h.

Перед использованием функций драйвера программист должен связать этот драйвер с аппаратной частью, то есть настроить линии модуля SDIO. Для этого ему нужно в основном файле своей программы main.c создать функции SD_LowLevel_Init() (для включения модуля SDIO) и SD_LowLevel_DeInit() (для отключения модуля SDIO), в которых необходимо выполнить конфигурирование этих линий. Если программист желает использовать модуль прямого доступа к памяти для увеличения скорости работы с SD-картой, то ему также нужно будет создать функции SD_LowLevel_DMA_TxConfig() и SD_LowLevel_DMA_RxConfig(), отвечающие за передачу и прием данных с помощью модуля ПДП. В качестве примера инициализации четырех указанных функций можно взять код, имеющийся в файле stm324xg_eval.c из [2] (UtilitiesSTM32_EVALSTM3240_41_G_EVAL).

Теперь рассмотрим основные функции для работы с SD-картой, предоставляемые этим драйвером. Для того, чтобы инициализировать карту, нужно вызвать функцию SD_Init(), которая настраивает модуль SDIO, обращаясь к SD_LowLevel_Init(), проверяет тип SD-карты, получает служебную информацию из регистров CID и CSD, задает скорость передачи данных (по умолчанию 24 МГц) и устанавливает ширину шины (4 бита). Прочитать данные, полученные с карты, можно с помощью функций SD_ReadBlock() (для чтения одного блока) и SD_ReadMultiBlocks() (для чтения нескольких блоков). Чтобы записать данные на карту, используют функции SD_WriteBlock() (для записи одного блока) и SD_WriteMultiBlocks() (для записи нескольких блоков). Эти функции чтения и записи принимают три аргумента: buffer (переменная-буфер, в которую должны помещаться данные для чтения и записи), address (адрес ячейки памяти SD-карты) и block_size (всегда 512, поскольку эти функции работают только с блоками длинной 512 байтов). Для стирания определенной области памяти карты имеется функция SD_Erase(). В качестве аргументов она принимает startaddr и endaddr. В первом указывается адрес ячейки памяти, с которой начнется стирание, а во втором – адрес ячейки, на которой стирание будет завершено.

Передача данных между модулем SDIO и памятью микроконтроллера может осуществляться как обычным путем через центральный процессор, так и через блок прямого доступа к памяти. Для выбора необходимого режима нужно в файле stm324xg_eval_sdio_sd.h раскомментировать либо строчку #define SD_POLLING_MODE (обычный режим), либо строчку #define SD_DMA_MODE (режим ПДП). После любой операции записи или чтения необходимо с помощью функции SD_GetStatus() проверять, завершила ли карта текущую операцию, и готова ли она к приему или отправке новых данных. Если эта функция вернула значение SD_TRANSFER_OK, то передача завершена успешно, возврат SD_TRANSFER_BUSY означает, что канал передачи занят, а возврат SD_TRANSFER_ERROR сообщает об ошибке передачи. Все эти значения определены в структуре SDTransferState, записанной в stm324xg_eval_sdio_sd.h. Если передача информации выполнялась через блок ПДП, то дополнительно нужно проверять, завершил ли контроллер ПДП все операции по пересылке данных. Это делается с помощью функции SD_ReadWaitOperation(). Также стоит отметить, что передача через блок ПДП завершается прерыванием, поэтому программисту необходимо организовать вызов функции SD_ProcessIRQ() в обработчике прерываний модуля SDIO SDIO_IRQHandler() и вызов функции SD_ProcessDMAIRQ() в обработчике прерываний DMA2 DMA2_Streamx_IRQHandler().

Для лучшего понимания принципа работы драйвера stm324xg_eval_sdio_sd можно воспользоваться рабочим примером из папки SDIOSDIO_uSDCard [2] (ProjectSTM32F4xx_StdPeriph_ExamplesSDIO). С помощью этой тестовой программы можно выполнить стирание определенной области памяти карты, запись данных по определенному адресу, чтение данных по этому же адресу с последующим сравнением отправленной и принятой информации. Идентичность буфера приема и буфера отправки является свидетельством того, что модуль SDIO, шина передачи информации и SD-карта функционируют нормально.

Использование SD-карт в малых встраиваемых системах

Таким образом, можно сказать, что SD-карты являются достойными конкурентами USB флеш-накопителей, когда речь заходит о проектировании малых встраиваемых систем, требующих хранения больших объемов данных. Передавать информацию с карты и на карту можно с помощью интерфейса SPI или по шине SD, которая разработана для этих целей и обеспечивает высокую скорость передачи. Реализация связи с картой существенно упрощается при использовании специальных драйверов, облегчающих работу с аппаратной частью и предлагающих программистам простые в использовании функции. Но, к сожалению, записанные в произвольном порядке данные не будут восприняты какой-либо операционной системой, например, Windows, поэтому в следующей части будет рассмотрен порядок работы с SD-картой, имеющей файловую систему FAT.

Список источников

  1. SD Card Specification. SD Association, October 2001, 29 pages.
  2. STM32F4xx DSP and Standard Peripherals Library.
  3. RM0090. Reference manual for STM32F4xxx advanced ARM-based 32-bit MCUs. STMicroelectronics, February 2013, 1422 pages.

Окончание

Перевод: Mikhail R по заказу РадиоЛоцман

Электронные компоненты. Бесплатная доставка по России
Для комментирования материалов с сайта и получения полного доступа к нашему форуму Вам необходимо зарегистрироваться.
Имя