RT-Thread 学习笔记(六)--- 开启基于SPI Flash的elmfat文件系统(上)

软件环境:Win7,Keil MDK 4.72a, IAR EWARM 7.2, GCC 4.2,Python 2.7 ,SCons 2.3.2

硬件环境:Armfly STM32F103ZE-EK v3.0开发板

参考文章:RT-Thread编程指南

[RTthread]新版本RTT中的SPI驱动框架

Github托管的Realtouch分支中examples目录中spi flash的例程

在RT-Thread默认的是SD卡作为文件系统挂载,需要加入相关驱动文件,操作如下:

【1】加入SPI总线驱动

在stm32f107分支的driver目录下有platform.c 平台初始化文件、rt_stm32f10x_spi.c和rt_stm32f10x_spi.h两个spi总线驱动文件,把它们复制到stm32f103ze-ek分支的driver中,并将platform.c重命名成rt_spi_flash_device.c结果如下:

RT-Thread 学习笔记(六)--- 开启基于SPI Flash的elmfat文件系统(上)_第1张图片

【2】加入SPI Flash设备驱动

在RT-Thread 官方的Git 托管库中有开源项目realtouch-stm32,在driver目录下面有SPI Flash驱动文件spi_flash_w25xx.c和spi_flash_w25xx.h两个文件,把它们复制到stm32f103ze-ek分支的driver中,结果如下:

RT-Thread 学习笔记(六)--- 开启基于SPI Flash的elmfat文件系统(上)_第2张图片

这样我们就在stm32f103ze-ek分支中加入SPI Flash相关驱动。

【3】将SPI Flash文件加入项目中

打开KeilMDK,在左侧的项目管理树中点开driver分支,然后按下图所示单击右键点击"Add Existing Fils to..."按钮。

RT-Thread 学习笔记(六)--- 开启基于SPI Flash的elmfat文件系统(上)_第3张图片

定位stm32f103ze-ek/drive目录,将上面刚刚复制的文件选中,如下图:

RT-Thread 学习笔记(六)--- 开启基于SPI Flash的elmfat文件系统(上)_第4张图片

然后点击"Add"按钮,完成添加,点击“close”按钮关闭对话框。

用同样的办法在rt-thread-1.2.2\components\drivers\spi目录中找到spi_core.c,spi_dev.c两个文件加入到工程的DeviceDrivers组中,结果如下:

RT-Thread 学习笔记(六)--- 开启基于SPI Flash的elmfat文件系统(上)_第5张图片

【4】打开rtconfig.h配置文件,开启文件DFS系统支持选项,定位到83行附近,修改如下:

/* SECTION: device filesystem */

#define RT_USING_SPI

#define RT_USING_SPI_FLASH
#define RT_USING_DFS
#define RT_USING_DFS_ELMFAT
#define RT_DFS_ELM_WORD_ACCESS

/* Reentrancy (thread safe) of the FatFs module.  */
#define RT_DFS_ELM_REENTRANT
/* Number of volumes (logical drives) to be used. */
#define RT_DFS_ELM_DRIVES 2
/* #define RT_DFS_ELM_USE_LFN 1 */
/* #define RT_DFS_ELM_CODE_PAGE 936 */
#define RT_DFS_ELM_MAX_LFN 255
/* Maximum sector size to be handled. */
#define RT_DFS_ELM_MAX_SECTOR_SIZE  4096  /*SPI Flash Sector size*/
/* the max number of mounted filesystem */
#define DFS_FILESYSTEMS_MAX 2
/* the max number of opened files  */
#define DFS_FD_MAX

修改完成后保存。

【5】修改application.c

打开application.c,定位到45行附近,加入如下代码:

extern void rt_spi_flash_device_init(void);


打开application.c,定位到101行附近,加入如下代码:

rt_spi_flash_device_init();

#ifdef  RT_USING_FINSH
    finsh_set_device(RT_CONSOLE_DEVICE_NAME);
#endif  /* RT_USING_FINSH */
    /* Filesystem Initialization */
#if defined(RT_USING_DFS) && defined(RT_USING_DFS_ELMFAT)
     /* mount SPI flash as root directory */ 
    if (dfs_mount("flash0", "/", "elm", 0, 0) == 0)
    {
        rt_kprintf("flash0 mount to /.\n");
    }
    else
        rt_kprintf("flash0 mount to / failed.\n");

#endif  /* RT_USING_DFS */

... ...

#ifdef RT_USING_RTGUI
{
extern void rt_hw_lcd_init();
extern void rtgui_touch_hw_init(void);

rt_device_t lcd;

/* init lcd */
rt_hw_lcd_init();

#ifdef RTGUI_USING_TOUCHPANEL
/* initilize touch panel */
rtgui_touch_hw_init("spi12");
#endif /* RTGUI_USING_TOUCHPANEL */

/* find lcd device */
lcd = rt_device_find("lcd");

/* set lcd device as rtgui graphic driver */
rtgui_graphic_set_device(lcd);

#ifndef RT_USING_COMPONENTS_INIT
/* init rtgui system server */
rtgui_system_server_init();
#endif /*RT_USING_COMPONENTS_INIT*/

#ifdef RTGUI_USING_CALIBRATION
calibration_set_restore(cali_setup);
calibration_set_after(cali_store);
calibration_init();
#endif /* #ifdef RTGUI_USING_CALIBRATION */

}
#endif /* RT_USING_RTGUI */


#ifdef RT_USING_USB_HOST
/* register stm32 usb host controller driver */
rt_hw_susb_init();
#endif

rt_thread_delay(50);
rt_device_init_all();

}

... ...

修改完成后保存。

【6】打开rt_spi_flash_device.c,看到有关spi底层初始化代码,这时对照开发板原理图,可以看到STM32F103ZE-EK开发板上使用的是SPI Flash芯片型号是SST25VF016B,和CPU连接引脚的原理图如下:

RT-Thread 学习笔记(六)--- 开启基于SPI Flash的elmfat文件系统(上)_第6张图片
可以看出,原理图上的SPI Flash用到的引脚分别是PA6(MISO),PA7(MOSI),PA5(SCK),其片选信号是PB2引脚,同样还使用SPI1总线的是LCD液晶的触摸屏芯片XTP2046,片选信号是PG11,如下图:

RT-Thread 学习笔记(六)--- 开启基于SPI Flash的elmfat文件系统(上)_第7张图片

因此我们在修改代码时也需要将其指定为SPI1,在rt_spi_flash_device.c中修改成如下代码:


#ifdef RT_USING_SPI
#include "rt_stm32f10x_spi.h"
#include "spi_flash_w25qxx.h"
#endif  /* RT_USING_SPI */

/*
 * SPI1_MOSI: PA7
 * SPI1_MISO: PA6
 * SPI1_SCK : PA5
 *
 * SPI Flash CE: PB2 
 * Touch Panel CS: PG11 

*/

#ifdef RT_USING_SPI
static void rt_hw_spi_init(void)
{
    /* register spi bus */
    {
        static struct stm32_spi_bus stm32_spi;
        GPIO_InitTypeDef GPIO_InitStructure;
        /* Enable GPIO clock */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE);
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        stm32_spi_register(SPI1, &stm32_spi, "spi1");
    }
    /* attach spi flash cs */

#ifdef RT_USING_SPI_FLASH
    {
        static struct rt_spi_device spi_device;
        static struct stm32_spi_cs  spi_cs;
        GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        /* spi11: PB2 */
        spi_cs.GPIOx = GPIOB;
        spi_cs.GPIO_Pin = GPIO_Pin_2;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
        GPIO_InitStructure.GPIO_Pin = spi_cs.GPIO_Pin;
        GPIO_SetBits(spi_cs.GPIOx, spi_cs.GPIO_Pin);
        GPIO_Init(spi_cs.GPIOx, &GPIO_InitStructure);
        rt_spi_bus_attach_device(&spi_device, "spi11", "spi1",(void*)&spi_cs);
    }

#endif /* RT_USING_SPI_FLASH */
#ifdef RTGUI_USING_TOUCHPANEL

/* attach touch panel cs */
    {
        static struct rt_spi_device spi_device;
        static struct stm32_spi_cs  spi_cs;
        GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        /* spi21: PG11 */
        spi_cs.GPIOx = GPIOG;
        spi_cs.GPIO_Pin = GPIO_Pin_11;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);
        GPIO_InitStructure.GPIO_Pin = spi_cs.GPIO_Pin;
        GPIO_SetBits(spi_cs.GPIOx, spi_cs.GPIO_Pin);
        GPIO_Init(spi_cs.GPIOx, &GPIO_InitStructure);
        rt_spi_bus_attach_device(&spi_device, "spi12", "spi1", (void*)&spi_cs);
    }

#endif /* RTGUI_USING_TOUCHPANEL */
}
#endif /* RT_USING_SPI */

void rt_spi_flash_device_init(void)
{
#if defined(RT_USING_DFS) && defined(RT_USING_DFS_ELMFAT) 
    w25qxx_init("flash0", "spi11");
#endif /* RT_USING_DFS && RT_USING_DFS_ELMFAT */

}

修改完毕后保存,如果一切顺利,应该编译能够通过,将在下篇文章中研究关于组件初始化问题。


你可能感兴趣的:(RT-Thread 学习笔记(六)--- 开启基于SPI Flash的elmfat文件系统(上))