硬汉嵌入式论坛

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

[技术讨论] 咨询:PC编程如何控制USB虚拟磁盘程序自动退出

[复制链接]

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
发表于 2021-5-25 01:47:13 | 显示全部楼层 |阅读模式

目的:PC控制TOOL 进入U盘模式,更新EMMC文件结束后退出U盘模式.

H7-TOOL 进入USB磁盘程序状态时,和上位机程序之间只能通过文件方式操作。
试过执行挂起USB设备的API,好像只是windows驱动层关闭了文件访问。STM32这边USB并不会收到任何消息。
大家有没其他的办法来控制。



回复

使用道具 举报

0

主题

99

回帖

99

积分

初级会员

积分
99
发表于 2021-5-25 08:29:49 | 显示全部楼层
搞成HID+MSC复合设备,用HID发控制指令?
回复

使用道具 举报

3

主题

163

回帖

172

积分

初级会员

积分
172
发表于 2021-5-25 08:31:23 | 显示全部楼层
可不可以这样,就是添加一个特殊文件,这个文件在传输时最后发送,下位机检测到这个文件后就退出U盘模式并将这个文件删掉。
回复

使用道具 举报

17

主题

248

回帖

299

积分

高级会员

积分
299
发表于 2021-5-25 08:52:39 | 显示全部楼层
楼主可以试调用windows的api来弹出磁盘设备。例如https://blog.csdn.net/qq2399431200/article/details/52336230
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106731
QQ
发表于 2021-5-25 09:43:22 | 显示全部楼层
ilcvm 发表于 2021-5-25 08:29
搞成HID+MSC复合设备,用HID发控制指令?

可以的,这种方式之前已经实现,需要单独的卸载和加载复合设备中的MSC,主要是怕用户的电脑上容易识别出错,还有待批量测试。
回复

使用道具 举报

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
 楼主| 发表于 2021-5-25 11:34:27 | 显示全部楼层
xieyang__ 发表于 2021-5-25 08:52
楼主可以试调用windows的api来弹出磁盘设备。例如https://blog.csdn.net/qq2399431200/article/details/523 ...

试过弹出U盘API,  STM32的USB未跟踪到有消息发过来。
回复

使用道具 举报

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
 楼主| 发表于 2021-5-25 11:39:03 | 显示全部楼层
jowo_pBuGF 发表于 2021-5-25 08:31
可不可以这样,就是添加一个特殊文件,这个文件在传输时最后发送,下位机检测到这个文件后就退出U盘模式并 ...

USB处于U盘操作模式时,是WINDOWS管理的扇区读写操作。这个时候只有加载FatFS文件系统来访问文件,相当于2个主机访问EMMC磁盘扇区。
回复

使用道具 举报

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
 楼主| 发表于 2021-5-25 11:39:04 | 显示全部楼层
jowo_pBuGF 发表于 2021-5-25 08:31
可不可以这样,就是添加一个特殊文件,这个文件在传输时最后发送,下位机检测到这个文件后就退出U盘模式并 ...

USB处于U盘操作模式时,是WINDOWS管理的扇区读写操作。这个时候只有加载FatFS文件系统来访问文件,相当于2个主机访问EMMC磁盘扇区。

不过我可以尝试下在写扇区的函数底层做个识别算法,识别512字节的扇区内容(不判断文件名和路径以及数据偏移),也就是说只要写入的文件中包含这512字节的特征数据,就执行退出操作。

回复

使用道具 举报

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
 楼主| 发表于 2021-5-26 00:12:24 | 显示全部楼层

已通过写入512字节的文件实现退出U盘模式。
实现方法不是最优,不过实现起来很简单。而且通过文件内容可以做不同的控制操作。

1、 在 int8_t STORAGE_Write(uint8_t lun, uint8_t * buf, uint32_t blk_addr,   uint16_t blk_len) 中判断512字节扇区内容,
   如果满足条件,设置 g_tVar.UsbEmmcRemoved = 1;
int8_t STORAGE_Write(uint8_t lun, uint8_t * buf, uint32_t blk_addr,
                     uint16_t blk_len)
{
    int8_t ret = -1;

printf_ok("STORAGE_Write %d, %d\r\n", blk_addr, blk_len);
    switch (lun)
    {
        case LUN_SD:   
            {
                CheckQuitFile(buf); /* 检查退出文件 */
               
                BSP_MMC_WriteBlocks((uint32_t *)buf, blk_addr, blk_len, 5000);
                while(BSP_MMC_GetCardState() != MMC_TRANSFER_OK);  

                ret = 0;
            }
            break;


2、在主程序中,  执行删除文件,并退出U盘状态。

    while (g_MainStatus == MS_USB_EMMC)
    {
        bsp_Idle();

        if (g_tVar.UsbEmmcRemoved == 1)
        {
            g_tVar.UsbEmmcRemoved = 0;
            
            bsp_DelayMS(1000);          /* 延迟1秒,等待windows写入文件执行完毕 */
            
            DeleteQuitFile();           /* 退出前删除退出文件 */
            
            g_MainStatus = MS_LINK_MODE;/* 退出U盘状态 */
        }


几个函数如下:
/*
*********************************************************************************************************
*    函 数 名: CheckQuitFile
*    功能说明: 判断512字节扇区内容,如果满足条件则退出USB磁盘模式。
*    形    参: 无      
*    返 回 值: 无
*********************************************************************************************************
*/

void CheckQuitFile(uint8_t *buf)
{
    uint32_t *p;
        
    p = (uint8_t *)buf;
    if (p[0] == 0x74697551)   /* Quit */
    {
        uint8_t i;
        
        for (i = 0; i < 128; i++)
        {
            if (p != 0x74697551)
            {
                break;
            }
        }
        
        if (i == 128)
        {
            g_tVar.UsbEmmcRemoved = 1;  /* 退出指令 */
        }
    }
}



/*
*********************************************************************************************************
*    函 数 名: DeleteQuitFile
*    功能说明: 删除退出文件
*    形    参: 无      
*    返 回 值: 无
*********************************************************************************************************
*/

void DeleteQuitFile(void)
{
    //#define EMMC_QUIT_FILE  "0:/H7-TOOL/quit_usb_emmc.txt"
    f_unlink(EMMC_QUIT_FILE);
}

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106731
QQ
发表于 2021-5-26 08:04:51 | 显示全部楼层
armfly 发表于 2021-5-26 00:12
已通过写入512字节的文件实现退出U盘模式。
实现方法不是最优,不过实现起来很简单。而且通过文件内容可 ...

每次写入都检查,略耗性能。这个地方可以优化下。
回复

使用道具 举报

3

主题

30

回帖

39

积分

新手上路

积分
39
发表于 2021-5-28 14:37:51 | 显示全部楼层
使用 磁盘弹出 是可以的 ,但是要使能STM32 的 VBUS引脚 中断功能,才可以获取得到正确的 hUsbDeviceFS.dev_state 设备状态
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-2 16:18 , Processed in 0.412077 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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