#include "ini.h" #include "stdint.h" #include "string.h" #include "stdlib.h" #include "cmsis_os.h" extern xSemaphoreHandle MutexAccessFlash; uint32_t substr(char *str, uint32_t PosStart, char end, char *s); FIL iniFile; /* Чтение строкового типа. Если секция или ключ не найдены или файл не открывается , то возвращаемое значение будет 0, усли ключ и секция найденны успешно, то = 1 path - Имя файла для чтения section - Имя секции для поиска key - Имя ключа для поиска value - Указатель на переменную в которую записать результат */ _Bool ini_ReadString(const TCHAR* path, const char* section, const char* key, char* value) { _Bool SectFind = 0; uint8_t State = 0; char *p, BufferRead[128] = {0}; if((section == NULL) || (key == NULL)) return 0; xSemaphoreTake(MutexAccessFlash, portMAX_DELAY);// пытаемся взять мьютекс для чтения файла конфигурации if(f_open(&iniFile, path, FA_READ) == FR_OK) { for(;State != 3;) { switch(State) { case 0: memset(value, NULL, strlen(value)); if(f_gets(BufferRead, 64, &iniFile) != NULL) // то все считалось { if(!SectFind)State = 1; else State = 2; } else if(f_eof(&iniFile) != 0) State = 3;//конец файла, выходим break; case 1: // поиск секции p = strchr(BufferRead, '['); if(p != NULL) { if(substr(p, 1, ']', value) != 0) { if(strncmp(value, section, strlen(section)) == 0) SectFind = 1;// если найдена нужная секция выставляем флаг } } State = 0; // переходим для взатия новой строки break; case 2: // поиск ключа if(strncmp(BufferRead, key, strlen(key)) == 0) // найден нужный ключ { p = strchr(BufferRead, '='); if(p != NULL) { if(substr(p, 1, '\n', value) != 0) { f_close(&iniFile); xSemaphoreGive(MutexAccessFlash); return 1; } else State = 3; } else State = 0; } else State = 0; break; } } f_close(&iniFile); } xSemaphoreGive(MutexAccessFlash); return 0; } /* Чтение числового типа Если секция или ключ не найдены или файл не открывается , то возвращает Defvalue, path - Имя файла для чтения section - Имя секции для поиска key - Имя ключа для поиска Defvalue - Значение по умолчанию если нет ключа */ uint16_t ini_ReadInteger(const TCHAR* path, const char* section, const char* key, uint16_t Defvalue, uint8_t radix) { char buf[16] = {0}; if((section == NULL) || (key == NULL)) return 0; if(ini_ReadString(path, section, key, buf) != 0) { if(radix == 16) return (strtol((char*)&buf[0], NULL, 16)); else if(radix == 10)return (strtol((char*)&buf[0], NULL, 10)); } return Defvalue; } //uint16_t ini_geth(const TCHAR* path, const char* section, const char* key, uint16_t Defvalue) //{ // char buf[16] = {0}; // if((section == NULL) || (key == NULL)) return 0; // if(ini_ReadString(path, section, key, buf) != 0)return (strtol(buf, NULL, 16)); // return Defvalue; //} /*Читает все значения ключа и заносит в массив ValueBuffer*/ _Bool ini_ReadKeyValue(const TCHAR* path, const char* section, const char* key, uint16_t *ValueBuffer) { char buf[64] = {0}, *end; if((section == NULL) || (key == NULL)) return 0; if(ini_ReadString(path, section, key, buf) != 0){ ValueBuffer[0] = strtol(buf, &end, 10); for(uint8_t i = 1; *end != '\0'; i++) ValueBuffer[i] = strtol(end + 1, &end, 10); return 1; } return 0; } uint32_t substr(char *str, uint32_t PosStart, char end, char *s) // возвращает длину подстроки, 0 если нет конечного символа { uint8_t len = 0; uint8_t PosEnd = 0; uint8_t StrLen = strlen(str); if(StrLen == 0) return 0; for(; str[PosStart + PosEnd] != end; PosEnd++) { len++; if(StrLen == len) return 0; } for(uint8_t i = 0; i < len; i++) s[i] = str[i + PosStart]; s[len] = '\0'; return len; }