硬汉嵌入式论坛

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

关于MDK5使用filesystem和sd卡时卡检测的问题

[复制链接]

6

主题

72

回帖

90

积分

初级会员

积分
90
发表于 2020-2-21 17:01:02 | 显示全部楼层 |阅读模式
疫情闭关期间,找了块板子玩玩,全部使用RTE。写到sd卡的时候,发现这块板跟之前的不太一样,它没有检测脚。我以前其它板的时候都是有检测脚的,这板突然没有了让我呆住了。
接口用的是SDIO,理论上RTE_Device.h里改下检测脚就行的,但现在没有了,这个脚就不使能了?
之前也用过SPI的情况,在SPI模式下,要用户自己实现fs_mc_read_cd函数,以实现卡检测。
但现在直接就没有检测引脚了,查看了一下 fmedia函数的说明:
The function fmedia uses media device interface driver to detect the presence of a removable drive in the system (such as SD/MMC cards or USB Flash drives). In case of SD/MMC cards, it can be used even when card socket does not provide card detection pin, but only after a successful device initialization (i.e. after a successful call of fmount or fs_ioc_device_ctrl using fsDevCtrlCodeControlMedia). In such case, device presence is determined using internal register states.
哎,喜出望外,写了段代码测试了一下,fmedia确实可以正常返回状态。
  1. <blockquote><blockquote><blockquote>static fsStatus init_filesystem (void)
复制代码
测试发现只有用FS_CONTROL_MEDIA_INIT参数才行,其余两个我的卡返回错误。到这里,以为这样就完事了,这么轻松?

在任务里面通过定时调用fmedia函数检测SD卡,以实现热拔插功能,问题就出来了:
1.当上电没有插卡时,fs_ioc_device_ctrl函数无法初始化卡,会导致fmedia返回fsUnsupported;
2.软件在检测到拔卡后,会卸载SD卡,这也同样会导致fmedia返回fsUnsupported;
那么,最终情况就是,上电不插卡,或者拔出后再插入,fmedia都无法正常返回结果,就等于是不支持热拔插了。


到这里,虽然软件上肯定会有办法解决,但总是觉得没有检测脚来得直接爽快,所以我这里还是得出这样一个结论:
在设计需要支持热拔插的设备时,检测脚尽量不要省!


对于我上面这种情况,哪位朋友有比较舒服的解决方法的话,希望能够一起分享一下
回复

使用道具 举报

6

主题

72

回帖

90

积分

初级会员

积分
90
 楼主| 发表于 2020-2-21 17:12:00 | 显示全部楼层
代码贴的不对,重新贴一下

  1. static fsStatus init_filesystem (void)
  2. {
  3.     fsStatus stat;
  4.     fsFileInfo info;
  5.     FILE *pfrec;
  6.     char *opt = "/L SD Card /FAT32";
  7.    
  8.     /* 挂载TF卡 */
  9.     stat = fmount ("M0:");
  10.     if (stat == fsNoFileSystem)
  11.     {
  12.         /* 格式化,格式化完之后不知道是不是就自动挂载了 */
  13.         stat = fformat ("M0:", opt);
  14.     }
  15.    
  16.     pfrec = fopen("001.csv","a");
  17.     if(pfrec)
  18.     {
  19.         fclose(pfrec);
  20.         return(fsOK);
  21.     }
  22.        
  23.     return(fsError);
  24. }

  25. void check_SD(void)
  26. {
  27.     static uint16_t count = 0;
  28.     fsStatus        fstat;
  29.    
  30.     fstat = fmedia("M0:");
  31.     if(fstat == fsOK)
  32.     {
  33.         if(count < 5)
  34.         {
  35.             if(!lastSDstate)count++;
  36.         }
  37.         else if(count == 5)
  38.         {
  39.             /* 检测到插入卡 */
  40.             if(!lastSDstate)
  41.             {
  42.                 fstat = init_filesystem();
  43.                 if(fstat == fsOK)
  44.                 {
  45.                     lastSDstate = 1;
  46.                     count = 6;
  47.                 }
  48.             }
  49.         }
  50.     }
  51.     else
  52.     {
  53.         if(lastSDstate)if(count)count--;
  54.         if(count == 1)
  55.         {
  56.             /* 检测到拔卡 */
  57.             if(lastSDstate)
  58.             {
  59.                 lastSDstate = 0;
  60.                 count = 0;
  61.                 funmount ("M0:");
  62.             }
  63.         }
  64.     }
  65. }

  66. void Thread_SD (void *argument)
  67. {
  68.     osStatus_t     status;
  69.     fsStatus       fstat;
  70.     MEM_MSG_t      Msg;
  71.     L_MEM_BLOCK_t *pMem;
  72.     MEM_Type_e     mpType;
  73.     FILE          *pfrec;
  74.     int32_t        drv_id;
  75.     uint32_t       drv_sta;
  76.    
  77.     fstat = finit ("M0:");
  78.     if (fstat != fsOK)
  79.     {
  80.         /* 接口初始化失败 */
  81.         osThreadFlagsWait(0x01, osFlagsWaitAny, osWaitForever);
  82.     }
  83.        
  84.     drv_id = fs_ioc_get_id("M0:");
  85.     drv_sta = FS_CONTROL_MEDIA_INIT;
  86.     fstat = fs_ioc_device_ctrl(drv_id,fsDevCtrlCodeControlMedia,&drv_sta);
  87.     if(fstat == fsOK)
  88.     {
  89. //        fstat = fmount ("M0:");
  90.     }
  91.        
  92.     while (1)
  93.     {
  94.         /* 检查热拔插 */
  95.         check_SD();
  96.         
  97.         /* 等待其它线程发送的消息 */
  98.         status = osMessageQueueGet(qid_SDcard, &Msg, NULL, 200);
  99.         /* 成功接收到消息 */
  100.         if (status == osOK)
  101.         {
  102.             pMem = Msg.addr;
  103.             mpType = Msg.mem_Type;
  104.             /* 参数合法则存储此包数据 */
  105.             if(pMem && pMem->len && lastSDstate)
  106.             {
  107.                 status = osOK;
  108.                 if(     mpType == mp_Small ){if(pMem->len > S_DATA_LEN)status = osError;}
  109.                 else if(mpType == mp_Middle){if(pMem->len > M_DATA_LEN)status = osError;}
  110.                 else if(mpType == mp_Large ){if(pMem->len > L_DATA_LEN)status = osError;}
  111.                 if(status == osOK)
  112.                 {
  113.                     /* 存储,暂时没找到不开关文件的方法 */
  114.                     pfrec = fopen (filename, "a");
  115.                     if(pfrec)
  116.                     {
  117.                         fwrite (pMem->Buf, pMem->len, sizeof(uint8_t), pfrec);
  118.                         fclose(pfrec);
  119.                     }
  120.                 }
  121.             }
  122.             Free_Mem(mpType,pMem);
  123.         }
  124.     }
  125. }
复制代码
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115668
QQ
发表于 2020-2-21 17:19:30 | 显示全部楼层
没有检测引脚太不方便了,而且实时性差

会头我也试试不用检测引脚。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-5-11 04:05 , Processed in 0.228218 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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