【笔记分享】NCS/Zephyr USB MSC实现方法介绍

本专栏由非官方人员 王小小海 所著,其内容主要记录了在开发NCS的过程中遇到的一些问题和解决方法,还有一些应用的例程。作者本人也是在实践应用中遇到的问题,想着把这些问题分享给可能遇到的朋友。仅仅做个人技术交流分享,不做任何商业用途。如有不对之处,请留言,本人及时更改。

本专栏不涉及基础的安装和环境搭建问题,本例程开发使用NCS 2.9.0开发,还请注意!。


所有分享内容

笔记分享

  1. 【笔记分享】NCS下radio_test添加FEM
  2. 【笔记分享】5340基于 BLE LBS 自定义网络核固件点亮LED并合并固件
  3. 【笔记分享】5340基于LBS自定义网络核双核DFU实现
  4. 【笔记分享】5340 设置public address 和 random address
  5. 【笔记分享】NCS nRF52/53 添加LVGL组件驱动屏幕
  6. 【笔记分享】VirtualBox Ubuntu22.04 不能使用nrfjprog问题记录
  7. 【笔记分享】5340使用内部负载电容调频偏
  8. 【笔记分享】基于 LE Audio 例程移植到nRF52840上运行思路
  9. 【nRF52/53】【笔记分享】基于 BLE LBS DFU使用内部外部Flash 升级
  10. 【nRF54H20】基础介绍与使用介绍
  11. 【笔记分享】nRF54H20 SPI速率范围记录
  12. 【笔记分享】NCS/Zephyr 使能SPI SD卡方法介绍

应用分享

暂无


前言

根据前面的文章,分享了如何实现 SPI SD卡的驱动,能够正常读写 SD卡了,那么怎么将SD卡里面的数据拷贝出来呢?当然 可以 选择 nRF52840 / nRF5340 / nRF54H20 系列。这样大大提高了SD卡拷贝的速度。


操作步骤

首先在上篇文章的基础上,选择 nRF52840 / nRF5340 系列的板子(nRF54H20 稍稍不同),文章会介绍。

nRF52/nRF53
  1. 首先打开pj.conf文件,添加USB协议栈和USB MSC组件。我用的nRF53,nRF52也是一样的。
  1. 在软件中添加 USB 使能函数。
nRF54H20
  1. 步骤其实和上面的一样,只不过是宏不一样,还有就是USB使能的函数不一样。

  2. 由于之前的工程是使用的nRF52和nRF53,app.overlay需要更改为 spi13x,不能用spi12x,具体原因需要请看【笔记分享】nRF54H20 SPI速率范围记录 介绍。

  3. 编译成功没有错误,下载运行即可。


具体代码

pj.conf

复制代码
#
# Copyright (c) 2018 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#
CONFIG_NCS_SAMPLES_DEFAULTS=y

CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="Nordic_LBS"

# Enable the LBS service
CONFIG_BT_LBS=y
CONFIG_BT_LBS_POLL_BUTTON=y
CONFIG_DK_LIBRARY=y

CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048


# Enable SDHC interface
CONFIG_DISK_DRIVERS=y

CONFIG_FILE_SYSTEM=y
CONFIG_FAT_FILESYSTEM_ELM=y
CONFIG_FS_FATFS_LFN=y


# nRF52/nRF53 USB MSC 支持
# CONFIG_USB_DEVICE_STACK=y
# CONFIG_USB_DEVICE_PRODUCT="Zephyr MSC sample"
# CONFIG_USB_DEVICE_PID=0x0008

# CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
# CONFIG_USB_MASS_STORAGE=y
# CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y
# CONFIG_USB_MASS_STORAGE_LOG_LEVEL_ERR=y
# CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n

# nRF54h20 USB MSC 支持
CONFIG_USB_DEVICE_STACK_NEXT=y
CONFIG_USBD_MSC_CLASS=y
CONFIG_USBD_MSC_LUNS_PER_INSTANCE=1
CONFIG_USBD_LOG_LEVEL_WRN=y
CONFIG_UDC_DRIVER_LOG_LEVEL_WRN=y

CONFIG_USBD_MSG_SLAB_COUNT=20 
## 大一点传输速度快一点
CONFIG_USBD_MAX_UDC_MSG=20      

USB操作的函数

复制代码
#if defined(CONFIG_USB_DEVICE_STACK_NEXT)
static struct usbd_context *sample_usbd;

#if CONFIG_DISK_DRIVER_SDMMC
USBD_DEFINE_MSC_LUN(sd, "SD", "Zephyr", "SD", "0.00");
#endif

static int enable_usb_device_next(void)
{
	int err;

	sample_usbd = sample_usbd_init_device(NULL);
	if (sample_usbd == NULL) {
		LOG_ERR("Failed to initialize USB device");
		return -ENODEV;
	}

	err = usbd_enable(sample_usbd);
	if (err) {
		LOG_ERR("Failed to enable device support");
		return err;
	}

	LOG_DBG("USB device support enabled");

	return 0;
}
#endif /* defined(CONFIG_USB_DEVICE_STACK_NEXT) */


int usb_msc_init(void)
{
    int ret;

    ret = sd_card_init();
    if (ret < 0)
    {
        LOG_ERR("SD card init failed: %d", ret);
        return ret;
    }

#if defined(CONFIG_USB_DEVICE_STACK_NEXT)
	ret = enable_usb_device_next();
#else
	ret = usb_enable(NULL);
#endif
	if (ret != 0) {
		LOG_ERR("Failed to enable USB");
		return 0;
	}

	LOG_INF("The device is put in USB mass storage mode.\n");

    return 0;
}

nRF54H20 SPI SD 设备树

复制代码
&pinctrl {

	spi131_default: spi131_default {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 0)>,
				<NRF_PSEL(SPIM_MOSI, 0, 3)>;
			/* Workaround for issue with PCA10121 v0.7.0
			 * related to SD-card
			 */
			nordic,drive-mode = <NRF_DRIVE_H0H1>;
		};
		group2 {
			psels = <NRF_PSEL(SPIM_MISO, 0, 4)>;
		};
	};

	spi131_sleep: spi131_sleep {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 0)>,
				<NRF_PSEL(SPIM_MISO, 0, 3)>,
				<NRF_PSEL(SPIM_MOSI, 0, 4)>;
			low-power-enable;
		};
	};
};

&spi131 {
	compatible = "nordic,nrf-spim";
	status = "okay";
	cs-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
	pinctrl-0 = <&spi131_default>;
	pinctrl-1 = <&spi131_sleep>;
	pinctrl-names = "default", "sleep";
	sdhc0: sdhc@0 {
		compatible = "zephyr,sdhc-spi-slot";
		reg = <0>;
		status = "okay";
		sdmmc {
			compatible = "zephyr,sdmmc-disk";
			status = "okay";
		};

		spi-max-frequency = <8000000>;
	};
};

结束语

好的,本次分享基本上就是这些。

有不明白的地方欢迎提问,也厚脸皮要个赞或者关注,谢谢各位啦。

如果有哪位朋友需要定制方案,也可以联系私信我。感谢大家的浏览。


本系列文章大多数是本人遇到和解决过的问题,难有疏忽之处,有什么问题或者不明白的地方,欢迎留言询问!

相关推荐
熬夜造bug1 小时前
LeetCode Hot100 刷题笔记(4)—— 二叉树、图论
笔记·算法·leetcode
FreakStudio1 小时前
一文速通 Python 并行计算:05 Python 多线程编程-线程的定时运行
单片机·嵌入式·多线程·面向对象·并行计算·电子diy
乌恩大侠2 小时前
笔记:基于环境语义的通感融合技术,将传统通信由“被动接收”转为“主动感知”
笔记
sealaugh322 小时前
aws(学习笔记第三十六课) apigw-http-api-lambda-dynamodb
笔记·学习·aws
*TQK*2 小时前
CSS学习笔记5——渐变属性+盒子模型阶段案例
css·笔记·学习
魑魅魍魉都是鬼3 小时前
音视频 一 看书的笔记 基础视频知识
笔记·音视频
慵懒学者3 小时前
16 Junit单元测试框架、反射、注解、动态代理(黑马Java视频笔记)
java·笔记·junit·单元测试
promising-w4 小时前
【keil】单步调试
stm32·单片机·嵌入式硬件
Q186000000004 小时前
springboot 四层架构之间的关系整理笔记二
spring boot·笔记·架构
andylauren5 小时前
STM32 MODBUS-RTU主从站库移植
stm32·单片机·嵌入式硬件