OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 59|回复: 0

《ESP32-P4开发指南— V1.0》第四十七章 USB U盘实验

[复制链接]

1262

主题

1276

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
5418
金钱
5418
注册时间
2019-5-8
在线时间
1404 小时
发表于 昨天 09:20 | 显示全部楼层 |阅读模式
第四十七章 USB U盘实验

1)实验平台:正点原子DNESP32P4开发板

2)章节摘自【正点原子】ESP32-P4开发指南— V1.0

3)购买链接:https://detail.tmall.com/item.htm?id=873309579825

4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/esp32/ATK-DNESP32P4.html

5)正点原子官方B站:https://space.bilibili.com/394620890

6)正点原子DNESP32S3开发板技术交流群:132780729


2.jpg

3.png

本章我们介绍ESP32-P4的USB HOST应用,即通过USB HOST功能,实现读写U盘/读卡器等大容量USB存储设备。
本章分为如下几个部分:
47.1 U盘简介
47.2 硬件设计
47.3 程序设计
47.4 下载验证


47.1 U盘简介
U盘(USB闪存盘,英文名:USB flash disk)是一种通过USB接口连接主机的微型高容量移动存储设备。它无需物理驱动器,支持即插即用,是最常用的移动存储工具之一。
ESP32-P4的USB OTG HS接口支持U盘功能。Espressif官方在ESP-IDF中提供了针对USB HOST大容量存储设备(MSC)的示例代码,路径为:esp-idf\examples\peripherals\usb\host\msc。本实验将参考官方示例代码,通过ESP32-P4的USB HOST接口实现对U盘或SD卡读卡器等设备的读写操作。

47.2 硬件设计

47.2.1 程序功能
本实验代码,开机后,初始化LCD和USB HOST,并不断轮询。当检测并识别U盘后,在LCD上面显示U盘总容量和连接状态。我们可通过espressif的REPL调用FATFS相关函数,来测试U盘数据的读写了。

47.2.2 硬件资源
1)RGBLCD/MIPILCD(引脚太多,不罗列出来)
2)USB_HOST HS接口

47.2.3 原理图
本开发板的USB HOST接口采用的是贴片USB母座,它和USB SLAVE是共用USB_DM和USB_DP信号的,所以USB HOST和USB SLAVE接口不能同时使用。USB HOST和ESP32-P4的连接原理图,如下图所示:

第四十七章 USB U盘实验726.png
图47.2.2.1 USB母座与ESP32-P4的连接电路图

从上图可以看出,USB母座(USB_HOST)是直接连接到ESP32-P4上面的,所以硬件上不需要我们做什么操作,可直接使用。
需要注意的是:本实验被测试的U盘是通过USB母座(USB_HOST)连接到ESP32-P4的,此时,USB_SLAVE接口是不能连接USB设备或者主机的。如果需要用到USB转串口,数据线可以通过USB_ UART接口连接到电脑。
下面,看看开发板上的USB母座(USB_HOST)的位置,请将U盘插入这个接口上。


第四十七章 USB U盘实验981.png
图47.2.2.2 开发板U盘母座

47.3 程序设计

47.3.1 USB HOST MSC的IDF驱动
usb_host_msc组件驱动位于ESP-IDF在线组件注册表中。如果需要将该组件添加到项目工程中,可按照以下步骤操作:
1)打开ESP-IDF注册表。
2)搜索 “usb_host_msc”组件。
3)将组件安装到项目中。
组件安装完成后,系统会自动更新main文件夹中的特殊组件清单文件idf_component.yml在项目编译时,系统会根据清单文件从注册表中下载并集成该组件到工程中。关于上述操作流程,可参考本书籍第八章的内容。
为了使用 usb_host_msc 组件提供的功能,首先需要在代码中导入以下头文件:
  1. #include "usb_hid_msc.h"
复制代码
接下来,作者将介绍一些常用的usb_host_msc函数,这些函数的描述及其作用如下:
1,安装USB HOST usb_host_install
该函数用于安装USB HOST,其函数原型如下:
  1. esp_err_t usb_host_install(const usb_host_config_t *config);
复制代码
函数形参:

1.png
表47.3.1.1 usb_host_install函数形参描述

返回值:
ESP_OK表示USB Host安装成功。
ESP_ERR_INVALID_ARG表示参数无效。
ESP_ERR_INVALID_STATE表示USB Host Library当前状态不正确。
ESP_ERR_NO_MEM表示内存不足。
config为指向USB Host Library 的配置结构体。接下来,笔者将详细介绍usb_host_config_t结构体中的各个成员变量,如下代码所示:
  1. /**
  2. * @brief USB Host Library 配置
  3. *
  4. * USB Host Library 的配置结构体,提供给 usb_host_install() 函数使用。
  5. */
  6. typedef struct {
  7.     bool skip_phy_setup;                   /* 如果设置true,USB Hos将不会配置USB PHY */
  8.     bool root_port_unpowered;  /* 如果设置为true,USB Host在安装时不会为根端口供电 */
  9.     int intr_flags;                          /* USB Host 栈底层中断的标志配置 */
  10.     usb_host_enum_filter_cb_t enum_filter_cb;   /* 枚举过滤器回调函数 */
  11. } usb_host_config_t;
复制代码
上述结构体用于传递USB Host Library配置参数,以下对各个成员做简单介绍。
1)skip_phy_setup:
若此字段设置为true,则不会配置USB PHY。
2)root_port_unpowered:
若此字段设置为true,则不会为USB HOST提供电源。
3)intr_flags:
USB Host 栈底层中断的标志配置,一般设置为0。
4)enum_filter_cb:
过滤回调函数。
2,安装USB主机大容量存储类(MSC)驱动 msc_host_install
该函数用于安装USB主机大容量存储类(MSC)驱动,其函数原型如下:
  1. esp_err_t msc_host_install(const msc_host_driver_config_t *config);
复制代码
函数形参:


2.png
表47.3.1.2 msc_host_install函数形参描述

返回值:
ESP_OK表示安装存储类(MSC)驱动安装成功。
其他表示安装存储类(MSC)驱动失败
config为指向MSC(大容量存储类)配置结构体。接下来,笔者将详细介绍msc_host_driver_config_t结构体中的各个成员变量,如下代码所示:
  1. /**
  2. * @brief MSC(大容量存储类)配置结构体
  3. */
  4. typedef struct {
  5.     /*  如果设置为 true,则会创建一个后台任务来处理 USB 事件;
  6.     否则用户需要定期调用 msc_host_handle_events 函数来处理事件。 */
  7.     bool create_backround_task;
  8.     size_t task_priority;           /*  创建的后台任务的优先级 */
  9.     size_t stack_size;              /*  创建的后台任务的堆栈大小 */
  10.     BaseType_t core_id;             /*  选择后台任务运行的核心 ID */
  11.     msc_host_event_cb_t callback;   /*  当发生 MSC 事件时调用的回调函数,不能为空 */
  12.     void *callback_arg;             /*  用户提供的参数,将传递给回调函数 */
  13. } msc_host_driver_config_t;
复制代码
msc_host_driver_config_t结构体用于传递MSC(大容量存储类)配置参数,以便在调用msc_host_install时进行初始化和设置。
3,处理 USB 主机库事件 usb_host_lib_handle_events
该函数用于处理 USB 主机库事件,其函数原型如下:
  1. esp_err_t usb_host_lib_handle_events(TickType_t timeout_ticks,
  2. uint32_t *event_flags_ret);
复制代码
函数形参:


3.png
表47.3.1.3 msc_host_install函数形参描述

返回值:
ESP_OK表示无事件需要处理。
ESP_ERR_INVALID_STATE表示USB主机库尚未安装。
ESP_ERR_TIMEOUT表示等待事件的信号量超时。
4,释放所有设备usb_host_device_free_all
该函数用于释放所有设备,其函数原型如下:
  1. esp_err_t usb_host_device_free_all(void);
复制代码
函数形参:
无。
返回值:
ESP_OK表示所有设备已被释放(即没有设备需要释放)
ESP_ERR_INVALID_STATE表示客户端必须先注销
ESP_ERR_NOT_FINISHED表示仍有一个或多个设备需要释放,请等待USB_HOST_LIB_EVENT_FLAGS_ALL_FREE事件。
5,卸载USB主机库usb_host_uninstall
该函数用于卸载USB主机库,其函数原型如下:
  1. esp_err_t usb_host_uninstall(void);
复制代码
函数形参:
无。
返回值:
ESP_OK表示USB主机库成功卸载。
ESP_ERR_INVALID_STATE表示USB主机库未安装,或存在未完成的操作。
6,初始化 MSC 设备msc_host_install_device
该函数用于处理 USB 主机库事件,其函数原型如下:
  1. esp_err_t msc_host_install_device( uint8_t device_address,
  2. msc_host_device_handle_t *device);
复制代码
函数形参:


4.png
表47.3.1.4 msc_host_install_device函数形参描述

返回值:
ESP_OK表示初始化成功。
其他错误码表示初始化失败。
7,将MSC设备注册到虚拟文件系统msc_host_vfs_register
该函数用于将MSC设备注册到虚拟文件系统,其函数原型如下:

  1. esp_err_t msc_host_vfs_register(msc_host_device_handle_t device,
  2.                                 const char *base_path,
  3.                                 const esp_vfs_fat_mount_config_t *mount_config,
  4.                                 msc_host_vfs_handle_t *vfs_handle);
复制代码
函数形参:

5.png
表47.3.1.5 msc_host_vfs_register函数形参描述

返回值:
ESP_OK表示注册成功。
其他错误码表示注册失败。
8,获取MSC设备信息msc_host_get_device_info
该函数用于将MSC设备注册到虚拟文件系统,其函数原型如下:

  1. esp_err_t msc_host_get_device_info(msc_host_device_handle_t device,
  2. msc_host_device_info_t *info);
复制代码
函数形参:

6.png
表47.3.1.6 msc_host_get_device_info函数形参描述

返回值:
ESP_OK表示成功获取设备信息。
其他错误码表示获取失败。
9,从虚拟文件系统中注销MSC设备msc_host_vfs_unregister
该函数用于从虚拟文件系统中注销MSC设备,其函数原型如下:
  1. esp_err_t msc_host_vfs_unregister(msc_host_vfs_handle_t vfs_handle);
复制代码
函数形参:

7.png
表47.3.1.7 msc_host_get_device_info函数形参描述

返回值:
ESP_OK表示成功获取设备信息。
其他错误码表示获取失败。
10,卸载MSC设备msc_host_uninstall_device
该函数用于卸载MSC设备,其函数原型如下:
  1. esp_err_t msc_host_uninstall_device(msc_host_device_handle_t device);
复制代码
函数形参:

8.png
表47.3.1.8 msc_host_uninstall_device函数形参描述

返回值:
ESP_OK表示成功卸载设备。
其他错误码表示卸载失败。

47.3.2 程序流程图
第四十七章 USB U盘实验5598.png
图47.3.2.1 U盘实验程序流程图

47.3.3 程序解析
本章节的例程是基于13_lcd实验编写的,所以笔者重点讲解有区别的文件。
1,USB HID MSC驱动
这里我们只讲解核心代码,详细的源码请大家参考光盘本实验对应源码。USB HID MSC驱动源码包括两个文件:usb_hid_msc.c和usb_hid_msc.h。
usb_hid_msc.h主要用于声明usb_hid_msc_init函数和USB消息结构体,以便在其他文件中调用,具体内容不再赘述。
下面我们再解析usb_hid_msc.c的程序,看一下初始化函数usb_hid_msc_init,代码如下:
  1. QueueHandle_t usb_queue = NULL;                /* 消息队列 */

  2. /**
  3. * @brief             MSC设备回调(连接/断开)
  4. * [url=home.php?mod=space&uid=271674]@param[/url]             event:MSC事件
  5. * @param             arg:传入参数
  6. * @retval           无
  7. */
  8. static void msc_event_cb(const msc_host_event_t *event, void *arg)
  9. {
  10.     /* 连接? */
  11.     if (event->event == MSC_DEVICE_CONNECTED)
  12.     {
  13.         /* 发现usb host 已插入U盘 */
  14.         usb_message_t message = {
  15.             .id = USB_DEVICE_CONNECTED,
  16.             .data.new_dev_address = event->device.address,
  17.         };
  18.         xQueueSend(usb_queue, &message, portMAX_DELAY);
  19.     }/* 断开? */
  20.     else if (event->event == MSC_DEVICE_DISCONNECTED)
  21.     {
  22.         /* 发现usb host 未检测到U盘 */
  23.         usb_message_t message = {
  24.             .id = USB_DEVICE_DISCONNECTED,
  25.         };
  26.         xQueueSend(usb_queue, &message, portMAX_DELAY);
  27.     }
  28. }

  29. /**
  30. * @brief             USB轮询任务
  31. * @param              args:未使用
  32. * @retval           无
  33. */
  34. static void usb_task_fun(void *args)
  35. {
  36.     /* usb host配置*/
  37.     const usb_host_config_t host_config = {.intr_flags = ESP_INTR_FLAG_LEVEL1 };
  38.     /* usb host初始化 */
  39.     ESP_ERROR_CHECK(usb_host_install(&host_config));
  40.     /* msc host设备配置 */
  41.     const msc_host_driver_config_t msc_config = {
  42.         .create_backround_task = true,  /* 创建回调任务 */
  43.         .task_priority = 5,             /* 任务优先级 */
  44.         .stack_size = 4096,             /* 任务堆栈大小 */
  45.         .callback = msc_event_cb,       /* msc事件回调函数 */
  46.     };
  47.     /* msc host安装 */
  48.     ESP_ERROR_CHECK(msc_host_install(&msc_config));

  49.     bool has_clients = true;

  50.     while (1)
  51.     {
  52.         uint32_t event_flags;
  53.         /* 处理USB事件处理器 */
  54.         usb_host_lib_handle_events(portMAX_DELAY, &event_flags);
  55.         /* 所有的客户端已从主机注销了吗? */
  56.         if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS)
  57.         {
  58.             has_clients = false;
  59.             /* 释放usb host内存 */
  60.             if (usb_host_device_free_all() == ESP_OK)
  61.             {
  62.                 break;
  63.             };
  64.         }
  65.         /* 主机已释放所有设备? */
  66.         if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE && !has_clients)
  67.         {
  68.             break;
  69.         }
  70.     }

  71.     vTaskDelay(pdMS_TO_TICKS(10));
  72.     /* 注销usb host */
  73.     ESP_ERROR_CHECK(usb_host_uninstall());
  74.     /* 删除usb轮询任务 */
  75.     vTaskDelete(NULL);
  76. }

  77. /**
  78. * @brief             USB读取U盘初始化
  79. * @param             无
  80. * @retval            ESP_OK:初始化成功
  81. */
  82. esp_err_t usb_hid_msc_init(void)
  83. {
  84.     /* 创建新的消息队列 */
  85.     usb_queue = xQueueCreate(5, sizeof(usb_message_t));
  86.     assert(usb_queue);

  87.     BaseType_t usb_task = xTaskCreate(usb_task_fun,"usb_task",4096,NULL,2,NULL);
  88.     assert(usb_task);

  89.     return ESP_OK;
  90. }
复制代码
以上代码实现了基于ESP32-P4的USB主机功能,专注于管理USB存储设备的连接与断开,并通过消息队列将设备状态变化通知其他任务。核心任务usb_task_fun负责USB主机的初始化、事件轮询和资源释放,确保整个系统的稳定运行。回调函数msc_event_cb处理存储设备的连接和断开事件,usb_hid_msc_init则提供了一个简单的初始化入口,整合了消息队列和任务创建,便于扩展和调用。
2,main.c驱动代码
在main.c里面编写如下代码。

  1. /* REPL控制器命令 */
  2. const esp_console_cmd_t cmds[] = {
  3.     {
  4.         .command = "file",
  5.         .help = "file browsing",
  6.         .hint = NULL,
  7.         .func = &console_file_browsing,
  8.     },
  9.     {
  10.         .command = "read",
  11.         .help = "read PATH   .eg: read /usb:/README.MD",
  12.         .hint = NULL,
  13.         .func = &console_read,
  14.     },
  15.     {
  16.         .command = "write",
  17.         .help = "write PATH Data   .eg: write /usb:/README.MD Hello ALIENTEK",
  18.         .hint = NULL,
  19.         .func = &console_write,
  20.     },
  21.     {
  22.         .command = "info",
  23.         .help = "Usb flash drive information",
  24.         .hint = NULL,
  25.         .func = &console_info,
  26.     },
  27.     {
  28.         .command = "speed",
  29.         .help = "Test read/write speed,eg: speed /usb:/README.MD",
  30.         .hint = NULL,
  31.         .func = &console_test_speed,
  32.     },
  33.     {
  34.         .command = "device_cfg",
  35.         .help = "Device configuration information",
  36.         .hint = NULL,
  37.         .func = &console_device_cfg,
  38.     },
  39. };

  40. /**
  41. * @brief            递归列出目录下的所有文件和文件夹
  42. * @param           path 需要列出的目录路径
  43. * @param             depth 当前目录层级
  44. * @retval             无
  45. */
  46. static void list_files(const char *path, int depth)
  47. {
  48.     /* 省略代码...... */
  49. }

  50. /**
  51. * @brief             测试读写速度
  52. * @param              argc:传入参数的数量
  53. * @param             argv:传入参数
  54. * @retval            -1:取消挂载失败。0:取消挂载成功
  55. */
  56. static int console_test_speed(int argc, char **argv)
  57. {
  58.     /* 省略代码...... */
  59.     return 0;
  60. }

  61. /**
  62. * @brief            文件浏览
  63. * @param             argc:传入参数的数量
  64. * @param              argv:传入参数
  65. * @retval           -1:读取失败。0:读取成功
  66. */
  67. static int console_file_browsing(int argc, char **argv)
  68. {
  69.     /* 省略代码...... */
  70.     return 0;
  71. }

  72. /**
  73. * @brief             读取存储设备的文件
  74. * @param             argc:传入参数的数量
  75. * @param             argv:传入参数
  76. * @retval            -1:读取失败。0:读取成功
  77. */
  78. static int console_read(int argc, char **argv)
  79. {
  80.     /* 省略代码...... */
  81.     return 0;
  82. }

  83. /**
  84. * @brief             写入存储设备的文件
  85. * @param             argc:传入参数的数量
  86. * @param             argv:传入参数
  87. * @retval            -1:读取失败。0:读取成功
  88. */
  89. static int console_write(int argc, char **argv)
  90. {
  91.     /* 省略代码...... */
  92.     return 0;
  93. }

  94. /**
  95. * @brief             获取U盘信息
  96. * @param             argc:传入参数的数量
  97. * @param             argv:传入参数
  98. * @retval             -1:读取失败。0:读取成功
  99. */
  100. static int console_info(int argc, char **argv)
  101. {
  102.     /* 省略代码...... */
  103.     return 0;
  104. }

  105. /**
  106. * @brief              获取MSC配置信息
  107. * @param              argc:传入参数的数量
  108. * @param              argv:传入参数
  109. * @retval            -1:读取失败。0:读取成功
  110. */
  111. static int console_device_cfg(int argc, char **argv)
  112. {
  113.     /* 省略代码...... */
  114.     return 0;
  115. }

  116. void app_main(void)
  117. {
  118.     esp_err_t ret;
  119.     uint8_t repl_state = 0xAA;

  120.     ret = nvs_flash_init();          /* 初始化NVS */

  121.     if(ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
  122.     {
  123.         ESP_ERROR_CHECK(nvs_flash_erase());
  124.         ESP_ERROR_CHECK(nvs_flash_init());
  125.     }

  126.     led_init();                         /* LED初始化 */
  127.     lcd_init();                         /* LCD初始化 */
  128.     usb_hid_msc_init();                 /* USB MSC HOST初始化 */

  129.     /* 实验信息 */
  130.     lcd_show_string(30, 50, 200, 16, 16, "ESP32-P4", RED);
  131.     lcd_show_string(30, 70, 200, 16, 16, "USB disk TEST", RED);
  132.     lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
  133.     lcd_show_string(30, 110, 200, 16, 16, "status:disconnect", RED);
  134.     lcd_show_string(30, 130, 200, 16, 16, "Total:          MB", RED);

  135.     while (1)
  136.     {
  137.         /* 接收消息 */
  138.         xQueueReceive(usb_queue, &msg, portMAX_DELAY);

  139.         if (msg.id == USB_DEVICE_CONNECTED)
  140.         {
  141.             /* 检查到U盘,则安装设备 */
  142.             ESP_ERROR_CHECK(msc_host_install_device(msg.data.new_dev_address
  143. , &msc_device));
  144.             /* 使用文件系统挂载U盘 */
  145.             const esp_vfs_fat_mount_config_t mount_config = {
  146.                 .format_if_mount_failed = false,    /* 挂载子分区? */
  147.                 .max_files = 3,                     /* 打开文件最大数量 */
  148.                 .allocation_unit_size = 8192,       /* 扇区大小 */
  149.             };
  150.             /* 注册文件系统 */
  151.             ESP_ERROR_CHECK( msc_host_vfs_register(msc_device, MNT_PATH,
  152. &mount_config, &vfs_handle));

  153.             if (msg.id == USB_DEVICE_CONNECTED && repl_state == 0xAA)
  154.             {
  155.                 /* 交互监视器 */
  156.                 esp_console_repl_t *repl = NULL;
  157.                 /* 默认配置 */
  158.                 esp_console_repl_config_t repl_config =
  159. ESP_CONSOLE_REPL_CONFIG_DEFAULT();
  160.                 repl_config.prompt = CONFIG_IDF_TARGET ">"; /* 提示符名称 */
  161. /* 命令行的最大长度。如果为0,则使用默认值 */
  162.                 repl_config.max_cmdline_length = 64;        
  163.                 esp_console_register_help_command();        /* 帮助命令 */
  164.                 /* 交互监视器使用串口那个通道输出 */
  165.                 esp_console_dev_uart_config_t hw_config =
  166. ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
  167.                 /* 新建REPL控制器 */
  168.                 ESP_ERROR_CHECK(esp_console_new_repl_uart(&hw_config,
  169. &repl_config, &repl));

  170.                 for (int count = 0; count < sizeof(cmds)
  171. / sizeof(esp_console_cmd_t); count++)
  172.                 {
  173.                     /* 添加命令 */
  174.                     ESP_ERROR_CHECK(esp_console_cmd_register(&cmds[count]));
  175.                 }
  176.                 /* 开始REPL控制器 */
  177.                 ESP_ERROR_CHECK(esp_console_start_repl(repl));
  178.                 repl_state = 0x00;
  179.             }

  180.             /* 获取磁盘信息 */
  181.             msc_host_device_info_t info;
  182.             ESP_ERROR_CHECK(msc_host_get_device_info(msc_device, &info));
  183.             uint64_t capacity = ((uint64_t)info.sector_size * info.sector_count)
  184. / (1024 * 1024);
  185.             lcd_show_string(84, 110, 200, 16, 16, "connected.", BLUE);
  186.             lcd_show_num(80, 130, capacity, 5, 16, BLUE);
  187.         }
  188.         if ((msg.id == USB_DEVICE_DISCONNECTED))
  189.         {
  190.             lcd_show_string(84, 110, 200, 16, 16, "disconnect", BLUE);
  191.             if (vfs_handle)
  192.             {
  193.                 ESP_ERROR_CHECK(msc_host_vfs_unregister(vfs_handle));
  194.                 vfs_handle = NULL;
  195.             }
  196.             if (msc_device)
  197.             {
  198.                 ESP_ERROR_CHECK(msc_host_uninstall_device(msc_device));
  199.                 msc_device = NULL;
  200.             }
  201.         }
  202.     }
  203. }
复制代码
上述代码实现了基于ESP32-P4的USB闪存驱动和REPL控制器功能,包含多个控制命令和功能模块。主要功能包括目录浏览、文件读写、USB设备信息获取、读写速度测试以及设备配置打印等。通过定义一系列控制命令(如file、read、write等)和递归函数list_files,支持对USB设备的文件系统操作。并且可实时检测U盘是否处于连接状态。

47.4 下载验证
在代码编译成功之后,我们可以在开发板上的HOST口插入U盘,此时LCD提示U盘连接成功,我们可通过终端来操作U盘中的文件,这些操作命令如下:

第四十七章 USB U盘实验14777.png
图47.4.1 REPL终端命令

从上图可以看到,若我们在终端输入 “file”命令,则终端会列出U盘中的所有文件目录,操作过程如下图所示。

第四十七章 USB U盘实验14850.png
图47.4.2 查询U盘文件目录

当然,我们也可以通过程序的方式添加自定义的操作命令,添加过程请参考本章节的实验。
回复

使用道具 举报

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

本版积分规则


关闭

原子哥极力推荐上一条 /1 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2026-2-13 12:59

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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