- SD_Error SD_Init(){
- return __SD_Init(0, 3, 1);
- }
3. 实现tos_hal_sd的接口函数
腾讯TinyOS的Fatfs组件里会调用tos_hal_sd层级的函数,避免直接调用芯片级的hal函数,实现多种芯片的软件兼容。所以我们需要为国民N32G457编写对应的文件。
hardware/chip/nationstech/tos_hal/tos_hal_sd.c(文件路径)
- #include "tos_k.h"
- #include "tos_hal.h"
- #include "sdio_tf.h"
- __API__ int tos_hal_sd_init(hal_sd_t *sd)
- {
- (void)sd;
- return SD_Init() == SD_OK ? 0 : -1;
- }
- __API__ int tos_hal_sd_read(hal_sd_t *sd, uint8_t *buf, uint32_t blk_addr, uint32_t blk_num, uint32_t timeout)
- {
- uint8_t err;
- (void)sd;
- if (!buf) {
- return -1;
- }
- err = SD_ReadDisk(buf, blk_addr, blk_num);
- err = SD_WaitWriteOperation();
- return err == SD_OK ? 0 : -1;
- }
- __API__ int tos_hal_sd_write(hal_sd_t *sd, const uint8_t *buf, uint32_t blk_addr, uint32_t blk_num, uint32_t timeout)
- {
- uint8_t err;
- (void)sd;
- if (!buf) {
- return -1;
- }
- err = SD_WriteDisk((uint8_t *)buf, blk_addr, blk_num);
- err = SD_WaitWriteOperation();
- return err == SD_OK ? 0 : -1;
- }
- __API__ int tos_hal_sd_read_dma(hal_sd_t *sd, uint8_t *buf, uint32_t blk_addr, uint32_t blk_num)
- {
- return -1;
- }
- __API__ int tos_hal_sd_write_dma(hal_sd_t *sd, const uint8_t *buf, uint32_t blk_addr, uint32_t blk_num)
- {
- return -1;
- }
- __API__ int tos_hal_sd_erase(hal_sd_t *sd, uint32_t blk_add_start, uint32_t blk_addr_end)
- {
- return 0;
- }
- __API__ int tos_hal_sd_info_get(hal_sd_t *sd, hal_sd_info_t *info)
- {
- SD_Error err;
- SD_CardInfo card_info;
- (void)sd;
- if (!sd || !info) {
- return -1;
- }
- err = SD_GetCardInfo(&card_info);
- if (err != SD_OK) {
- return -1;
- }
- info->card_type = card_info.CardType;
- info->blk_num = card_info.CardCapacity / card_info.CardBlockSize;
- info->blk_size = card_info.CardBlockSize;
- return 0;
- }
- __API__ int tos_hal_sd_state_get(hal_sd_t *sd, hal_sd_state_t *state)
- {
- int ret = 0;
- SDCardState sd_state;
- (void)sd;
- if (!sd || !state) {
- return -1;
- }
- sd_state = SD_GetState();
- switch (sd_state) {
- case SD_CARD_READY:
- *state = HAL_SD_STAT_READY;
- break;
- case SD_CARD_SENDING:
- *state = HAL_SD_STAT_PROGRAMMING;
- break;
- case SD_CARD_RECEIVING:
- *state = HAL_SD_STAT_RECEIVING;
- break;
- case SD_CARD_TRANSFER:
- *state = HAL_SD_STAT_TRANSFER;
- break;
- case SD_CARD_ERROR:
- *state = HAL_SD_STAT_ERROR;
- break;
- default:
- ret = -1;
- break;
- }
- return ret;
- }
- __API__ int tos_hal_sd_deinit(hal_sd_t *sd)
- {
- (void)sd;
- return 0;
- }
4. 将对应文件添加到GN构建配置文件中
添加了新的c源文件,我们需要把对应的文件添加到GN构建配置文件中,每个组件的根目录下都有一个BUILD.gn配置文件。该文件定义了组件包含的文件,组件编译选项(若需要添加),组件依赖等等内容。
由于腾讯TinyOS并没有实现完整的系统级hal层函数,这个tos_hal_sd.c文件就暂时放在厂商芯片代码目录中(hardware/chip/nationstech/),我们在配置文件的最后添加这个文件的配置。
- source_set("n32g457_sdk") {
- sources = [
- "Peripheral/misc.c",
- "Peripheral/n32g45x_adc.c",
- "Peripheral/n32g45x_bkp.c",
- "Peripheral/n32g45x_can.c",
- "Peripheral/n32g45x_comp.c",
- "Peripheral/n32g45x_crc.c",
- "Peripheral/n32g45x_dbg.c",
- "Peripheral/n32g45x_dma.c",
- "Peripheral/n32g45x_dvp.c",
- "Peripheral/n32g45x_eth.c",
- "Peripheral/n32g45x_exti.c",
- "Peripheral/n32g45x_flash.c",
- "Peripheral/n32g45x_gpio.c",
- "Peripheral/n32g45x_i2c.c",
- "Peripheral/n32g45x_iwdg.c",
- "Peripheral/n32g45x_opamp.c",
- "Peripheral/n32g45x_pwr.c",
- "Peripheral/n32g45x_qspi.c",
- "Peripheral/n32g45x_rcc.c",
- "Peripheral/n32g45x_rtc.c",
- "Peripheral/n32g45x_sdio.c",
- "Peripheral/n32g45x_spi.c",
- "Peripheral/n32g45x_tim.c",
- "Peripheral/n32g45x_usart.c",
- "Peripheral/n32g45x_wwdg.c",
- ]
- sources += [
- "USBFS/usb_core.c",
- "USBFS/usb_init.c",
- "USBFS/usb_int.c",
- "USBFS/usb_mem.c",
- "USBFS/usb_regs.c",
- "USBFS/usb_sil.c",
- ]
- sources += [
- "sdio_tf.c",
- "system_n32g45x.c",
- ]
- sources += [ "../tos_hal/tos_hal_sd.c" ]
- }
适配完毕后,编译源码,默认配置下,TinyOS的fatfs还是比较大的体积的。通过psize命令,可以看到fs/fatfs组件体积又182.3K这么大,如此大的体积,是不符合BootLoader的需求的。
5. 检查代码是否可以读写tf卡
通过修改hardware/board/n32g45xvl_STB/main.c文件,我们尝试初始化SD卡和擦写部分扇区(直接调用SD_WriteBlock函数)
- /*****************************************************************************
- * Copyright (c) 2019, Nations Technologies Inc.
- *
- * All rights reserved.
- * ****************************************************************************
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the disclaimer below.
- *
- * Nations' name may not be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * ****************************************************************************/
- /**
- * [url=home.php?mod=space&uid=288409]@file[/url] main.c
- * [url=home.php?mod=space&uid=187600]@author[/url] Nations
- * [url=home.php?mod=space&uid=895143]@version[/url] v1.0.0
- *
- * [url=home.php?mod=space&uid=17282]@CopyRight[/url] Copyright (c) 2019, Nations Technologies Inc. All rights reserved.
- */
- #include "main.h"
- #include "n32g45x.h"
- #include "sdio_tf.h"
- #include "stdint.h"
- #include "stdio.h"
- #include "tos_k.h"
- #define USARTx USART1
- #define USARTx_GPIO GPIOA
- #define USARTx_CLK RCC_APB2_PERIPH_USART1
- #define USARTx_GPIO_CLK RCC_APB2_PERIPH_GPIOA
- #define USARTx_RxPin GPIO_PIN_10
- #define USARTx_TxPin GPIO_PIN_9
- #define GPIO_APBxClkCmd RCC_EnableAPB2PeriphClk
- #define USART_APBxClkCmd RCC_EnableAPB2PeriphClk
- #ifdef __GNUC__
- /* With GCC, small printf (option LD Linker->Libraries->Small printf
- set to 'Yes') calls __io_putchar() */
- #define PUTCHAR_PROTOTYPE int __io_putchar(char ch)
- #define GETCHAR_PROTOTYPE int __io_getchar()
- #else
- #define PUTCHAR_PROTOTYPE int fputc(char ch)
- #define GETCHAR_PROTOTYPE int fgetc()
- #endif /* __GNUC__ */
- PUTCHAR_PROTOTYPE {
- if (ch == '\n') {
- while (USART_GetFlagStatus(USARTx, USART_FLAG_TXC) == RESET)
- ;
- USART_SendData(USARTx, '\r');
- }
- while (USART_GetFlagStatus(USARTx, USART_FLAG_TXC) == RESET)
- ;
- USART_SendData(USARTx, ch);
- return ch;
- }
- GETCHAR_PROTOTYPE {
- uint8_t ch = 0;
- ch = USART_ReceiveData(USARTx);
- return ch;
- }
- /** @addtogroup N32G45X_StdPeriph_Examples
- * @{
- */
- /** @addtogroup USART_Printf
- * @{
- */
- typedef enum { FAILED = 0, PASSED = !FAILED } TestStatus;
- #define countof(a) (sizeof(a) / sizeof(*(a)))
- USART_InitType USART_InitStructure;
- void RCC_Configuration(void);
- #define APPLICATION_TASK_STK_SIZE 1024
- k_task_t application_task;
- __aligned(4) uint8_t application_task_stk[APPLICATION_TASK_STK_SIZE];
- u8 buf[512];
- u8 Readbuf[512];
- /*********************************************************************
- * @fn show_sdcard_info
- *
- * [url=home.php?mod=space&uid=247401]@brief[/url] SD Card information.
- *
- * [url=home.php?mod=space&uid=266161]@return[/url] none
- */
- void show_sdcard_info(void) {
- printf("SD Card initialization success!\r\n");
- printf("*CardType is: %d\r\n", SDCardInfo.CardType);
- printf("*CardCapacity is: %lld\r\n",
- SDCardInfo.CardCapacity / (1024 * 1024));
- printf("*CardBlockSize is: %d\r\n", (int)SDCardInfo.CardBlockSize);
- printf("*RCA is: %d\r\n", SDCardInfo.RCA);
- printf("*Manufacture(MID) is: %d\r\n", SDCardInfo.SD_cid.ManufacturerID);
- printf("*OEM/Appli(OID) is: %d\r\n", SDCardInfo.SD_cid.OEM_AppliID);
- printf("*Product Name(PNM) is: %d\r\n", (int)SDCardInfo.SD_cid.ProdName1);
- printf("*Serial Number(PSN) is: %x\r\n",
- (unsigned int)SDCardInfo.SD_cid.ProdSN);
- printf("*Manu Date COde(MDT) is: %x\r\n", SDCardInfo.SD_cid.ManufactDate);
- printf("*Card SysSpecVersion is: %d\r\n", SDCardInfo.SD_csd.SysSpecVersion);
- printf("*Card MaxBusClkFrec is: %d\r\n", SDCardInfo.SD_csd.MaxBusClkFrec);
- printf("*Card MaxRdBlockLen is: %d\r\n", SDCardInfo.SD_csd.RdBlockLen);
- printf("*Card RdCurrent VDD is: %d -> %d\r\n",
- SDCardInfo.SD_csd.MaxRdCurrentVDDMin,
- SDCardInfo.SD_csd.MaxRdCurrentVDDMax);
- printf("*Card WrSpeedFact is: %d\r\n", SDCardInfo.SD_csd.WrSpeedFact);
- printf("*Card MaxWrBlockLen is: %d\r\n", SDCardInfo.SD_csd.MaxWrBlockLen);
- printf("*Card WrCurrent VDD is: %d -> %d\r\n",
- SDCardInfo.SD_csd.MaxWrCurrentVDDMin,
- SDCardInfo.SD_csd.MaxWrCurrentVDDMax);
- }
- SD_Error Status = SD_OK;
- void application_entry(void *arg) {
- u32 i;
- u32 Sector_Nums;
- while (SD_Init()) {
- printf("SD Card Error!\r\n");
- tos_task_delay(1000);
- }
- show_sdcard_info();
- printf("SD Card OK\r\n");
- Sector_Nums = ((u32)(SDCardInfo.CardCapacity >> 20)) / 2;
- printf("Sector_Nums:%d\r\n", Sector_Nums);
- for (i = 0; i < 512; i++) {
- buf[i] = i;
- }
- for (i = 0; i < 512; i++) {
- Status = SD_WriteBlock(buf, i, 1);
- Status = SD_WaitWriteOperation();
- while (SD_GetStatus() != SD_TRANSFER_OK)
- ;
- if (Status != SD_OK) {
- printf("SD Card write block failed!\r\n");
- }
- Status = SD_ReadBlock(Readbuf, i, 1);
- Status = SD_WaitReadOperation();
- while (SD_GetStatus() != SD_TRANSFER_OK)
- ;
- if (memcmp(buf, Readbuf, 512)) {
- printf(" %d sector Verify fail\n", i);
- break;
- }
- }
- if (i == Sector_Nums / 2) {
- printf("SD OK\r\n");
- }
- }
- /**
- * @brief Main program
- */
- int main(void) {
- /* System Clocks Configuration */
- RCC_Configuration();
- NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
- /* Configure the GPIO ports */
- GPIO_InitType GPIO_InitStructure;
- /* Configure USARTx Tx as alternate function push-pull */
- GPIO_InitStructure.Pin = USARTx_TxPin;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitPeripheral(USARTx_GPIO, &GPIO_InitStructure);
- /* Configure USARTx Rx as input floating */
- GPIO_InitStructure.Pin = USARTx_RxPin;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_InitPeripheral(USARTx_GPIO, &GPIO_InitStructure);
- /* USARTy and USARTz configuration
- * ------------------------------------------------------*/
- USART_InitStructure.BaudRate = 115200;
- USART_InitStructure.WordLength = USART_WL_8B;
- USART_InitStructure.StopBits = USART_STPB_1;
- USART_InitStructure.Parity = USART_PE_NO;
- USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
- USART_InitStructure.Mode = USART_MODE_RX | USART_MODE_TX;
- /* Configure USARTx */
- USART_Init(USARTx, &USART_InitStructure);
- /* Enable the USARTx */
- USART_Enable(USARTx, ENABLE);
- tos_knl_init(); // 初始化TencentOS tiny内核
- printf("TinyOS demo!\r\n");
- // 创建一个优先级为5的任务
- tos_task_create(&application_task, "task_prio5", application_entry, NULL, 4,
- application_task_stk, APPLICATION_TASK_STK_SIZE, 0);
- // 开始内核调度,线程中不允许有睡死代码。
- tos_knl_start();
- while (1) {
- }
- }
- /**
- * @brief Configures the different system clocks.
- */
- void RCC_Configuration(void) {
- /* Enable GPIO clock */
- GPIO_APBxClkCmd(USARTx_GPIO_CLK | RCC_APB2_PERIPH_AFIO, ENABLE);
- /* Enable USARTy and USARTz Clock */
- USART_APBxClkCmd(USARTx_CLK, ENABLE);
- }
烧录到开发板上,可以正确获取SD卡信息,并读写SD卡扇区。SDIO代码没问题。
四、fatfs编译优化注意事项
1. 回到上一个步骤的fatfs体积的问题,通过搜索引擎可以查到,我们可以调整FF_USE_LFN 宏定义的值,关闭长文件名的支持。以下为修改后的代码。
文件路径 components/fs/fatfs/wrapper/include/tos_ffconf.h (由于腾讯TinyOS改写了fatfs的源码,并重命名了ffconf.h文件,我们需要修改这个文件才能生效)。
- #define FF_USE_LFN 0
- #define FF_MAX_LFN 255
- /* The FF_USE_LFN switches the support for LFN (long file name).
- /
- / 0: Disable LFN. FF_MAX_LFN has no effect.
- / 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
- / 2: Enable LFN with dynamic working buffer on the STACK.
- / 3: Enable LFN with dynamic working buffer on the HEAP.
- /
- / To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
- / requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
- / additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
- / The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
- / be in range of 12 to 255. It is recommended to be set 255 to fully support LFN
- / specification.
- / When use stack for the working buffer, take care on stack overflow. When use heap
- / memory for the working buffer, memory management functions, ff_memalloc() and
- / ff_memfree() in ffsystem.c, need to be added to the project. */
执行mclean命令清空了编译产物后,重新执行mbuild和psize命令,可以看到fatfs的组件体积减小到了8.9K,体积减小了不少。
虽然整体体积34K的flash,对于16K的目标BootLoader大小来说还是相差比较大。目前就暂时不管他,先考虑完成IAP功能(SDIO功能占用体积极大,估计要换成SPI或者软SPI读写SD卡能降低不少体积)。
这里我们用TinyOS的VFS层代码进行测试,测试代码如下(同样是修改上文提到的main.c文件):
- /*****************************************************************************
- * Copyright (c) 2019, Nations Technologies Inc.
- *
- * All rights reserved.
- * ****************************************************************************
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the disclaimer below.
- *
- * Nations' name may not be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * ****************************************************************************/
- /**
- * @file main.c
- * @author Nations
- * @version v1.0.0
- *
- * @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved.
- */
- #include "main.h"
- #include "n32g45x.h"
- #include "sdio_tf.h"
- #include "stdint.h"
- #include "stdio.h"
- #include "tos_k.h"
- #define USARTx USART1
- #define USARTx_GPIO GPIOA
- #define USARTx_CLK RCC_APB2_PERIPH_USART1
- #define USARTx_GPIO_CLK RCC_APB2_PERIPH_GPIOA
- #define USARTx_RxPin GPIO_PIN_10
- #define USARTx_TxPin GPIO_PIN_9
- #define GPIO_APBxClkCmd RCC_EnableAPB2PeriphClk
- #define USART_APBxClkCmd RCC_EnableAPB2PeriphClk
- #ifdef __GNUC__
- /* With GCC, small printf (option LD Linker->Libraries->Small printf
- set to 'Yes') calls __io_putchar() */
- #define PUTCHAR_PROTOTYPE int __io_putchar(char ch)
- #define GETCHAR_PROTOTYPE int __io_getchar()
- #else
- #define PUTCHAR_PROTOTYPE int fputc(char ch)
- #define GETCHAR_PROTOTYPE int fgetc()
- #endif /* __GNUC__ */
- PUTCHAR_PROTOTYPE {
- if (ch == '\n') {
- while (USART_GetFlagStatus(USARTx, USART_FLAG_TXC) == RESET)
- ;
- USART_SendData(USARTx, '\r');
- }
- while (USART_GetFlagStatus(USARTx, USART_FLAG_TXC) == RESET)
- ;
- USART_SendData(USARTx, ch);
- return ch;
- }
- GETCHAR_PROTOTYPE {
- uint8_t ch = 0;
- ch = USART_ReceiveData(USARTx);
- return ch;
- }
- /** @addtogroup N32G45X_StdPeriph_Examples
- * @{
- */
- /** @addtogroup USART_Printf
- * @{
- */
- typedef enum { FAILED = 0, PASSED = !FAILED } TestStatus;
- #define countof(a) (sizeof(a) / sizeof(*(a)))
- USART_InitType USART_InitStructure;
- void RCC_Configuration(void);
- #define APPLICATION_TASK_STK_SIZE 1024
- k_task_t application_task;
- __aligned(4) uint8_t application_task_stk[APPLICATION_TASK_STK_SIZE];
- /*********************************************************************
- * @fn show_sdcard_info
- *
- * @brief SD Card information.
- *
- * @return none
- */
- void show_sdcard_info(void) {
- printf("SD Card initialization success!\r\n");
- printf("*CardType is: %d\r\n", SDCardInfo.CardType);
- printf("*CardCapacity is: %lld\r\n",
- SDCardInfo.CardCapacity / (1024 * 1024));
- printf("*CardBlockSize is: %d\r\n", (int)SDCardInfo.CardBlockSize);
- printf("*RCA is: %d\r\n", SDCardInfo.RCA);
- printf("*Manufacture(MID) is: %d\r\n", SDCardInfo.SD_cid.ManufacturerID);
- printf("*OEM/Appli(OID) is: %d\r\n", SDCardInfo.SD_cid.OEM_AppliID);
- printf("*Product Name(PNM) is: %d\r\n", (int)SDCardInfo.SD_cid.ProdName1);
- printf("*Serial Number(PSN) is: %x\r\n",
- (unsigned int)SDCardInfo.SD_cid.ProdSN);
- printf("*Manu Date COde(MDT) is: %x\r\n", SDCardInfo.SD_cid.ManufactDate);
- printf("*Card SysSpecVersion is: %d\r\n", SDCardInfo.SD_csd.SysSpecVersion);
- printf("*Card MaxBusClkFrec is: %d\r\n", SDCardInfo.SD_csd.MaxBusClkFrec);
- printf("*Card MaxRdBlockLen is: %d\r\n", SDCardInfo.SD_csd.RdBlockLen);
- printf("*Card RdCurrent VDD is: %d -> %d\r\n",
- SDCardInfo.SD_csd.MaxRdCurrentVDDMin,
- SDCardInfo.SD_csd.MaxRdCurrentVDDMax);
- printf("*Card WrSpeedFact is: %d\r\n", SDCardInfo.SD_csd.WrSpeedFact);
- printf("*Card MaxWrBlockLen is: %d\r\n", SDCardInfo.SD_csd.MaxWrBlockLen);
- printf("*Card WrCurrent VDD is: %d -> %d\r\n",
- SDCardInfo.SD_csd.MaxWrCurrentVDDMin,
- SDCardInfo.SD_csd.MaxWrCurrentVDDMax);
- }
- SD_Error Status = SD_OK;
- #include "ff.h"
- #include "tos_vfs.h"
- #include "tos_fatfs_drv.h"
- #include "tos_fatfs_vfs.h"
- char buf[512];
- void application_entry(void *arg) {
- int fd, ret;
- vfs_err_t err;
- extern vfs_blkdev_ops_t sd_dev;
- extern vfs_fs_ops_t fatfs_ops;
- err = tos_vfs_block_device_register("/dev/sd", &sd_dev);
- if (err != VFS_ERR_NONE) {
- printf("/dev/sd block device register failed!\n");
- }
- err = tos_vfs_fs_register("fatfs_sd", &fatfs_ops);
- if (err != VFS_ERR_NONE) {
- printf("fatfs_sd fs register failed!\n");
- }
- if (tos_vfs_fs_mkfs("/dev/sd", "fatfs_sd", FM_FAT32, 0) != 0) {
- printf("mkfs failed!\n");
- }
- if (tos_vfs_fs_mount("/dev/sd", "/fs/fatfs_sd", "fatfs_sd") != 0) {
- printf("mount failed!\n");
- }
- fd = tos_vfs_open("/fs/fatfs_sd/test_file.txt", VFS_OFLAG_CREATE_ALWAYS | VFS_OFLAG_WRITE);
- if (fd < 0) {
- printf("open failed!\n");
- }
- ret = tos_vfs_write(fd, "fatfs sample content", strlen("fatfs sample content"));
- if (ret >= 0) {
- printf("write ok\n");
- printf("write data:\n%s\n", "fatfs sample content");
- } else {
- printf("write error: %d\n", ret);
- }
- ret = tos_vfs_close(fd);
- if (ret < 0) {
- printf("close failed!\n");
- }
- fd = tos_vfs_open("/fs/fatfs_sd/test_file.txt", VFS_OFLAG_EXISTING | VFS_OFLAG_READ);
- if (fd < 0) {
- printf("open file error!\n");
- }
- memset(buf, 0, sizeof(buf));
- ret = tos_vfs_read(fd, buf, sizeof(buf));
- if (ret >= 0) {
- printf("read ok: %d\n", ret);
- printf("read data:\n%s\n", buf);
- } else {
- printf("read error: %d\n", ret);
- }
- ////////////////////////////////////////////////
- ret = tos_vfs_lseek(fd, 2, VFS_SEEK_CUR);
- if (ret < 0) {
- printf("lseek error\n");
- }
- memset(buf, 0, sizeof(buf));
- ret = tos_vfs_read(fd, buf, sizeof(buf));
- if (ret >= 0) {
- printf("read ok: %d\n", ret);
- printf("read data:\n%s\n", buf);
- } else {
- printf("read error: %d\n", ret);
- }
- /////////////////////////////////////////////////
- tos_vfs_close(fd);
- }
- /**
- * @brief Main program
- */
- int main(void) {
- /* System Clocks Configuration */
- RCC_Configuration();
- NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
- /* Configure the GPIO ports */
- GPIO_InitType GPIO_InitStructure;
- /* Configure USARTx Tx as alternate function push-pull */
- GPIO_InitStructure.Pin = USARTx_TxPin;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitPeripheral(USARTx_GPIO, &GPIO_InitStructure);
- /* Configure USARTx Rx as input floating */
- GPIO_InitStructure.Pin = USARTx_RxPin;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_InitPeripheral(USARTx_GPIO, &GPIO_InitStructure);
- /* USARTy and USARTz configuration
- * ------------------------------------------------------*/
- USART_InitStructure.BaudRate = 115200;
- USART_InitStructure.WordLength = USART_WL_8B;
- USART_InitStructure.StopBits = USART_STPB_1;
- USART_InitStructure.Parity = USART_PE_NO;
- USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
- USART_InitStructure.Mode = USART_MODE_RX | USART_MODE_TX;
- /* Configure USARTx */
- USART_Init(USARTx, &USART_InitStructure);
- /* Enable the USARTx */
- USART_Enable(USARTx, ENABLE);
- tos_knl_init(); // 初始化TencentOS tiny内核
- printf("TinyOS demo!\r\n");
- // 创建一个优先级为5的任务
- tos_task_create(&application_task, "task_prio5", application_entry, NULL, 4,
- application_task_stk, APPLICATION_TASK_STK_SIZE, 0);
- // 开始内核调度,线程中不允许有睡死代码。
- tos_knl_start();
- while (1) {
- }
- }
- /**
- * @brief Configures the different system clocks.
- */
- void RCC_Configuration(void) {
- /* Enable GPIO clock */
- GPIO_APBxClkCmd(USARTx_GPIO_CLK | RCC_APB2_PERIPH_AFIO, ENABLE);
- /* Enable USARTy and USARTz Clock */
- USART_APBxClkCmd(USARTx_CLK, ENABLE);
- }
编译代码后,烧录到板子上测试结果如下:
经过调试和阅读相关源码,暂时未找到为何设备注册错误。阅读原厂SDIO源码发现默认是启用了SDIO的DMA模式(似乎也可以通过宏定义不开启DMA模式,禁用后仍是出现上图的报错),但是由于时间仓储,未能继续再往下开发下去。
总结:通过本次活动,我学习到了N32G457的SDIO读写SD卡,以及腾讯TinyOS的相关移植知识。由于本人的能力不足,未能实现本次活动的目标,但也让我学到了不少知识。由于活动时间结束了,本次的分享只能分享部分经验,而不是完整的IAP功能,只能在4月抽空再完成对应功能,并在本帖跟进对应内容。本次活动的相关源码在https://gitee.com/walker2048/mcu_playground/tree/dev/可以获取到。