⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 This project provides a general purpose library which implements read and write support for MMC, SD
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2006-2009 by Roland Riegel <feedback@roland-riegel.de> * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */#include <string.h>#include <avr/pgmspace.h>#include <avr/sleep.h>#include "fat.h"#include "fat_config.h"#include "partition.h"#include "sd_raw.h"#include "sd_raw_config.h"#include "uart.h"#define DEBUG 1/** * \mainpage MMC/SD/SDHC card library * * This project provides a general purpose library which implements read and write * support for MMC, SD and SDHC memory cards. * * It includes * - low-level \link sd_raw MMC, SD and SDHC read/write routines \endlink * - \link partition partition table support \endlink * - a simple \link fat FAT16/FAT32 read/write implementation \endlink * * \section circuit The circuit * The circuit which was mainly used during development consists of an Atmel AVR * microcontroller with some passive components. It is quite simple and provides * an easy test environment. The circuit which can be downloaded on the * <a href="http://www.roland-riegel.de/sd-reader/">project homepage</a> has been * improved with regard to operation stability. * * I used different microcontrollers during development, the ATmega8 with 8kBytes * of flash, and its pin-compatible alternative, the ATmega168 with 16kBytes flash. * The first one is the one I started with, but when I implemented FAT16 write * support, I ran out of flash space and switched to the ATmega168. For FAT32, an * ATmega328 is required. *  * The circuit board is a self-made and self-soldered board consisting of a single * copper layer and standard DIL components, except of the MMC/SD card connector. * * The connector is soldered to the bottom side of the board. It has a simple * eject button which, when a card is inserted, needs some space beyond the connector * itself. As an additional feature the connector has two electrical switches * to detect wether a card is inserted and wether this card is write-protected. *  * \section pictures Pictures * \image html pic01.jpg "The circuit board used to implement and test this application." * \image html pic02.jpg "The MMC/SD card connector on the soldering side of the circuit board." * * \section software The software * The software is written in pure standard ANSI-C. It might not be the smallest or * the fastest one, but I think it is quite flexible. See the project's * <a href="http://www.roland-riegel.de/sd-reader/benchmarks/">benchmark page</a> to get an * idea of the possible data rates. * * I implemented an example application providing a simple command prompt which is accessible * via the UART at 9600 Baud. With commands similiar to the Unix shell you can browse different * directories, read and write files, create new ones and delete them again. Not all commands are * available in all software configurations. * - <tt>cat \<file\></tt>\n *   Writes a hexdump of \<file\> to the terminal. * - <tt>cd \<directory\></tt>\n *   Changes current working directory to \<directory\>. * - <tt>disk</tt>\n *   Shows card manufacturer, status, filesystem capacity and free storage space. * - <tt>init</tt>\n *   Reinitializes and reopens the memory card. * - <tt>ls</tt>\n *   Shows the content of the current directory. * - <tt>mkdir \<directory\></tt>\n *   Creates a directory called \<directory\>. * - <tt>rm \<file\></tt>\n *   Deletes \<file\>. * - <tt>sync</tt>\n *   Ensures all buffered data is written to the card. * - <tt>touch \<file\></tt>\n *   Creates \<file\>. * - <tt>write \<file\> \<offset\></tt>\n *   Writes text to \<file\>, starting from \<offset\>. The text is read *   from the UART, line by line. Finish with an empty line. * * \htmlonly * <p> * The following table shows some typical code sizes in bytes, using the 20090330 release with a * buffered read-write MMC/SD configuration, FAT16 and static memory allocation: * </p> * * <table border="1" cellpadding="2"> *     <tr> *         <th>layer</th> *         <th>code size</th> *         <th>static RAM usage</th> *     </tr> *     <tr> *         <td>MMC/SD</td> *         <td align="right">2410</td> *         <td align="right">518</td> *     </tr> *     <tr> *         <td>Partition</td> *         <td align="right">456</td> *         <td align="right">17</td> *     </tr> *     <tr> *         <td>FAT16</td> *         <td align="right">7928</td> *         <td align="right">188</td> *     </tr> * </table> * * <p> * The static RAM is mostly used for buffering memory card access, which * improves performance and reduces implementation complexity. * </p> *  * <p> * Please note that the numbers above do not include the C library functions * used, e.g. some string functions. These will raise the numbers somewhat * if they are not already used in other program parts. * </p> *  * <p> * When opening a partition, filesystem, file or directory, a little amount * of RAM is used, as listed in the following table. Depending on the library * configuration, the memory is either allocated statically or dynamically. * </p> * * <table border="1" cellpadding="2"> *     <tr> *         <th>descriptor</th> *         <th>dynamic/static RAM</th> *     </tr> *     <tr> *         <td>partition</td> *         <td align="right">17</td> *     </tr> *     <tr> *         <td>filesystem</td> *         <td align="right">26</td> *     </tr> *     <tr> *         <td>file</td> *         <td align="right">53</td> *     </tr> *     <tr> *         <td>directory</td> *         <td align="right">49</td> *     </tr> * </table> *  * \endhtmlonly * * \section adaptation Adapting the software to your needs * The only hardware dependent part is the communication layer talking to the * memory card. The other parts like partition table and FAT support are * completely independent, you could use them even for managing Compact Flash * cards or standard ATAPI hard disks. * * By changing the MCU* variables in the Makefile, you can use other Atmel * microcontrollers or different clock speeds. You might also want to change * the configuration defines in the files fat_config.h, partition_config.h, * sd_raw_config.h and sd-reader_config.h. For example, you could disable * write support completely if you only need read support. * * For further information, visit the project's * <a href="http://www.roland-riegel.de/sd-reader/faq/">FAQ page</a>. *  * \section bugs Bugs or comments? * If you have comments or found a bug in the software - there might be some * of them - you may contact me per mail at feedback@roland-riegel.de. * * \section acknowledgements Acknowledgements * Thanks go to Ulrich Radig, who explained on his homepage how to interface * MMC cards to the Atmel microcontroller (http://www.ulrichradig.de/). * I adapted his work for my circuit. Although this is a very simple * solution, I had no problems using it. *  * \section copyright Copyright 2006-2009 by Roland Riegel * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 2 as published by * the Free Software Foundation (http://www.gnu.org/copyleft/gpl.html). * At your option, you can alternatively redistribute and/or modify the following * files under the terms of the GNU Lesser General Public License version 2.1 * as published by the Free Software Foundation (http://www.gnu.org/copyleft/lgpl.html): * - byteordering.c * - byteordering.h * - fat.c * - fat.h * - fat_config.h * - partition.c * - partition.h * - partition_config.h * - sd_raw.c * - sd_raw.h * - sd_raw_config.h * - sd-reader_config.h */static uint8_t read_line(char* buffer, uint8_t buffer_length);static uint32_t strtolong(const char* str);static uint8_t find_file_in_dir(struct fat_fs_struct* fs, struct fat_dir_struct* dd, const char* name, struct fat_dir_entry_struct* dir_entry);static struct fat_file_struct* open_file_in_dir(struct fat_fs_struct* fs, struct fat_dir_struct* dd, const char* name); static uint8_t print_disk_info(const struct fat_fs_struct* fs);int main(){    /* we will just use ordinary idle mode */    set_sleep_mode(SLEEP_MODE_IDLE);    /* setup uart */    uart_init();    while(1)    {        /* setup sd card slot */        if(!sd_raw_init())        {#if DEBUG            uart_puts_p(PSTR("MMC/SD initialization failed\n"));#endif            continue;        }        /* open first partition */        struct partition_struct* partition = partition_open(sd_raw_read,                                                            sd_raw_read_interval,#if SD_RAW_WRITE_SUPPORT                                                            sd_raw_write,                                                            sd_raw_write_interval,#else                                                            0,                                                            0,#endif                                                            0                                                           );        if(!partition)        {            /* If the partition did not open, assume the storage device             * is a "superfloppy", i.e. has no MBR.             */            partition = partition_open(sd_raw_read,                                       sd_raw_read_interval,#if SD_RAW_WRITE_SUPPORT                                       sd_raw_write,                                       sd_raw_write_interval,#else                                       0,                                       0,#endif                                       -1                                      );            if(!partition)            {#if DEBUG                uart_puts_p(PSTR("opening partition failed\n"));#endif                continue;            }        }        /* open file system */        struct fat_fs_struct* fs = fat_open(partition);        if(!fs)        {#if DEBUG            uart_puts_p(PSTR("opening filesystem failed\n"));#endif            continue;        }        /* open root directory */        struct fat_dir_entry_struct directory;        fat_get_dir_entry_of_path(fs, "/", &directory);        struct fat_dir_struct* dd = fat_open_dir(fs, &directory);        if(!dd)        {#if DEBUG            uart_puts_p(PSTR("opening root directory failed\n"));#endif            continue;        }                /* print some card information as a boot message */        print_disk_info(fs);        /* provide a simple shell */        char buffer[24];        while(1)        {            /* print prompt */            uart_putc('>');            uart_putc(' ');            /* read command */            char* command = buffer;            if(read_line(command, sizeof(buffer)) < 1)                continue;            /* execute command */            if(strcmp_P(command, PSTR("init")) == 0)            {                break;            }            else if(strncmp_P(command, PSTR("cd "), 3) == 0)            {                command += 3;                if(command[0] == '\0')                    continue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -