Телесистемы
 Разработка, производство и продажа радиоэлектронной аппаратуры
На главную   | Карта сайта | Пишите нам | В избранное
Требуется программист в Зеленограде
- обработка данных с датчиков; ColdFire; 40 тыс.
e-mail:jobsmp@pochta.ru

Телесистемы | Электроника | Конференция «Микроконтроллеры и их применение»

я глубоко не разбирался, но форматирование (под ФАТ16), запись и чтение проходит нормально, но иногда возникали ошибки инициализации - зависало при Init, добавил паузу после срабатывания датчика до инициализации - стало работать нормально

Отправлено ыфефт 02 апреля 2007 г. 12:25
В ответ на: To Satan. отправлено UraGun 02 апреля 2007 г. 11:50

Не знаю. Может проблема в электронной части (разводка и т.п.)

Документация действительно какая-то неструктурированная, неполная. Долго разобирался с контрольными суммами (правильных реализаций так и не нашел, только у Silabs в AN189 что-то более-менее нормальное), хотя и не нужное, может пригодится например для повышения защищенности, или для работы в режиме MMC.

Я добился правильного форматирования и чтения карточки, на компьютере раздел ФАТ16 видится и пишется правильно, сейчас работаю над простой записью/чтением файла (нужно сделать логгер для данных, приходящих в посл. порт, проц. Мега8). Сначала надеялся на работу в побайтовом режиме (как вы описывали), так действительно было бы проще, но те несколько карточек с которыми работал не поддерживают такой режим, пришлось сделать секторный буфер в памяти и работать через него.

Пока еще дорабатываю модули для MMC и FAT.

Пишу секторы командой (пока без каких-либо проверок), потом проверяю кард-ридером, вроде все правильно :

mmc_spi_wr_block_data(&mmc_buf_sector[0], adr, sizeof(mmc_buf_sector));

Вот еще модуль для файловых систем (пока на ФАТ16).
fs_fat16_calc_params вычисляет параметры системы,
fs_fat16_bootsec_wr_info создает загрузочный сектор в буфере
fs_fat16_bootsec_rd_info читает информацию о диске из загрузочного сектора


//File systems parameters/definitions/functions/////////////////////////////////////////////////////////////////////////////////

/** \addtogroup params_fs File systems (файловые системы)
*/

/** \brief FAT partition information structure (структура информации о дисковом разделе) \ingroup params_fs */
typedef struct {
uint32_t sector_start; /**< \brief starting sector of partition (номер начального сектора раздела) */
uint32_t sectors; /**< \brief number of sectors in partition (общее количество секторов в разделе) */
uint16_t sectors_bootrec;/**< \brief number of sectors in boot record (количество секторов в загрузочной записи) */
uint16_t root_entries; /**< \brief number of root directory entries (количество записей в корневом каталоге) */
uint8_t sectors_cluster;/**< \brief number of sectors in cluster (количество секторов в кластере) */
uint8_t sectors_cluster_shr_bits; /**< \brief number of bits to shift sector number right for clucter number calculation (количество бит на которое нужно сдвинуть номер сектора вправо чтобы получить номер кластера) */
uint16_t clusters; /**< \brief actual number of clusters in partition (общее количество кластеров в разделе) */
uint8_t sectors_fat; /**< \brief number of sectors in FAT (количество секторов в одной копии FAT) */
uint8_t fats; /**< \brief number of FATs (количество таблиц FAT) */
}fs_part_info_struct;

/** \brief FAT partition directory entry structure (структура файловой записи для систем FAT) \ingroup params_fs */
typedef struct {
uint8_t name[11]; /**< \brief file name and extension (название и расширение файла) */
uint8_t attr; /**< \brief file attributes (атрибуты файла) */
uint8_t nt_res; /**< \brief Reserved for use by Windows NT. Set value to 0 when a file is created and never modify or look at it after that */
uint8_t crt_time_tenth; /**< \brief Millisecond stamp at file creation time. This field actually contains a count of tenths of a second. The granularity of the seconds part of DIR_CrtTime is 2 seconds so this field is a count of tenths of a second and its valid value range is 0-199 inclusive (миллисекунды времени создания файла 0-199) */
uint16_t crt_time; /**< \brief Time file was created (время создания файла) */
uint16_t crt_date; /**< \brief Date file was created (дата создания файла) */
uint16_t crt_date_last; /**< \brief Last access date. Note that there is no last access time, only a date. This is the date of last read or write. In the case of a write, this should be set to the same date as DIR_WrtDate (дата последнего доступа к файлу) */
uint16_t frst_clust_hi; /**< \brief High word of this entry’s first cluster number (always 0 for a FAT12 or FAT16 volume) (старшее слово номера первого кластера файла) */
uint16_t wrt_time; /**< \brief Time of last write. Note that file creation is considered a write (время последней записи в файл) */
uint16_t wrt_date; /**< \brief Date of last write. Note that file creation is considered a write (дата последней записи в файл) */
uint16_t frst_clust_lo; /**< \brief Low word of this entry’s first cluster number (младшее слово номера первого кластера файла) */
uint32_t filesize; /**< \brief 32-bit DWORD holding this file’s size in bytes (размер файла в байтах) */
}fs_fat_dir_entry_struct;

//dir entry attributes (атрибуты файлов для системы FAT)
#define fs_fat_attr_READ_ONLY 0x01 /**< \brief entry is read only (только для чтения) \ingroup params_fs */
#define fs_fat_attr_HIDDEN 0x02 /**< \brief entry is hidden (скрытый) \ingroup params_fs */
#define fs_fat_attr_SYSTEM 0x04 /**< \brief entry is system (системный) \ingroup params_fs */
#define fs_fat_attr_VOLUME_ID 0x08 /**< \brief entry is volume label (метка диска) \ingroup params_fs */
#define fs_fat_attr_DIRECTORY 0x10 /**< \brief entry is directory (папка) \ingroup params_fs */
#define fs_fat_attr_ARCHIVE 0x20 /**< \brief entry is archived (архивный) \ingroup params_fs */
#define fs_fat_attr_LONG_NAME (fs_fat_attr_READ_ONLY | fs_fat_attr_HIDDEN | fs_fat_attr_SYSTEM | fs_fat_attr_VOLUME_ID) /**< \brief long name used (использовано длинное имя файла) \ingroup params_fs */


/** \brief packs day, month, year to 16-bit word (упаковка даты в 16-битный формат FAT) \ingroup params_fs */
uint16_t fs_fat_pack_date(uint8_t day, uint8_t month, uint16_t year)
{uint16_t u16_01;
u16_01 = (day & 0x1f);
u16_01 |= ((month & 0xf) << 4);
if (year < 1980) year = 1980;
u16_01 |= (((year - 1980) & 0x7f) << 9);
return(u16_01);
}

/** \brief packs seconds, minutes, hours to 16-bit word (упаковка времени в 16-битный формат FAT) \ingroup params_fs */
uint16_t fs_fat_pack_time(uint8_t seconds, uint8_t minutes, uint8_t hours)
{uint16_t u16_01;
u16_01 = ((seconds >> 1) & 0x1f);
u16_01 |= ((minutes & 0x3f) << 5);
u16_01 |= ((hours & 0x1f) << 11);
return(u16_01);
}

/** \brief calculates other parameters of FAT16 partition from initial info - sectors, sector_start, sectors_bootrec, root_entries, fats must be initialized (вычисляет остальные параметры системы FAT16) \ingroup params_fs */
void fs_fat16_calc_params(fs_part_info_struct *part_info)
{uint8_t u8_01, u8_02;
//calculate number of sectors per cluster
u8_01 = ((part_info->sectors - part_info->sectors_bootrec) >> 16);
u8_02 = 0;
//calculate number of bits to calculate cluster number from sector number by right shifts
if (u8_01 & 0x40) {u8_01 = 128; u8_02 = 7;}
else if (u8_01 & 0x20) {u8_01 = 64; u8_02 = 6;}
else if (u8_01 & 0x10) {u8_01 = 32; u8_02 = 5;}
else if (u8_01 & 0x08) {u8_01 = 16; u8_02 = 4;}
else if (u8_01 & 0x04) {u8_01 = 8; u8_02 = 3;}
else if (u8_01 & 0x02) {u8_01 = 4; u8_02 = 2;}
else if (u8_01 & 0x01) {u8_01 = 2; u8_02 = 1;}
else {u8_01 = 0x01; u8_02 = 0;}
part_info->sectors_cluster = u8_01; //sectors per cluster
part_info->sectors_cluster_shr_bits = u8_02; //number of right shifts for cluster number calculation
//calculate total number of clusters reserved in FAT
part_info->clusters = (part_info->sectors - part_info->sectors_bootrec) >> (part_info->sectors_cluster_shr_bits);
//calculate number of sectors per FAT
part_info->sectors_fat = ((part_info->clusters) >> 8) + 1;
//calculate actual number of clusters available in partition
part_info->clusters -= ((part_info->sectors_bootrec + ((part_info->sectors_fat) * (part_info->fats))) >> (part_info->sectors_cluster_shr_bits));
//calculate starting sector of root directory
//part_info->sector_root = (part_info->sectors_bootrec) + (part_info->sector_start) + ((part_info->sectors_fat) * part_info->fats);
}

/** \brief creates FAT16 boot sector *buf from information from structure *part_info (создает загрузочный сектор из информации о диске) \ingroup params_fs */
void fs_fat16_bootsec_wr_info(fs_part_info_struct *part_info, uint8_t *buf)
{
//clear sector buffer
memset(buf, 0, 512);
//JMP instruction
buf[0] = 0xeb; buf[1] = 0x3c; buf[2] = 0x90;
//OEM name = 'MSDOS5.0'
buf[3] = 'M'; buf[4] = 'S'; buf[5] = 'D'; buf[6] = 'O';
buf[7] = 'S'; buf[8] = '5'; buf[9] = '.'; buf[10] = '0';
//bytes/sector = 512
*(uint16_t *)(&buf[11]) = 512;
//sectors/cluster
buf[13] = part_info->sectors_cluster;
//number of reserved sectors
*(uint16_t *)(&buf[14]) = part_info->sectors_bootrec;
//number of FATs
buf[16] = part_info->fats;
//number of root directory entries
*(uint16_t *)(&buf[17]) = part_info->root_entries;
//media descriptor
buf[21] = 0xf8;
//one FAT size, sectors
*(uint16_t *)(&buf[22]) = part_info->sectors_fat;
//total sectors in partition
*(uint32_t *)(&buf[32]) = part_info->sectors;
//extended boot signature
buf[38] = ')';
//file system name
buf[54] = 'F'; buf[55] = 'A'; buf[56] = 'T'; buf[57] = '1';
buf[58] = '6';
//Boot sector signature
*(uint16_t *)(&buf[510]) = 0xaa55;
}

/** \brief reads partition information from FAT16 boot sector *buf to *part_info structure, returns 0 if all information ok, 1 if no valid information found (читает информацио о диске из загрузочной записи в информационную структуру) \ingroup params_fs */
uint8_t fs_fat16_bootsec_rd_info(fs_part_info_struct *part_info, uint8_t *buf)
{uint8_t result;
result = 0;
if ( ((buf[0] == 0xeb) && (buf[2] == 0x90)) //check the JMP instruction
&& (buf[21] == 0xf8) //check media descriptor
&& (buf[38] == ')') //check extended boot signature
&& (*(uint16_t *)(&buf[11]) == 512) //check sector size
//check file system name
&& ((buf[54] == 'F') && (buf[55] == 'A') && (buf[56] == 'T') && (buf[57] == '1') && (buf[58] == '6'))
&& (*(uint16_t *)(&buf[510]) == 0xaa55) //check boot sector signature
)
{uint8_t u8_01, u8_02;
//read sectors/cluster
u8_01 = part_info->sectors_cluster = buf[13];
//compute number of right shifts for cluster number calculation
if (u8_01 == 128) u8_02 = 7;
else if (u8_01 == 64) u8_02 = 6;
else if (u8_01 == 32) u8_02 = 5;
else if (u8_01 == 16) u8_02 = 4;
else if (u8_01 == 8) u8_02 = 3;
else if (u8_01 == 4) u8_02 = 2;
else if (u8_01 == 2) u8_02 = 1;
else u8_02 = 0;
part_info->sectors_cluster_shr_bits = u8_02;
//read number of reserved sectors
part_info->sectors_bootrec = *(uint16_t *)(&buf[14]);
//read number of FATs
part_info->fats = buf[16];
//read number of root directory entries
part_info->root_entries = *(uint16_t *)(&buf[17]);
//read one FAT size, sectors
part_info->sectors_fat = *(uint16_t *)(&buf[22]);
//read total sectors in partition
part_info->sectors = (((uint32_t)(((buf[35] << 8) | buf[34]) << 8) | buf[33]) << 8) | buf[32];//*(uint32_t *)(&buf[32]);
//compute number of clusters in partition
part_info->clusters = ((part_info->sectors - part_info->sectors_bootrec - (part_info->sectors_fat * part_info->fats) - ((part_info->root_entries * 32) >> 9)) >> part_info->sectors_cluster_shr_bits) + 2;
}else result = 1; //if error in partition info occured, return 1
return(result);
}




Составить ответ | Вернуться на конференцию

Ответы


Отправка ответа
Имя*: 
Пароль: 
E-mail: 
Тема*:

Сообщение:

Ссылка на URL: 
URL изображения: 

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

Перейти к списку ответов | Конференция | Раздел "Электроника" | Главная страница | Карта сайта

Rambler's Top100 Рейтинг@Mail.ru
 
Web telesys.ru