硬汉嵌入式论坛

 找回密码
 立即注册
查看: 8166|回复: 3
收起左侧

[ThreadX全家桶] 通过标准库文件操作访问 FILEX 文件系统

[复制链接]

58

主题

267

回帖

446

积分

高级会员

积分
446
发表于 2020-11-20 23:38:20 | 显示全部楼层 |阅读模式
移植 FILEX 文件系统后,因为要使用 LUA 直接执行文件的功能,就需要实现标准库中的文件操作。经过摸索已经实现了用到的需求(不是全部的标准库文件操作),实现流程如下:

1、开启 microlib 库,不开启微库的实现流程与这里描述的不一样,复杂得多。
2、移植好 FILEX。 具体移植过程不详述,可参考论坛中其他道友的帖子。
3、实现 fopen, fclose, fwrite, fread, fseek 五个文件操作函数。 其中 fopen 只实现了 "r", "r+", "w" 和 “w+” 四种模式,且行为与标准库不完全一样,但已满足目前的需求,可自行添加更多功能。
4、实现 fputs 和 fgets 函数。主要用于 printf。
5、代码中的 BSP_COM_Send 是串口发送函数,要自己实现。 如果要用到 lua 的 print 函数,则要在 fwrite 中调用 BSP_COM_Send ,printf 要在 fputs 中调用 BSP_COM_Send 。6、time, exit 和 system 是移植 LUA 需要添加的函数。

代码如下:
  1. #include <stdio.h>
  2. #include <string.h>
复制代码


代码贴上后发布出来咋只有 2 行? 重贴一次

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "fx_api.h"


  4. VOID _fx_spiflash_driver(FX_MEDIA *media_ptr);

  5. static unsigned char media_memory[4096];
  6. static FX_MEDIA fs_disk;
  7. static uint8_t fs_is_inited = 0;
  8. static TX_BLOCK_POOL fs_block_pool;

  9. /*
  10.     文件系统初始化
  11.     每次打开文件时都要进行初始化,如果filex已经初始化,则仅进行计数累加,如果未初始化则初始化filex
  12. */
  13. static UINT fs_init(void)
  14. {
  15.     TX_INTERRUPT_SAVE_AREA
  16.     UINT  status = FX_SUCCESS;
  17.     static uint8_t fs_block_inited = 0;

  18.     TX_DISABLE

  19.     /* 创建文件系统的块内存,用于分配 FX_FILE 文件句柄 */
  20.     if(fs_block_inited == 0)
  21.     {
  22.         status = tx_block_pool_create(&fs_block_pool, "fs block pool", sizeof(FX_FILE), (void*)BSP_FILEX_BLOCK_ADDR, BSP_FILEX_BLOCK_SIZE);
  23.         if(status != TX_SUCCESS)
  24.         {
  25.             TX_RESTORE
  26.             return status;
  27.         }
  28.         fs_block_inited = 1;
  29.     }

  30.     /* 打开 FILEX 媒体设备 */
  31.     if(fs_is_inited == 0)
  32.     {
  33.         /* Initialize FileX.  */
  34.         fx_system_initialize();

  35.         /* Open the SPIFLASH disk.  */
  36.         status = fx_media_open(&fs_disk, "SPIFLASH DISK", _fx_spiflash_driver, 0, media_memory, sizeof(media_memory));

  37.         /* Check the media open status.  */
  38.         if (status != FX_SUCCESS)
  39.         {
  40.             fx_media_format(&fs_disk,
  41.                             _fx_spiflash_driver,    // Driver entry
  42.                             0,                      // RAM disk memory pointer
  43.                             media_memory,           // Media buffer pointer
  44.                             sizeof(media_memory),   // Media buffer size
  45.                             "D_SPIFLASH",           // Volume Name
  46.                             1,                      // Number of FATs
  47.                             32,                     // Directory Entries
  48.                             0,                      // Hidden sectors
  49.                             4096*2,                 // Total sectors
  50.                             4096,                   // Sector size
  51.                             1,                      // Sectors per cluster
  52.                             1,                      // Heads
  53.                             1);                     // Sectors per track

  54.             /* Open the SPIFLASH disk again. */
  55.             status = fx_media_open(&fs_disk, "SPIFLASH DISK", _fx_spiflash_driver, 0, media_memory, sizeof(media_memory));
  56.         }

  57.         if(status == FX_SUCCESS)
  58.         {
  59.             fs_is_inited = 1;
  60.         }
  61.     }
  62.     else
  63.     {
  64.         fs_is_inited++;
  65.     }   

  66.     TX_RESTORE

  67.     return status;
  68. }

  69. /*
  70.     文件系统关闭
  71. */
  72. static void fs_deinit(void)
  73. {
  74.     TX_INTERRUPT_SAVE_AREA

  75.     TX_DISABLE

  76.     if(fs_is_inited)
  77.     {
  78.         fs_is_inited--;
  79.         if(fs_is_inited == 0)
  80.         {
  81.             /* Close the media.  */
  82.             fx_media_close(&fs_disk);
  83.         }
  84.     }

  85.     TX_RESTORE
  86. }


  87. #define O_RDONLY    0
  88. #define O_RDWR      1
  89. #define O_CREATE    2

  90. FILE* fopen(const char* filename, const char* mode)
  91. {
  92.     UINT    status;
  93.     FX_FILE *file = TX_NULL;
  94.     int     fmode = O_RDONLY;

  95.     if(fs_init() != FX_SUCCESS)
  96.     {
  97.         return 0;
  98.     }

  99.          if(strcmp(mode, "r") == 0)   fmode = O_RDONLY;
  100.     else if(strcmp(mode, "r+") == 0)  fmode = O_RDWR;
  101.     else if(strcmp(mode, "w") == 0)   fmode = O_CREATE | O_RDWR;
  102.     else if(strcmp(mode, "w+") == 0)  fmode = O_CREATE | O_RDWR;
  103.     else
  104.     {
  105.         fs_deinit();
  106.         return 0;
  107.     }

  108.     if(fmode & O_CREATE)
  109.     {
  110.         /* Create file */
  111.         status =  fx_file_create(&fs_disk, (char*)filename);
  112.         /* Check the create status.  */
  113.         if (status != FX_SUCCESS)
  114.         {
  115.             /* Check for an already created status. */
  116.             if (status != FX_ALREADY_CREATED)
  117.             {
  118.                 fs_deinit();
  119.                 return 0;
  120.             }
  121.         }
  122.     }

  123.     /* 为文件指针分配内存 */
  124.     status = tx_block_allocate(&fs_block_pool, (void**)&file, TX_NO_WAIT);
  125.     if(status != TX_SUCCESS)
  126.     {
  127.         fs_deinit();
  128.         return 0;
  129.     }

  130.     /* Open the test file.  */
  131.     if(fmode & O_RDWR)
  132.     {
  133.         status =  fx_file_open(&fs_disk, file, (char*)filename, FX_OPEN_FOR_WRITE);
  134.     }
  135.     else
  136.     {
  137.         status =  fx_file_open(&fs_disk, file, (char*)filename, FX_OPEN_FOR_READ);
  138.     }
  139.     /* Check the file open status.  */
  140.     if (status != FX_SUCCESS)
  141.     {
  142.         tx_block_release(file);
  143.         fs_deinit();
  144.         return 0;
  145.     }

  146.     /* Seek to the beginning of the file.  */
  147.     status =  fx_file_seek(file, 0);
  148.     /* Check the file seek status.  */
  149.     if (status != FX_SUCCESS)
  150.     {
  151.         tx_block_release(file);
  152.         fs_deinit();
  153.         return 0;
  154.     }

  155.     return (FILE*)file;
  156. }

  157. int fclose(FILE* stream)
  158. {
  159.     /* Close the file.  */
  160.     fx_file_close((FX_FILE*)stream);
  161.     tx_block_release((void*)stream);
  162.     fs_deinit();

  163.     return 0;
  164. }

  165. size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
  166. {
  167.     if((stream == &__stdout) || (stream == &__stderr))
  168.     {
  169.         // lua 的 print 会调用到这里
  170.         BSP_COM_Send((uint8_t*)ptr, size*nmemb);
  171.         return nmemb;
  172.     }

  173.     if(stream == &__stdin)
  174.     {
  175.         return -1;
  176.     }

  177.     if(fx_file_write((FX_FILE*)stream, (void*)ptr, size*nmemb) != FX_SUCCESS)
  178.     {
  179.         return 0;
  180.     }
  181.     else
  182.     {
  183.         return nmemb;
  184.     }
  185. }

  186. size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
  187. {
  188.     ULONG actual;

  189.     if(fx_file_read((FX_FILE*)stream, (void*)ptr, size*nmemb, &actual) != FX_SUCCESS)
  190.     {
  191.         return 0;
  192.     }
  193.     else
  194.     {
  195.         return actual/size;
  196.     }
  197. }

  198. int fseek(FILE *stream, long int offset, int whence)
  199. {
  200.     ULONG off;
  201.     UINT seek_from;

  202.     switch(whence)
  203.     {
  204.     case SEEK_SET:
  205.         seek_from = FX_SEEK_BEGIN;
  206.         off = offset;
  207.         break;
  208.     case SEEK_END:
  209.         seek_from = FX_SEEK_END;
  210.         off = offset;
  211.         break;
  212.     case SEEK_CUR:
  213.         if(offset < 0)
  214.         {
  215.             seek_from = FX_SEEK_BACK;
  216.             off = -offset;
  217.         }
  218.         else
  219.         {
  220.             seek_from = FX_SEEK_FORWARD;
  221.             off = offset;
  222.         }
  223.     default:
  224.         break;
  225.     }

  226.     /* position is relative to the start of file fh */
  227.     if(fx_file_relative_seek((FX_FILE*)stream, offset, seek_from) != FX_SUCCESS)
  228.     {
  229.         return -1;
  230.     }
  231.     else
  232.     {
  233.         return 0;
  234.     }   
  235. }

  236. int fputc(int ch, FILE* stream)
  237. {
  238.     if((stream == &__stdout) || (stream == &__stderr))
  239.     {
  240.         // printf 函数会调用到这里
  241.         BSP_COM_Send((uint8_t*)&ch, 1);
  242.         return ch;
  243.     }

  244.     if(stream == &__stdin)
  245.     {
  246.         return -1;
  247.     }

  248.     {
  249.         UCHAR dat = ch;
  250.         if(fx_file_write((FX_FILE*)stream, &dat, 1) != FX_SUCCESS)
  251.         {
  252.             return -1;
  253.         }
  254.         return ch;
  255.     }
  256. }

  257. int fgetc(FILE *stream)
  258. {
  259.     UINT  status;
  260.     UCHAR ch;
  261.     ULONG actual;

  262.     status = fx_file_read((FX_FILE*)stream, &ch, 1, &actual);
  263.     if((status != FX_SUCCESS) || (actual != 1))
  264.     {
  265.         return -1;
  266.     }
  267.     return ch;
  268. }

  269. time_t time(time_t * time)
  270. {
  271.     return 0;
  272. }

  273. void exit(int status)
  274. {
  275.     while(1);
  276. }

  277. int system(const char * string)
  278. {
  279.     return 0;
  280. }
复制代码





回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115804
QQ
发表于 2020-11-21 09:52:54 | 显示全部楼层
谢谢楼主分享。
回复

使用道具 举报

24

主题

70

回帖

142

积分

初级会员

积分
142
发表于 2021-1-27 10:45:04 | 显示全部楼层
有没有把类似linux或yaffs文件系统转换到标准文件系统的例子?,尤其是文件描述符 int fd 与文件指针 FILE *fp的转换
回复

使用道具 举报

58

主题

267

回帖

446

积分

高级会员

积分
446
 楼主| 发表于 2021-1-27 18:48:59 | 显示全部楼层
utyang 发表于 2021-1-27 10:45
有没有把类似linux或yaffs文件系统转换到标准文件系统的例子?,尤其是文件描述符 int fd 与文件指针 FILE  ...

没有
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-5-20 00:27 , Processed in 0.439842 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表