STM32F103C8T6 كمحرك أقراص فلاش مع نظام الملفات FAT12

عند تطوير الأجهزة ، غالبًا ما يكون من الضروري تخزين الإعدادات خارج برنامج العمل. من الأفضل أن تكون قادرًا على تعديلها دون استخدام أدوات خاصة.

ضع في اعتبارك خيار التخزين في أكثر وحدات التحكم STM F103 شيوعًا. كما ساهمت اللوح الأزرق المعروف جيدا في انتشار المرض.

الصورة
لا يتيح الفلاش المتوفر فيه تخزين الإعدادات وتعديلها فقط باستخدام نظام الملفات FAT12 في الفلاش الداخلي ، ولكن أيضًا لتنظيم تحديث البرنامج الثابت.

وفقًا للوثائق ، يحتوي STM32F103C8T6 على ذاكرة فلاش 64 كيلو بايت. ومع ذلك ، في جميع STM32F103C8T6 تقريبا ، يتم تثبيت 128K. تم ذكر ذلك أيضًا في العديد من المصادر - عادة ما يضعون 64 كيلو بايت أكثر تسمح لك هذه "الميزة" باستخدام المتحكم الدقيق كمحرك أقراص فلاش بسعة 128K - 20K (يحتاج النظام إلى FAT12) - حجم البرنامج الثابت.

واجه العديد من المتحمسين الذين حاولوا استخدام وحدة التحكم هذه كمحرك أقراص محمول مشكلة استخدامه في وضع نظام الملفات FAT12. استخدامها لإزالة / ملء صورة القرص تحولت. ولكن عند العمل كما هو الحال مع محرك الملفات ، بدأت المشاكل.

تتكون هذه المشكلة في تسلسل مختلف للوصول إلى القطاعات (الكتل). عند تحميل صورة القرص ، يحدث التسجيل بالتتابع ، على سبيل المثال:

-تسجيل كتلة رقم 1 ،
-تسجيل كتلة رقم 2 ،
سجل كتلة رقم 3.

عند كتابة بيانات FAT12 ، يمكن أن يحدث التسجيل بشكل تعسفي:

سجل كتلة رقم 3 ،
-تسجيل كتلة رقم 1 ،
سجل كتلة رقم 2.

ونظرًا لأن الكتابة إلى الفلاش تتطلب محو الصفحة بأكملها التي يبلغ طولها 1 كيلو بايت ، عند استخدام قطاعات 512 بايت في محرك الأقراص (ولا يمكنك استخدام القطاعات الأخرى) ، في حالة استخدام الوصول العشوائي ، يتم مسح المعلومات في القطاع المجاور. لمنع حدوث ذلك ، يستخدم المثال أعلاه صفيف 512 بايت لتخزين القطاع المجاور. ويجب أن يكون التسجيل كما يلي:

- تحديد عنوان بداية الصفحة ،
- تذكر القطاع المجاور ،
- محو الصفحة ،
- اكتب القطاع المحفوظ ،
- كتابة البيانات.

من أجل عدم الخوض في غابة الحديد دون الحاجة المطلوبة ، أعددت المشروع في CubeMX.

سأقدم مثالًا عن وظيفة للكتابة إلى الفلاش عبر HAL (usbd_storage_if.c)

//    flash void writeBuf (uint32_t page_addr, uint8_t *buf){ uint32_t erase_addr=get_erase_addr(page_addr); uint32_t buf_erase_addr; uint32_t buf32; if (page_addr != erase_addr) { buf_erase_addr=erase_addr; } else { buf_erase_addr=erase_addr+STORAGE_BLK_SIZ; } HAL_FLASH_Unlock(); //      set_buf_before_erase(buf_erase_addr); //       FLASH_EraseInitTypeDef EraseInitStruct; uint32_t PAGEError = 0; EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; EraseInitStruct.PageAddress = erase_addr; EraseInitStruct.NbPages = 1; HAL_FLASHEx_Erase(&EraseInitStruct,&PAGEError); //    for (int i=0; i<STORAGE_BLK_SIZ/4;i++) { HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,buf_erase_addr,blk_buff[i]); buf_erase_addr+=4; } //   for (int i=0; i<STORAGE_BLK_SIZ/4;i++) { buf32=*(uint32_t *)&buf[i*4]; HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, page_addr,buf32); page_addr+=4; } HAL_FLASH_Lock(); } 

حجم الملف الثنائي الذي حصلت عليه حوالي 20 كيلو بايت ، لذلك يتم تعريف صفحة ذاكرة البيانات الخاصة بي مع 0x08006000 (24K).

نحن نجمع (الكود المصدري للمثال يمكن أن يؤخذ هنا).

نحن نتواصل:

 [ 8193.499792] sd 4:0:0:0: Attached scsi generic sg2 type 0 [ 8193.502050] sd 4:0:0:0: [sdb] 128 512-byte logical blocks: (65.5 kB/64.0 KiB) [ 8193.502719] sd 4:0:0:0: [sdb] Write Protect is off [ 8193.502722] sd 4:0:0:0: [sdb] Mode Sense: 00 00 00 00 [ 8193.503439] sd 4:0:0:0: [sdb] Asking for cache data failed [ 8193.503445] sd 4:0:0:0: [sdb] Assuming drive cache: write through [ 8193.523812] sdb: [ 8193.526914] sd 4:0:0:0: [sdb] Attached SCSI removable disk 

يتم تحديد القرص ، كل شيء على ما يرام!

لنبدأ تشكيل القسم وتنسيق القرص لدينا.

في نظام Linux ، هذا بسيط جدًا من سطر الأوامر:

 sudo fdisk /dev/sdb 



التنسيق في FAT12:

 sudo mkfs.fat /dev/sdb -F 12 

انسخ الملف للاختبار:



ومع ذلك ، لا ينبغي لأحد أن ينسى أنه وفقا للوثائق ، وعدد دورات إعادة كتابة الفلاش
يتم ضمانه في غضون 100000 فقط. على سبيل المثال ، التنسيق والكتابة سوف يستغرق ملف واحد 30 كيلو بايت (وفقًا لسجل تصحيح هذا المثال):

 00106 44 67 Write_FS blk_addr=003 0x08006600 

106 دورات إعادة الكتابة.

يبقى السؤال - كيف يمكنني قراءة البيانات عن طريق الوصول إلى ملفات FAT12 مباشرة؟
حول هذا الموضوع في المقال التالي.
شكرا لاهتمامكم!

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


All Articles