الوصول إلى البيانات المبسطة FAT12 الداخلية ل STM32

في مقالة سابقة ، نظرنا في خيار استخدام متحكم STM32F103C8T6 كمحرك أقراص محمول مع نظام ملفات داخلي FAT12. يمكنك الآن التفكير في كيفية الحصول على البيانات من نظام الملفات الداخلي لدينا. على سبيل المثال ، نحتاج إلى تخزين بعض إعدادات برنامجنا.
لا يوجد أي تعقيد خاص بنيات تنسيق البيانات مطلوب لتخزين الإعدادات المسماة. نحن نقبل التنسيق التالي - إعداد واحد = ملف واحد. على سبيل المثال ، نحتاج إلى تخزين سرعة الاتصال عبر UART ، وعلى سبيل المثال ، التأخير بالميللي ثانية من الصمام الوامض. قم بإنشاء (في أي محرر نصوص) ملفات UART_SPD.SET و DELAY_BL.SET في نظام الملفات لدينا. نكتب القيم فيها: 115200 و 1000 ، على التوالي.
للحصول على هذه البيانات ، بالانتقال إلى FAT12 الداخلية ، ستحتاج إما إلى أخذ مكتبة HAL FatFs القياسية ومحاولة تكييفها مع الفلاش الداخلي. أو اذهب بطريقة أبسط وأكثر ملاءمة - اكتب وظيفة قارئ بيانات ملف FAT12 ، والتي سنفعلها:

uint8_t f12_read_data ( char *file_name, //       11  - "NAME TXT" char **file_data, //      char *file_list, //     uint16_t file_list_size) { //     // FAT12 - http://elm-chan.org/docs/fat_e.html uint16_t BPB_BytsPerSec; uint8_t BPB_NumFATs; uint16_t BPB_RootEntCnt; uint16_t BPB_RsvdSecCnt; uint16_t BPB_FATSz16; uint8_t BPB_SecPerClus; uint16_t BS_BootSign; uint8_t found=0; uint16_t cluster_no; char *fname; uint32_t SEEK_FAT12_NAMES_OFFSET; uint32_t SEEK_FAT12_NAMES_OFFSET_END; uint32_t SEEK_DATA_OFFSET; uint32_t fs; //   FAT12 BPB_BytsPerSec=uint16_t_from_internal_flash(PAGE_ADDR+11); BPB_NumFATs=uint8_t_from_internal_flash(PAGE_ADDR+16); BPB_RootEntCnt=uint16_t_from_internal_flash(PAGE_ADDR+17); BPB_RsvdSecCnt=uint16_t_from_internal_flash(PAGE_ADDR+14); BPB_FATSz16=uint16_t_from_internal_flash(PAGE_ADDR+22); BPB_SecPerClus=uint8_t_from_internal_flash(PAGE_ADDR+13); BS_BootSign=uint16_t_from_internal_flash(PAGE_ADDR+510); if (BS_BootSign != 0xAA55) { //   boot  FAT return FAT12_ERR_BAD_FAT; } SEEK_FAT12_NAMES_OFFSET = (BPB_RsvdSecCnt+(BPB_FATSz16 * BPB_NumFATs)) * BPB_BytsPerSec; //     SEEK_FAT12_NAMES_OFFSET_END=SEEK_FAT12_NAMES_OFFSET + (((32 * BPB_RootEntCnt + BPB_BytsPerSec - 1) / BPB_BytsPerSec) * BPB_BytsPerSec); //     SEEK_DATA_OFFSET= BPB_BytsPerSec * BPB_RsvdSecCnt+ // Boot  +  ((BPB_FATSz16 * BPB_NumFATs) * BPB_BytsPerSec) + //  FAT BPB_RootEntCnt*32; //    -  if (file_list_size > 0) //     file_list[0]=0; while (SEEK_FAT12_NAMES_OFFSET < SEEK_FAT12_NAMES_OFFSET_END) { fname = char_from_internal_flash(PAGE_ADDR+SEEK_FAT12_NAMES_OFFSET); cluster_no = uint16_t_from_internal_flash(PAGE_ADDR + SEEK_FAT12_NAMES_OFFSET + 0x1A); fs = uint32_t_from_internal_flash(PAGE_ADDR + SEEK_FAT12_NAMES_OFFSET + 0x1C); if ((file_list_size > 0) && (strlen(file_list)+20 < file_list_size) && (cluster_no > 0)) { sprintf(file_list,"%s%11s %06d bytes\r\n", file_list,fname, fs); //     } for (int i=0;i<9;i++) { //      if (fname[i] != file_name[i]) { found=0; break; } found=1; } if (found==1) break; SEEK_FAT12_NAMES_OFFSET+=0x20; } if (found == 0) { return FAT12_ERR_FILE_NOT_FOUND; } if ( *file_data != 0 ) { *file_data=char_from_internal_flash(PAGE_ADDR+(cluster_no-2) * (BPB_SecPerClus * BPB_BytsPerSec) + //   SEEK_DATA_OFFSET); } return 0; } 

الآن - نحصل على قيمة الإعدادات اللازمة:

 f12_read_data("UART_SPDSET" /*  ,   11  - */,&fdata, file_list, 200); 


سيحتوي صفيف fdata على السلسلة "115200" ، والتي يمكن تحويلها إلى عدد صحيح باستخدام دالة atoi ():
المشروع مع رموز المصدر يمكن أن يؤخذ هنا .

هذا كل شيء. شكرا لاهتمامكم!

Source: https://habr.com/ru/post/ar441858/


All Articles