山东神华网站建设北京、广州最新发布
本专栏由非官方人员 王小小海 所著,其内容主要记录了在开发NCS的过程中遇到的一些问题和解决方法,还有一些应用的例程。作者本人也是在实践应用中遇到的问题,想着把这些问题分享给可能遇到的朋友。仅仅做个人技术交流分享,不做任何商业用途。如有不对之处,请留言,本人及时更改。
本专栏不涉及基础的安装和环境搭建问题,本例程开发使用NCS 2.9.0开发,还请注意!。
所有分享内容
笔记分享
- 【笔记分享】NCS下radio_test添加FEM
- 【笔记分享】5340基于 BLE LBS 自定义网络核固件点亮LED并合并固件
- 【笔记分享】5340基于LBS自定义网络核双核DFU实现
- 【笔记分享】5340 设置public address 和 random address
- 【笔记分享】NCS nRF52/53 添加LVGL组件驱动屏幕
- 【笔记分享】VirtualBox Ubuntu22.04 不能使用nrfjprog问题记录
- 【笔记分享】5340使用内部负载电容调频偏
- 【笔记分享】基于 LE Audio 例程移植到nRF52840上运行思路
- 【nRF52/53】【笔记分享】基于 BLE LBS DFU使用内部外部Flash 升级
- 【nRF54H20】基础介绍与使用介绍
- 【笔记分享】nRF54H20 SPI速率范围记录
应用分享
暂无
前言
在使用 nRF5340 LE Audio的时候需要记录音频数据,这时候我们可以使用 SPI Nor Flash 或者 SD卡,当然最性价比高的当然是使用SD卡,那么这次我们主要分享如何在NCS上使能SPI SD卡,并且挂载SD卡进行读写。
操作步骤
-
首先我们任意创建一个工程。这里我使用的 BLE的 LBS工程,当然不管是什么工程,方法都是一样的。
-
添加一个设备树,app.overlay (这是最快的,当然可以建立 boards 文件夹然后建立对应板子的.overlay文件)
-
在pj.conf文件中添加 文件系统和 DISK 驱动。
- 编写驱动,测试对应SD卡注册状态。这里我们创建一个 sd_card.c文件里面 包含了 初始化SD卡、查询卡的大小、文件系统的打开、读写、关闭功能。并将此文件添加到CMakeLists.txt中。
具体代码
设备树
需要根据具体SPI修改对应设备树
&pinctrl {spi4_default: spi4_default {group1 {psels = <NRF_PSEL(SPIM_SCK, 0, 8)>,<NRF_PSEL(SPIM_MOSI, 0, 9)>;/* 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, 10)>;};};spi4_sleep: spi4_sleep {group1 {psels = <NRF_PSEL(SPIM_SCK, 0, 8)>,<NRF_PSEL(SPIM_MISO, 0, 10)>,<NRF_PSEL(SPIM_MOSI, 0, 9)>;low-power-enable;};};
};&spi4 {compatible = "nordic,nrf-spim";status = "okay";cs-gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;pinctrl-0 = <&spi4_default>;pinctrl-1 = <&spi4_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 = <32000000>;};
};
pj.conf文件
# Enable SDHC interface
CONFIG_DISK_DRIVERS=yCONFIG_FILE_SYSTEM=y
CONFIG_FAT_FILESYSTEM_ELM=y
CONFIG_FS_FATFS_LFN=y
SD卡测试代码
/** Copyright (c) 2018 Nordic Semiconductor ASA** SPDX-License-Identifier: LicenseRef-Nordic-5-Clause*/#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/storage/disk_access.h>
#include <zephyr/fs/fs.h>
#include <ff.h>
#include <string.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/devicetree.h>
#include <string.h>#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(sd_card);#define SD_ROOT_PATH "/SD:/"
/* Round down to closest 4-byte boundary */
#define PATH_MAX_LEN ROUND_DOWN(CONFIG_FS_FATFS_MAX_LFN, 4)static const char *sd_root_path = "/SD:";
static FATFS fat_fs;
static bool sd_init_success;static struct fs_mount_t mnt_pt = {.type = FS_FATFS,.fs_data = &fat_fs,
};int sd_card_open(char const *const filename, struct fs_file_t *f_seg_read_entry)
{int ret;char abs_path_name[PATH_MAX_LEN + 1] = SD_ROOT_PATH;size_t available_path_space = PATH_MAX_LEN - strlen(SD_ROOT_PATH);if (!sd_init_success){return -ENODEV;}if (strlen(filename) > CONFIG_FS_FATFS_MAX_LFN){LOG_ERR("Filename is too long");return -ENAMETOOLONG;}if ((strlen(abs_path_name) + strlen(filename)) > PATH_MAX_LEN){LOG_ERR("Filepath is too long");return -EINVAL;}strncat(abs_path_name, filename, available_path_space);LOG_INF("abs path name:\t%s", abs_path_name);fs_file_t_init(f_seg_read_entry);ret = fs_open(f_seg_read_entry, abs_path_name, FS_O_READ);if (ret){LOG_ERR("Open file failed: %d", ret);return ret;}return 0;
}int sd_card_read(char *buf, size_t *size, struct fs_file_t *f_seg_read_entry)
{int ret;ret = fs_read(f_seg_read_entry, buf, *size);if (ret < 0){LOG_ERR("Read file failed. Ret: %d", ret);return ret;}*size = ret;return 0;
}int sd_card_close(struct fs_file_t *f_seg_read_entry)
{int ret;ret = fs_close(f_seg_read_entry);if (ret){LOG_ERR("Close file failed: %d", ret);return ret;}return 0;
}int sd_card_init(void)
{int ret;static const char *sd_dev = "SD";uint64_t sd_card_size_bytes;uint32_t sector_count;size_t sector_size;ret = disk_access_init(sd_dev);if (ret){LOG_DBG("SD card init failed, please check if SD card inserted");return -ENODEV;}ret = disk_access_ioctl(sd_dev, DISK_IOCTL_GET_SECTOR_COUNT, §or_count);if (ret){LOG_ERR("Unable to get sector count");return ret;}LOG_DBG("Sector count: %d", sector_count);ret = disk_access_ioctl(sd_dev, DISK_IOCTL_GET_SECTOR_SIZE, §or_size);if (ret){LOG_ERR("Unable to get sector size");return ret;}LOG_DBG("Sector size: %d bytes", sector_size);sd_card_size_bytes = (uint64_t)sector_count * sector_size;LOG_INF("SD card volume size: %lld B", sd_card_size_bytes);mnt_pt.mnt_point = sd_root_path;ret = fs_mount(&mnt_pt);if (ret){LOG_ERR("Mnt. disk failed, could be format issue. should be FAT/exFAT");return ret;}sd_init_success = true;return 0;
}
结束语
好的,本次分享基本上就是这些。
有不明白的地方欢迎提问,也厚脸皮要个赞或者关注,谢谢各位啦。
如果有哪位朋友需要定制方案,也可以联系私信我。感谢大家的浏览。
本系列文章大多数是本人遇到和解决过的问题,难有疏忽之处,有什么问题或者不明白的地方,欢迎留言询问!