Driver para sistemas de ficheros de tipo FAT32/FAT16 de solo lectura J. Arias, 2015 En este código se proporcionan las funciones necesarias para la lectura de ficheros en sistemas de ficheros de tipo FAT32 o FAT16 mediante un mínimo uso de memoria. Aunque el código se ha probado en un PC, se ha desarrollado pensando en tarjetas de memoria de tipo SD en sistemas empotrados. En dichos sistemas se deberá sustituir la función rdsector() por otra adecuada al hardware de cada caso. Uso de memoria: 512 bytes para uso interno en la matriz global 'FATbuf[512]'. Esta matriz se puede usar también como buffer destino para las lecturas de ficheros, aunque ello obliga a recargar el contenido de la tabla FAT más frecuentemente, lo que reduce la velocidad efectiva de lectura. 32 bytes en variables globales. El resto de las variables van en los registros de la CPU o la pila. Ojo: la función "scandir" es recursiva y en cada llamada necesita al menos 11 bytes de pila, si bien no se anidan más de dos funciones "scandir". Utilización: En primer lugar se debe proporcionar una función "rdsector(unsigned int LBA, unsigned char *buf)" adecuada al hardware concreto que conecta el medio de almacenamiento con el micro. La función "initFAT()" lee del MBR y del superbloque la información necesaria para acceder a los ficheros. Esta función falla y retorna un valor distinto de cero si el sistema de ficheros no es FAT32 ni FAT16 (por ejemplo FAT12, obsoleto). Entre las variables globales inicializadas están los desplazamientos hasta las distintas áreas del sistema de ficheros (FAT, directorio root, datos) y otros detalles como el tipo de FAT o el número de sectores por cluster. Una valiable de especial importancia es 'FATvar.root_cluster', ya que se usará en "scandir", que almacena el número del primer cluster del directorio raíz (siempre vale 0 para FAT16 pero es un valor arbitrario en FAT32) A continuación se usará la función "scandir("name.ext",root_cluster)" para buscar el fichero deseado en el directorio raíz. El nombre del fichero no debe superar los 8 caracteres ni su extensión 3 caracteres, y no se distinguen minúsculas de mayúsculas. Si el fichero se encuentra se retorna su cluster inicial, mientras que si la búsqueda falla se retorna el valor cero. Si como argumento se pasa el nombre de un subdirectorio, se retornará el cluster inicial de dicho subdirectorio, dato que se podrá utilizar en otras llamadas a "scandir". Por último, se pueden incluir barras '/' o '\' en el nombre, lo que provocará una búsqueda recursiva en el árbol de directorios por parte de scandir. Una vez localizado el fichero con "scandir" tan solo falta leerlo con "rdfile(buf)". Esta función lee un sector (512 bytes) del fichero al buffer que se le indique, que podría ser incluso 'FATbuf', y retorna el número de bytes válidos. Un valor de retorno menor de 512 indica que se ha alcanzado el final del fichero. Restricciones: Este código sólo funciona correctamente en procesadores de tipo Little-Endian. Es más, se ha aprovechado esta característica para optimizar el código cuando ha sido posible. Los nombres de ficheros deben ser de tipo MS-DOS, esto es: con un máximo de 8 caracteres decentes para el nombre y de 3 caracteres para la extensión. Caracteres indecentes son por ejemplo el espacio, símbolos como '>' o letras no presentes en ASCII, como la 'Ñ'. Nótese que los nombres largos quedan modificados, como por ejemplo: "nombrelargo.ext" que pasa a ser "NOMBRE~1.EXT" El número de sectores por cluster ha de ser una potencia de 2 (lo habitual) Esto evita tener que realizar multiplicaciones. La función "scandir" llama a "rdfile", lo que supone la pérdida del estado del posible fichero que se estuviese leyendo. Por ello no se debe llamar a "scandir" mientras tengamos ficheros en proceso de lectura.