硬汉嵌入式论坛

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

RL-USB同时模拟NAND和SD卡已经实现

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106739
QQ
发表于 2021-2-16 10:37:55 | 显示全部楼层 |阅读模式

1111.png

  1. /*------------------------------------------------------------------------------
  2. * MDK Middleware - Component ::USB:Device:MSC
  3. * Copyright (c) 2004-2020 Arm Limited (or its affiliates). All rights reserved.
  4. *------------------------------------------------------------------------------
  5. * Name:    USBD_User_MSC_0.c
  6. * Purpose: USB Device Mass Storage Device class (MSC) User module
  7. * Rev.:    V6.3.4
  8. *----------------------------------------------------------------------------*/
  9. /**
  10. * \addtogroup usbd_mscFunctions
  11. *
  12. */


  13. //! [code_USBD_User_MSC]

  14. #include <stdint.h>
  15. #include <stdbool.h>
  16. #include <string.h>
  17. #include "rl_usb.h"

  18. // If the USE_FILE_SYSTEM value is 1 then File System is used and media can
  19. // be accessed from application code or can be accessed by USB Mass Storage
  20. // requests, default media in that case is one selected as default in File
  21. // System Configuration file.
  22. // If the USE_FILE_SYSTEM value is 0 then File System is not used and media
  23. // can only be accessed by USB Mass Storage requests, default media in that
  24. // case is RAM memory containing dummy disk image.
  25. #define USE_FILE_SYSTEM   1             // 1 = File System is used, 0 = File System is not used

  26. // Definition MEDIA_DRIVE is used to define Drive to be used for media
  27. // Available options are:
  28. //   "R:" or "R0:" if media is RAM
  29. //   "M:" or "M0:" if media is Memory Card 0
  30. //           "M1:" if media is Memory Card 1
  31. //   "N:" or "N0:" if media is NAND Flash 0
  32. //           "N1:" if media is NAND Flash 1
  33. #define MEDIA_DRIVE     "M0:"
  34. #define MEDIA_DRIVE1     "N0:"

  35. #if (USE_FILE_SYSTEM == 1)              // If File System is used
  36. #include "rl_fs.h"
  37. #define  MEDIA_OWN_USB     (1U     )    // Media owned by USB (bit mask)
  38. #define  MEDIA_OWN_CHG     (1U << 1)    // Media ownership change requested (bit mask)
  39. extern
  40.    
  41. volatile uint8_t  usbd_msc0_media_own;
  42. volatile uint8_t  usbd_msc0_media_own;  // USB MSC0 media ownership
  43. static   int32_t  drv_id;               // FAT drive id
  44. static   bool     media_ok;             // Media is initialized and ok

  45. volatile uint8_t  usbd_msc0_media_own1;
  46. volatile uint8_t  usbd_msc0_media_own1;  // USB MSC0 media ownership
  47. static   int32_t  drv_id1;               // FAT drive id
  48. static   bool     media_ok1;             // Media is initialized and ok

  49. #else
  50. static   uint32_t memory   [8192/4];    // Memory in RAM for dummy disk image
  51. static   uint32_t block_buf[ 512/4];    // Buffer for block read/write to media
  52. extern
  53. const    uint8_t  memory_disk_image[4096];  // Dummy Memory Disk Image
  54. #endif


  55. // Called during USBD_Initialize to initialize the USB MSC class instance.
  56. void USBD_MSC0_Initialize (void) {

  57. #if (USE_FILE_SYSTEM == 1)              // If File System is used
  58.   uint32_t param_status;

  59.   usbd_msc0_media_own = MEDIA_OWN_USB;  // Initially media is owned by USB
  60.   media_ok            = false;          // Current media status (not initialized = not ok)

  61.   if (finit (MEDIA_DRIVE) != fsOK) {    // Initialize File System
  62.     return;                             // Exit if failed
  63.   }

  64.   drv_id = fs_ioc_get_id (MEDIA_DRIVE); // Get ID of media drive
  65.   if (drv_id < 0)           { return; } // If ID is invalid exit

  66.   param_status = 0U;                    // Parameter for function call is 0
  67.                                         // Initialize media
  68.   if (fs_ioc_device_ctrl (drv_id, fsDevCtrlCodeControlMedia, &#182;m_status) != fsOK) {
  69.     return;                             // Exit if failed
  70.   }

  71.   if (fs_ioc_lock (drv_id)) {           // Lock media for USB usage
  72.     return;                             // Exit if failed
  73.   }

  74.   media_ok = true;                      // Media was initialized and is ok
  75.   
  76.   /////////////////////////////////////////////////////////////////////////////////////////
  77.   /////////////////////////////////////////////////////////////////////////////////////////  
  78.   uint32_t param_status1;

  79.   usbd_msc0_media_own1 = MEDIA_OWN_USB;  // Initially media is owned by USB
  80.   media_ok1            = false;          // Current media status (not initialized = not ok)

  81.   if (finit (MEDIA_DRIVE1) != fsOK) {    // Initialize File System
  82.     return;                              // Exit if failed
  83.   }

  84.   drv_id1 = fs_ioc_get_id (MEDIA_DRIVE1); // Get ID of media drive
  85.   if (drv_id1 < 0)           { return; }  // If ID is invalid exit

  86.   param_status1 = 0U;                    // Parameter for function call is 0
  87.                                          // Initialize media
  88.   if (fs_ioc_device_ctrl (drv_id, fsDevCtrlCodeControlMedia, &#182;m_status1) != fsOK) {
  89.     return;                              // Exit if failed
  90.   }

  91.   if (fs_ioc_lock (drv_id1)) {           // Lock media for USB usage
  92.     return;                              // Exit if failed
  93.   }

  94.   media_ok1 = true;                      // Media was initialized and is ok
  95. #else
  96.                                         // Copy the dummy image from code to RAM
  97.   memcpy (memory, memory_disk_image, sizeof(memory_disk_image));
  98. #endif
  99. }


  100. // \brief Called during USBD_Uninitialize to de-initialize the USB MSC class instance.
  101. void USBD_MSC0_Uninitialize (void) {
  102.   // Add code for de-initialization
  103. }


  104. // Get cache information.
  105. // \param[out]    buffer               cache buffer address.
  106. // \param[out]    size                 cache buffer size.
  107. // \return        true                 operation succeeded.
  108. // \return        false                operation failed.
  109. bool USBD_MSC0_GetCacheInfo (uint32_t *buffer, uint32_t *size) {

  110. #if (USE_FILE_SYSTEM == 1)              // If File System is used
  111.   fsIOC_Cache cache_info;

  112.   // Get cache settings of File System
  113.   if (fs_ioc_get_cache(drv_id, &cache_info) != fsOK) {
  114.     return false;                       // Exit if failed
  115.   }

  116.   // Use File Systems cache for MSC
  117.   *buffer = (uint32_t)cache_info.buffer;// Cache buffer from File System
  118.   *size   = cache_info.size;            // Cache size
  119. #else
  120.   *buffer = (uint32_t)block_buf;        // Local buffer for data
  121.   *size   = sizeof(block_buf);          // Size of local buffer
  122. #endif

  123.   return true;
  124. }

  125. // Get maximum number of logical units.
  126. // \return                             number of logical units that device contains
  127. //                                       - value > 0 and <= 4 : maximum number of logical units
  128. //                                       - value 0 :            use setting from configuration file
  129. uint8_t USBD_MSC0_GetMaxLUN (void) {

  130.   return 2U;                            // Device contains 2 logical units
  131. }


  132. // Get media capacity.
  133. // \param[out]    block_count          total number of blocks on media.
  134. // \param[out]    block_size           media block size.
  135. // \return        true                 operation succeeded.
  136. // \return        false                operation failed.
  137. bool USBD_MSC0_LUN_GetMediaCapacity (uint8_t lun, uint32_t *block_count, uint32_t *block_size) {

  138. #if (USE_FILE_SYSTEM == 1)              // If File System is used
  139.   fsMediaInfo media_info;
  140.    
  141.   if(lun == 0)
  142.   {
  143.       // Read media information of actual media
  144.       if (fs_ioc_read_info(drv_id, &media_info) != fsOK) {
  145.         return false;                       // Exit if failed
  146.       }
  147.      
  148.       *block_count = media_info.block_cnt;  // Total number of blocks on media
  149.       *block_size  = media_info.read_blen;  // Block size of blocks on media  
  150.   }
  151.   else
  152.   {
  153.       // Read media information of actual media
  154.       if (fs_ioc_read_info(drv_id1, &media_info) != fsOK) {
  155.         return false;                       // Exit if failed
  156.       }
  157.      
  158.       *block_count = media_info.block_cnt;  // Total number of blocks on media
  159.       *block_size  = media_info.read_blen;  // Block size of blocks on media      
  160.   }
  161. #else
  162.   *block_count = sizeof(memory)/512U;   // Total number of blocks on media
  163.   *block_size  = 512U;                  // Block size of blocks on media
  164. #endif

  165.   return true;
  166. }


  167. // Read data from media.
  168. // \param[in]     lba                  logical address of first block to read.
  169. // \param[in]     cnt                  number of contiguous blocks to read from media.
  170. // \param[out]    buf                  data buffer for data read from media.
  171. // \return        true                 read succeeded.
  172. // \return        false                read failed.
  173. bool USBD_MSC0_LUN_Read (uint8_t lun, uint32_t lba, uint32_t cnt, uint8_t *buf) {

  174. #if (USE_FILE_SYSTEM == 1)              // If File System is used
  175.   if(lun == 0)                                     // Read data directly from media
  176.   {
  177.       if (fs_ioc_read_sector (drv_id, lba, buf, cnt) != fsOK) {
  178.         return false;
  179.       }  
  180.   }
  181.   else
  182.   {
  183.      if (fs_ioc_read_sector (drv_id1, lba, buf, cnt) != fsOK) {
  184.        return false;
  185.      }
  186.   }
  187. #else
  188.                                         // Read data from dummy image in RAM
  189.   memcpy (buf, &memory[lba * (512U/4U)], cnt * 512U);
  190. #endif

  191.   return true;
  192. }


  193. // Write data to media.
  194. // \param[in]     lba                  logical address of first block to write.
  195. // \param[in]     cnt                  number of contiguous blocks to write to media.
  196. // \param[out]    buf                  data buffer containing data to write to media.
  197. // \return        true                 write succeeded.
  198. // \return        false                write failed.
  199. bool USBD_MSC0_LUN_Write (uint8_t lun, uint32_t lba, uint32_t cnt, const uint8_t *buf) {

  200. #if (USE_FILE_SYSTEM == 1)              // If File System is used
  201.                                         // Write data directly to media
  202.   if(lun == 0)
  203.   {
  204.       if (fs_ioc_write_sector (drv_id, lba, buf, cnt) != fsOK) {
  205.         return false;
  206.       }   
  207.   }
  208.   else
  209.   {
  210.       if (fs_ioc_write_sector (drv_id1, lba, buf, cnt) != fsOK) {
  211.         return false;
  212.       }   
  213.   }
  214. #else
  215.                                         // Write data to image in RAM
  216.   memcpy (&memory[lba * (512U/4U)], buf, cnt * 512U);
  217. #endif

  218.   return true;
  219. }


  220. // Check media presence and write protect status.
  221. //        (if media is not owned by USB it returns that media is not ready)
  222. // \return                             media presence and write protected status
  223. //                bit 1:               write protect bit
  224. //                 - value 1:            media is write protected
  225. //                 - value 0:            media is not write protected
  226. //                bit 0:               media presence bit
  227. //                 - value 1:            media is present
  228. //                 - value 0:            media is not present
  229. uint32_t USBD_MSC0_LUN_CheckMedia (uint8_t lun) {

  230. #if (USE_FILE_SYSTEM == 1)              // If File System is used
  231.        uint32_t param_status;
  232.        uint8_t  media_state;            // Bit 0. media ready, Bit 1. media write protect
  233. static uint8_t  media_ready_ex = 0U;    // Previous media ready state
  234.        uint8_t  own;

  235.   if(lun == 0)  
  236.   {
  237.      // Get current media status
  238.       media_state = 0U;
  239.       switch (fs_ioc_device_ctrl (drv_id, fsDevCtrlCodeCheckMedia, &#182;m_status)) {
  240.         case fsOK:
  241.           if (param_status & FS_MEDIA_NOCHKMEDIA) {
  242.             // If check media not available on hardware layer
  243.             media_state  =  USBD_MSC_MEDIA_READY;
  244.             break;
  245.           }
  246.           if (param_status & FS_MEDIA_INSERTED) {
  247.             media_state  =  USBD_MSC_MEDIA_READY;
  248.           }
  249.           if (param_status & FS_MEDIA_PROTECTED) {
  250.             media_state |=  USBD_MSC_MEDIA_PROTECTED;
  251.           }
  252.           break;
  253.         case fsError:
  254.         case fsUnsupported:
  255.         case fsAccessDenied:
  256.         case fsInvalidParameter:
  257.         case fsInvalidDrive:
  258.         case fsInvalidPath:
  259.         case fsUninitializedDrive:
  260.         case fsDriverError:
  261.         case fsMediaError:
  262.         case fsNoMedia:
  263.         case fsNoFileSystem:
  264.         case fsNoFreeSpace:
  265.         case fsFileNotFound:
  266.         case fsDirNotEmpty:
  267.         case fsTooManyOpenFiles:
  268.         case fsAlreadyExists:
  269.         case fsNotDirectory:
  270.           break;
  271.       }
  272.      
  273.       // Store current owner so no new request can interfere
  274.       own = usbd_msc0_media_own;
  275.      
  276.       // De-initialize media according to previous owner
  277.       if (own & MEDIA_OWN_CHG) {                    // If owner change requested
  278.         if (own & MEDIA_OWN_USB) {                  // If new requested owner is USB (previous owner was File System)
  279.           (void)funmount (MEDIA_DRIVE);             // De-initialize media and dismount Drive
  280.         } else {                                    // If new requested owner is File System (previous owner was USB)
  281.           (void)fs_ioc_unlock (drv_id);             // Un-lock media
  282.         }
  283.       }
  284.      
  285.       // Initialize media according to current owner
  286.       if ((own & MEDIA_OWN_CHG)        ||           // If owner change requested or
  287.           (media_state ^ media_ready_ex)) {         // if media ready state has changed (disconnect(SD remove)/connect(SD insert))
  288.         if (media_state & USBD_MSC_MEDIA_READY) {   // If media is ready
  289.           if (own & MEDIA_OWN_USB){                 // If current owner is USB
  290.             media_ok     = false;                   // Invalidate current media status (not initialized = not ok)
  291.             param_status = 0U;                      // Parameter for function call is 0
  292.             if (fs_ioc_device_ctrl (drv_id, fsDevCtrlCodeControlMedia, &#182;m_status) == fsOK) {
  293.                                                     // Initialization of media has succeeded
  294.               if (fs_ioc_lock (drv_id) == fsOK) {   // If lock media for USB usage has succeeded
  295.                 media_ok = true;                    // Media was initialized and is ok
  296.               }
  297.             }
  298.           } else {                                  // If current owner is File System
  299.             if (fmount (MEDIA_DRIVE) == fsOK) {     // Initialize media and Mount Drive for File System usage
  300.               media_ok = true;                      // Media was initialized and is ok
  301.             }
  302.           }
  303.         }
  304.         if (own & MEDIA_OWN_CHG) {
  305.           usbd_msc0_media_own &= ~MEDIA_OWN_CHG;    // Clear request to change media owner if it was handled
  306.         }
  307.         media_ready_ex = media_state & USBD_MSC_MEDIA_READY;
  308.       }
  309.      
  310.       // If media is not ok or owned by File System return that it is not ready for USB
  311.       if ((!media_ok) || (!(usbd_msc0_media_own & MEDIA_OWN_USB))) {
  312.         return 0U;
  313.       }  
  314.   }
  315.   else
  316.   {
  317.      // Get current media status
  318.       media_state = 0U;
  319.       switch (fs_ioc_device_ctrl (drv_id1, fsDevCtrlCodeCheckMedia, &#182;m_status)) {
  320.         case fsOK:
  321.           if (param_status & FS_MEDIA_NOCHKMEDIA) {
  322.             // If check media not available on hardware layer
  323.             media_state  =  USBD_MSC_MEDIA_READY;
  324.             break;
  325.           }
  326.           if (param_status & FS_MEDIA_INSERTED) {
  327.             media_state  =  USBD_MSC_MEDIA_READY;
  328.           }
  329.           if (param_status & FS_MEDIA_PROTECTED) {
  330.             media_state |=  USBD_MSC_MEDIA_PROTECTED;
  331.           }
  332.           break;
  333.         case fsError:
  334.         case fsUnsupported:
  335.         case fsAccessDenied:
  336.         case fsInvalidParameter:
  337.         case fsInvalidDrive:
  338.         case fsInvalidPath:
  339.         case fsUninitializedDrive:
  340.         case fsDriverError:
  341.         case fsMediaError:
  342.         case fsNoMedia:
  343.         case fsNoFileSystem:
  344.         case fsNoFreeSpace:
  345.         case fsFileNotFound:
  346.         case fsDirNotEmpty:
  347.         case fsTooManyOpenFiles:
  348.         case fsAlreadyExists:
  349.         case fsNotDirectory:
  350.           break;
  351.       }
  352.      
  353.       // Store current owner so no new request can interfere
  354.       own = usbd_msc0_media_own1;
  355.      
  356.       // De-initialize media according to previous owner
  357.       if (own & MEDIA_OWN_CHG) {                    // If owner change requested
  358.         if (own & MEDIA_OWN_USB) {                  // If new requested owner is USB (previous owner was File System)
  359.           (void)funmount (MEDIA_DRIVE);             // De-initialize media and dismount Drive
  360.         } else {                                    // If new requested owner is File System (previous owner was USB)
  361.           (void)fs_ioc_unlock (drv_id1);             // Un-lock media
  362.         }
  363.       }
  364.      
  365.       // Initialize media according to current owner
  366.       if ((own & MEDIA_OWN_CHG)        ||           // If owner change requested or
  367.           (media_state ^ media_ready_ex)) {         // if media ready state has changed (disconnect(SD remove)/connect(SD insert))
  368.         if (media_state & USBD_MSC_MEDIA_READY) {   // If media is ready
  369.           if (own & MEDIA_OWN_USB){                 // If current owner is USB
  370.             media_ok1     = false;                   // Invalidate current media status (not initialized = not ok)
  371.             param_status = 0U;                      // Parameter for function call is 0
  372.             if (fs_ioc_device_ctrl (drv_id1, fsDevCtrlCodeControlMedia, &#182;m_status) == fsOK) {
  373.                                                     // Initialization of media has succeeded
  374.               if (fs_ioc_lock (drv_id1) == fsOK) {   // If lock media for USB usage has succeeded
  375.                 media_ok = true;                    // Media was initialized and is ok
  376.               }
  377.             }
  378.           } else {                                  // If current owner is File System
  379.             if (fmount (MEDIA_DRIVE1) == fsOK) {     // Initialize media and Mount Drive for File System usage
  380.               media_ok = true;                      // Media was initialized and is ok
  381.             }
  382.           }
  383.         }
  384.         if (own & MEDIA_OWN_CHG) {
  385.           usbd_msc0_media_own1 &= ~MEDIA_OWN_CHG;    // Clear request to change media owner if it was handled
  386.         }
  387.         media_ready_ex = media_state & USBD_MSC_MEDIA_READY;
  388.       }
  389.      
  390.       // If media is not ok or owned by File System return that it is not ready for USB
  391.       if ((!media_ok1) || (!(usbd_msc0_media_own1 & MEDIA_OWN_USB))) {
  392.         return 0U;
  393.       }   
  394.   }
  395.   
  396.   return media_state;
  397. #else
  398.   return USBD_MSC_MEDIA_READY;
  399. #endif
  400. }
  401. //! [code_USBD_User_MSC]
复制代码


回复

使用道具 举报

2

主题

8

回帖

14

积分

新手上路

积分
14
发表于 2021-3-24 21:13:14 | 显示全部楼层
工程文件能传上来吗
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106739
QQ
 楼主| 发表于 2021-3-25 09:43:54 | 显示全部楼层
ztrx 发表于 2021-3-24 21:13
工程文件能传上来吗

基于STM32H7的RTX5+RL-USB+RL-FlashFS+RL-TCPnet+emWin6.x综合模板发布,含MDK AC5和AC6,升级至V1.1(2021-03-01)
http://www.armbbs.cn/forum.php?m ... 4012&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

41

主题

112

回帖

235

积分

高级会员

积分
235
发表于 2021-4-9 17:21:27 | 显示全部楼层
厉害,有基于freertos的版本吗?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106739
QQ
 楼主| 发表于 2021-4-10 08:36:32 | 显示全部楼层
bear_yh 发表于 2021-4-9 17:21
厉害,有基于freertos的版本吗?

没整。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-3 14:27 , Processed in 0.221833 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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