{"id":12,"date":"2025-04-23T22:54:16","date_gmt":"2025-04-23T22:54:16","guid":{"rendered":"https:\/\/blog.ganji.dev\/?p=12"},"modified":"2025-04-23T22:56:38","modified_gmt":"2025-04-23T22:56:38","slug":"bringing-fatfs-to-rtems-a-developers-perspective-on-porting-and-integration","status":"publish","type":"post","link":"https:\/\/blog.ganji.dev\/?p=12","title":{"rendered":"Bringing FatFS to RTEMS: A Developer\u2019s Perspective on Porting and Integration"},"content":{"rendered":"\n<p>If you\u2019ve worked with RTEMS, you\u2019re probably familiar with its DOSFS \u2014 a serviceable FAT implementation that&#8217;s grown over time. But what if we could swap it out with something smaller, simpler, and easier to maintain? That\u2019s exactly what this GSoC 2025 project aims to explore: porting FatFS, a lean and widely-used FAT\/exFAT implementation, into RTEMS and building benchmarking tools to evaluate its real-world performance.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"245\" height=\"255\" src=\"https:\/\/blog.ganji.dev\/wp-content\/uploads\/2025\/04\/layers.png\" alt=\"\" class=\"wp-image-14\"\/><\/figure>\n\n\n\n<p>In this post, I\u2019ll walk through the architectural plan for this port, share the feature compatibility insights (FAT12\/16\/32, LFN, Unicode, case folding), and describe the challenges and design strategies in porting FatFS into a modern RTEMS environment.<\/p>\n\n\n\n<p><strong>Why FatFS?<\/strong><br>FatFS is a highly portable, memory-conscious filesystem library supporting FAT12, FAT16, and FAT32 \u2014 perfect for embedded systems. Unlike the more complex DOSFS in RTEMS, FatFS offers a minimal codebase, modular configuration, and great documentation, making it an attractive candidate for integration.<\/p>\n\n\n\n<p>The goal isn\u2019t just a replacement \u2014 it\u2019s an upgrade in simplicity and maintainability, with robust performance measurement tools built-in.<\/p>\n\n\n\n<p><strong>Bridging the Gap: Mapping FatFS to RTEMS<br><\/strong>Porting FatFS involves aligning its API with RTEMS\u2019s filesystem infrastructure. RTEMS uses the <code>libio<\/code> and <code>libblock<\/code> subsystems to expose filesystem operations and access block devices, respectively. Here\u2019s the plan to bring these together:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Filesystem Registration<\/strong>: Implement <code>rtems_filesystem_operations_table<\/code> and related structures so that FatFS can register as a valid filesystem type.<\/li>\n\n\n\n<li><strong>Mount\/Unmount Logic<\/strong>: Use <code>f_mount()<\/code> and <code>f_unmount()<\/code> to interface with FatFS\u2019s virtual volume logic, backed by RTEMS\u2019s block device abstraction.<\/li>\n\n\n\n<li><strong>File\/Dir Handlers<\/strong>: Provide implementations for file and directory handlers (<code>open<\/code>, <code>read<\/code>, <code>write<\/code>, <code>opendir<\/code>, <code>readdir<\/code>, etc.) by wrapping FatFS calls.<\/li>\n<\/ul>\n\n\n\n<p><strong>Implementing <code>diskio.c<\/code>: RTEMS &lt;-&gt; FatFS I\/O Bridge<br><\/strong>The heart of the port is the <code>diskio.c<\/code> layer \u2014 a bridge that connects FatFS\u2019s calls (like <code>disk_read<\/code>, <code>disk_write<\/code>) to the underlying RTEMS block driver API.<\/p>\n\n\n\n<p>Example mapping:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>DRESULT disk_read(BYTE pdrv, BYTE* buff, LBA_t sector, UINT count) {\n    \/\/ Convert to RTEMS block device API (via bdbuf or direct I\/O ops)\n}<\/code><\/pre>\n\n\n\n<p>We\u2019ll use <code>rtems_bdbuf_read()<\/code> and <code>rtems_bdbuf_write()<\/code> to handle sector operations, ensuring caching and sync behavior match FatFS expectations. Timestamp functions (<code>get_fattime<\/code>) will tie into RTEMS\u2019s time services.<\/p>\n\n\n\n<p><strong>Feature Compatibility Overview<br><\/strong>Let\u2019s evaluate FatFS features based on your proposal\u2019s criteria:<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-regular\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Feature<\/strong><\/td><td><strong>Support in FatFS<\/strong><\/td><td><strong>RTEMS Integration Notes<\/strong><\/td><\/tr><tr><td>FAT12\/16\/32<\/td><td>\u2705 Yes<\/td><td>Select via config (<code>ffconf.h<\/code>). All formats supported.<\/td><\/tr><tr><td>Long File Names<\/td><td>\u2705 Optional<\/td><td>Enable <code>_USE_LFN &gt; 0<\/code>. Requires dynamic memory or static buffers.<\/td><\/tr><tr><td>Unicode (UTF-16)<\/td><td>\u2705 Optional<\/td><td>Enable <code>_LFN_UNICODE<\/code>. Careful memory handling needed for RTEMS.<\/td><\/tr><tr><td>Case Folding<\/td><td>\u2705 Built-in<\/td><td>FATFS matches FAT behavior (case-insensitive by default).<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>We\u2019ll ensure all these configurations are documented, tested, and enabled based on the use-case demands of embedded applications.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you\u2019ve worked with RTEMS, you\u2019re probably familiar with its DOSFS \u2014 a serviceable FAT implementation that&#8217;s grown over time. But what if we could swap it out with something smaller, simpler, and easier to maintain? That\u2019s exactly what this GSoC 2025 project aims to explore: porting FatFS, a lean and widely-used FAT\/exFAT implementation, into [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-12","post","type-post","status-publish","format-standard","hentry","category-gsoc"],"_links":{"self":[{"href":"https:\/\/blog.ganji.dev\/index.php?rest_route=\/wp\/v2\/posts\/12","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.ganji.dev\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.ganji.dev\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.ganji.dev\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.ganji.dev\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=12"}],"version-history":[{"count":3,"href":"https:\/\/blog.ganji.dev\/index.php?rest_route=\/wp\/v2\/posts\/12\/revisions"}],"predecessor-version":[{"id":17,"href":"https:\/\/blog.ganji.dev\/index.php?rest_route=\/wp\/v2\/posts\/12\/revisions\/17"}],"wp:attachment":[{"href":"https:\/\/blog.ganji.dev\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=12"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ganji.dev\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=12"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ganji.dev\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=12"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}