您尚未登录。

楼主 # 2022-01-05 12:37:16

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

[记录]f1c200s运行RT-thread

最近画了块f1c200s_ch579m的板子,尝试给200s跑RTT。
F1C100s-LCD-TV-CH579M 板子

涉及内容:
(1)基于RTThread的F1C100s开发(带boot启动+硬件多图层+硬件游标+LVGL+SDIO)
(2)Gitee-RT-Thread
(3)RT-Thread 下载
1、从上面链接下载资源,获取资源
(1)[rt-thread-gitee_master.zip]
(2)[allwinner_tina_prj_v1.zip]
(3)[env_released_1.2.0.zip]
2、安装ENV
(1)安装步骤,请观看视频:跳转到RTT官方视频页
3、解压资源
(1)解压 [rt-thread-gitee_master.zip] 到D盘根目录(当然也可以其他盘啦~笑~)
(2)解压 [allwinner_tina_prj_v1.zip] ,
      然后复制allwinner_tina_prj_v1  到  rt-thread-gitee_master\bsp目录下。
(有人问,为什么不用官方的allwinner_tina呢?因为官方的工程,不带bootloader,咱们为了方便,直接借助网友的工程。)
(3)在目录 D:\rt-thread-gitee_master\bsp\allwinner_tina_prj_v1,打开ENV。
(4)在ENV下,输入menuconfig。
(5)编译RTT,输入scons。
(6)得到未经修饰的rtthread.bin
(7)执行脚本文件,[flashtospi.bat],
这个脚本用于修饰rtthread.bin,增加魔术头,并下载bin文件到flash中。
(8)提示缺少120D.dll文件,咱们从网上复制一个这个文件进来,放在D:\rt-thread-gitee_master\bsp\allwinner_tina_prj_v1\tools目录下。
        继续执行第(7)步,修饰rtthread.bin成功。但是下载失败。
    板子接入USB,按住上面的BOOT键,按下RST键,然后松开RST,此时电脑识别到usb设备。
        继续执行第(7)步,程序下载成功。



bootloader分析笔记.md(右键另存为)
bootloader分析笔记.pdf(右键另存为)

最近编辑记录 LinjieGuo (2022-01-05 12:44:10)

离线

楼主 #1 2022-01-05 13:11:11

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

4、现象,接上串口0,看打印。
打印了一些乱七八糟的东西,可能是板子不匹配导致的。
(1)修改main.c文件,干掉一些东西,先让系统跑起来。

#include "rtthread.h"
#include "drv_clock.h"
#include "drv_gpio.h"
#include <rtdevice.h>
#include <dfs_fs.h>
#include <drv_sdio.h>
#include <drv_fb.h>
#include <stdio.h>

#include "UartCursor.h"
#include "LVGL_Interface.h"
#include "demo.h"
#include "AppPriorityList.h"


lcd_layer_Struct lcd_layer1={
	.width=100,
	.height=100,
	.posx=0,
	.posy=0,
	.priority=1,
	.pipe=1,
	.alpha_enable=1,
	.alpha_value=0xA0,
	.vram=(void *)0x80500000,
	.vram_format=VRAM_FORMAT_RGB565,	
};
lcd_layer_Struct lcd_layer2={
	.width=100,
	.height=100,
	.posx=50,
	.posy=50,
	.priority=2,
	.pipe=0,
	.alpha_enable=1,
	.alpha_value=0xA0,
	.vram=(void *)0x80600000,
	.vram_format=VRAM_FORMAT_RGB565,	
};


void start_thread(void *parameter)
{
	while(1)
	{
		rt_thread_delay(1);
	}	
}

#define RT_STARTLOOP_THREAD_STACK_SIZE 2048
#define MY_DISP_HOR_RES  LV_HOR_RES_MAX

static void MainThreadCreat()
{ 
	rt_thread_t tid;
	tid = rt_thread_create("start_thread", start_thread, RT_NULL,
					   RT_STARTLOOP_THREAD_STACK_SIZE, PRIORITY_START_LOOP, 20);
    RT_ASSERT(tid != RT_NULL);
    rt_thread_startup(tid);
	rt_kprintf("[Thread]start_thread Created.\n");
}


int main(int argc, char **argv)
{
	rt_kprintf("Start...\n");
	rt_kprintf("periph_get_pll_clk:%d\n", periph_get_pll_clk());
    rt_kprintf("cpu_get_clk:%d\n", cpu_get_clk());
    rt_kprintf("ahb_get_clk:%d\n", ahb_get_clk());
    rt_kprintf("apb_get_clk:%d\n", apb_get_clk());
	MainThreadCreat();
    return 0;
}

(2)编译,修饰,烧写。
    复位单板,启动,看起来较为正常了,但是还是有些问题。
rtt_boot_log.png

插上TF卡,还是这个样子,怀疑是板子引脚不匹配导致的。

最近编辑记录 LinjieGuo (2022-01-05 13:16:08)

离线

楼主 #2 2022-01-05 13:19:23

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

5、看看系统启动流程
    我们看看系统注册了什么组件、注册了什么驱动。启动的时候,做了什么事情。
    RTT借助宏INIT_EXPORT实现了自动初始化机制,我们找到这个宏的定义:
(参考帖子:[求助]RTT组件自动统一初始化宏INIT_EXPORT)
    自动初始化机制的核心就在文件D:\rt-thread-gitee_master\src\components.c
和D:\rt-thread-gitee_master\include\rtdef.h里面
因为代码篇幅过长,不做详细描述,咱们使能RTT内核调试宏,将初始化流程打印出来看看
(1)使能内核调试宏

#ifndef RT_DEBUG_INIT
#define RT_DEBUG_INIT                  1
#endif

(2)编译、修饰、烧写、查看启动日志
rtt_boot_log2.png
可以看到,启动的时候,执行了哪些组件的初始化。(BOARD/PREV/DEVICE/COMPONENT/ENV/APP)

打印日志上面2条红色的错误依然醒目,得看看是什么原因导致的。

最近编辑记录 LinjieGuo (2022-01-05 16:41:44)

离线

楼主 #3 2022-01-05 13:58:38

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

6、搜索相关内容
    通过搜索关键字:[E/[MMC]] [err]:0x00000100,  RTO
    找到相关帖子
(1)f1c100s 运行时提示错
    看来RTT论坛并不重视答疑,从2020年的帖子,到现在都没有解答。
(2)找不到相关内容~~~~难受!

离线

楼主 #4 2022-01-05 14:01:22

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

7、查看代码,看看能不能找到问题所在
        既然是一个成熟的系统,那么,十有八九,不是别人系统问题,只能是单板匹配问题。
        单板差异,那么驱动就有差异,E/MMC相关的是sdio,我们看看SDIO引脚配置是否匹配。
从源码里面看到,
SDIO 0所使用的引脚为:/* SDC0: PF0-PF5 */[[]],
SDIO 1没有使用,所以没有配置。

static void sdio_gpio_init(struct sdio_drv *sdio_des)
{
    int pin;

    if ((rt_uint32_t)sdio_des->mmc_des == MMC0_BASE_ADDR)
    {
        /* SDC0: PF0-PF5 */[[]]
        for (pin = GPIO_PIN_0; pin <= GPIO_PIN_5; pin++)
        {
            gpio_set_func(GPIO_PORT_F, pin, IO_FUN_1);
            gpio_set_pull_mode(GPIO_PORT_F, pin, PULL_UP);
            gpio_set_drive_level(GPIO_PORT_F, pin, DRV_LEVEL_2);
        }
    }
    else if ((rt_uint32_t)sdio_des->mmc_des == MMC1_BASE_ADDR)
    {
        //todo: config gpio port
        RT_ASSERT(0);
    }

}

对应我们的单板,SDIO0 使用的引脚情况是一致的。
找不到红色字的原因,只好先放下他。先看看其他东西怎么玩!

最近编辑记录 LinjieGuo (2022-01-05 15:39:10)

离线

楼主 #5 2022-01-05 16:26:44

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

8、访问tf/sd卡
(1)格式化sd卡,有3种方法
<方法1>使用msh命令行格式化:

msh />list_device
device           type         ref count
-------- -------------------- ----------
sd0      Block Device         0       
wind25qx Block Device         0       
spi10    SPI Device           0       
spi1     SPI Bus              0       
spi00    SPI Device           0       
spi0     SPI Bus              0       
uart2    Character Device     0       
uart0    Character Device     2       
msh />mkfs -t elm sd0
msh />

<方法2>程序里面格式化(参考官方文档:虚拟文件系统)
dfs_mkfs( "elm", "sd0");//其中elm是文件系统类型,sd0是块设备名称

<方法3>把tf卡拔出来,电脑格式化~~~笑~~

(2)挂载sd卡到根目录
    原本,我想把spi flash块设备挂载为/,然后sd卡挂接为/sdcard,
    奈何本人水平太差,不知道怎么分割spiflash的空间,一部分作为程序空间,一部分作为存储空间。(希望高手指教)
    所以,直接把sd卡挂接为/。
    几行代码搞定,把代码写在线程里:

void start_thread(void *parameter)
{
	int ret = 0;

	rt_thread_delay(100);
	/*挂载sdio0上的sd卡,文件系统类型为elm*/
	if( 0 == dfs_mount("sd0","/","elm", 0,0) )
	{
		printf("sd0 mount to / \n");
	}
	else
	{
		printf("sd0 mount to / faild \n");
	}
		
	
	while(1)
	{
		rt_thread_delay(1);
	}
}	

(3)使用msh给sd卡创建文件夹。
rtt_msh_dir.png

最近编辑记录 LinjieGuo (2022-01-05 16:36:49)

离线

#6 2022-01-05 17:12:18

jordonwu
会员
注册时间: 2021-07-05
已发帖子: 32
积分: 23

Re: [记录]f1c200s运行RT-thread

楼主高效! 这跑的是rt-smart?

离线

楼主 #7 2022-01-05 17:32:44

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

jordonwu 说:

楼主高效! 这跑的是rt-smart?

就是RT-Thread不是rt smart

离线

楼主 #8 2022-01-05 17:44:12

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

9、疑问,为什么上面挂接sd卡的代码要延时呢?
    因为不延时,挂接不成功啊!
为什么会这样呢?通过查看代码,其实是跟SDIO相关的。

int rt_mmcsd_core_init(void)
{
    rt_err_t ret;

    /* initialize detect SD cart thread */
    /* initialize mailbox and create detect SD card thread */
    ret = rt_mb_init(&mmcsd_detect_mb, "mmcsdmb",
        &mmcsd_detect_mb_pool[0], sizeof(mmcsd_detect_mb_pool) / sizeof(mmcsd_detect_mb_pool[0]),
        RT_IPC_FLAG_FIFO);
    RT_ASSERT(ret == RT_EOK);

   ret = rt_mb_init(&mmcsd_hotpluge_mb, "mmcsdhotplugmb",
        &mmcsd_hotpluge_mb_pool[0], sizeof(mmcsd_hotpluge_mb_pool) / sizeof(mmcsd_hotpluge_mb_pool[0]),
        RT_IPC_FLAG_FIFO);
    RT_ASSERT(ret == RT_EOK);
     ret = rt_thread_init(&mmcsd_detect_thread, "mmcsd_detect", mmcsd_detect, RT_NULL,
                 &mmcsd_stack[0], RT_MMCSD_STACK_SIZE, RT_MMCSD_THREAD_PREORITY, 20);
    if (ret == RT_EOK)
    {
        rt_thread_startup(&mmcsd_detect_thread);
    }

    rt_sdio_init();

    return 0;
}

rt_mmcsd_core_init()这个函数里面,创建了一个线程,这个线程里面负责SDIO接口的一些事情,
具体做什么事情还没搞懂,凭我的直觉,反正就是跟他有关系。~笑~

void mmcsd_detect(void *param)
{
    struct rt_mmcsd_host *host;
    rt_uint32_t  ocr;
    rt_int32_t  err;

    while (1)
    {
        if (rt_mb_recv(&mmcsd_detect_mb, (rt_ubase_t *)&host, RT_WAITING_FOREVER) == RT_EOK)
        {
            if (host->card == RT_NULL)
            {
                mmcsd_host_lock(host);
                mmcsd_power_up(host);
                mmcsd_go_idle(host);

                mmcsd_send_if_cond(host, host->valid_ocr);

                err = sdio_io_send_op_cond(host, 0, &ocr);
                if (!err)
                {
                    if (init_sdio(host, ocr))
                        mmcsd_power_off(host);
                    mmcsd_host_unlock(host);
                    continue;
                }

                /*
                 * detect SD card
                 */
                err = mmcsd_send_app_op_cond(host, 0, &ocr);
                if (!err)
                {
                    if (init_sd(host, ocr))
                        mmcsd_power_off(host);
                    mmcsd_host_unlock(host);
                    rt_mb_send(&mmcsd_hotpluge_mb, (rt_ubase_t)host);
                    continue;
                }

                /*
                 * detect mmc card
                 */
                err = mmc_send_op_cond(host, 0, &ocr);
                if (!err)
                {
                    if (init_mmc(host, ocr))
                        mmcsd_power_off(host);
                    mmcsd_host_unlock(host);
                    rt_mb_send(&mmcsd_hotpluge_mb, (rt_ubase_t)host);
                    continue;
                }
                mmcsd_host_unlock(host);
            }
            else
            {
                /* card removed */
                mmcsd_host_lock(host);
                if (host->card->sdio_function_num != 0)
                {
                    LOG_W("unsupport sdio card plug out!");
                }
                else
                {
                    rt_mmcsd_blk_remove(host->card);
                    rt_free(host->card);

                    host->card = RT_NULL;
                }
                mmcsd_host_unlock(host);
                rt_mb_send(&mmcsd_hotpluge_mb, (rt_ubase_t)host);
            }
        }
    }
}

最近编辑记录 LinjieGuo (2022-01-05 17:46:14)

离线

#9 2022-01-06 17:47:47

jhon
会员
注册时间: 2021-12-23
已发帖子: 1
积分: 1

Re: [记录]f1c200s运行RT-thread

rtthread studio 里面已经有f1c100s了 ,可以直接一键生成工程 效果一样

离线

楼主 #10 2022-01-06 18:53:23

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

jhon 说:

rtthread studio 里面已经有f1c100s了 ,可以直接一键生成工程 效果一样

哈哈,我对elipse不太爽,现在用source insight阅读代码的。而且好像也是不能使用调试器调试的。

最近编辑记录 LinjieGuo (2022-01-06 18:56:36)

离线

楼主 #11 2022-01-07 22:06:23

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

离线

楼主 #12 2022-01-08 14:53:10

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

@LinjieGuo
请教了RTT群里的大神,RTT是支持把SPI FLASH进行分区管理的。也就是说,可以把Flash分出2个区或者多个区,然后bin文件下载进分区0,分区1/2...就可以用来格式化了。
这得益于RTT的扩展包FAL--RTT-FAL支持
我们根据指导文件进行操作。
1.1、打开 FAL
使用 fal package 需要在 RT-Thread 的包管理器中选择它,具体路径如下:

RT-Thread online packages
    system packages --->
        --- fal: Flash Abstraction Layer implement. Manage flash device and partition.
        [*]   Enable debug log output
        [*]   FAL partition table config has defined on 'fal_cfg.h'
        (onchip) The flash device which saving partition table
        (65536) The patition table end address relative to flash device offset.
        [ ]   FAL uses SFUD drivers
        (norflash0) The name of the device used by FAL (NEW)
                version (latest)  --->

每个功能的配置说明如下:

(1)开启调试日志输出(默认开启);
(2)分区表是否在 fal_cfg.h 中定义(默认开启)。如果关闭此选项,fal 将会自动去指定 Flash 的指定位置去检索并装载分区表,
   具体配置详见下面两个选项;
          存放分区表的 Flash 设备;
          分区表的 结束地址 位于 Flash 设备上的偏移。
(3)启用 FAL 针对 SFUD 的移植文件(默认关闭);
       
然后让 RT-Thread 的包管理器自动更新,或者使用 pkgs --update 命令更新包到 BSP 中。

最近编辑记录 LinjieGuo (2022-01-08 15:41:31)

离线

楼主 #13 2022-01-08 14:56:01

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

上面是FAL的开启指引,咱们按照指引进行一顿操作!

--- fal: Flash Abstraction Layer implement. Manage flash device and partition.                                                           
[*]   Enable debug log output                                                                                                      
[*]   FAL partition table config has defined on 'fal_cfg.h'                         
[*]   FAL uses SFUD drivers                                                                                                                     
        (spi00) The name of the device used by FAL  
        version (v0.5.0)  --->

保存,然后使用命令,从menuconfig更新packge到工程中,packages目录里面有一些内容,
没有.c文件,不知道是不是有异常。

x@LAPTOP-BH56UJG6 E:\SVN_Public\rt_thread\bsp\allwinner_tina_prj_v1
$ pkgs --update

x@LAPTOP-BH56UJG6 E:\SVN_Public\rt_thread\bsp\allwinner_tina_prj_v1
$ ls -l packages\
total 7
-rw-r--r-- 1 meika Administrators  266 Jan  8 13:44 SConscript
-rw-r--r-- 1 meika Administrators 1288 Jan  8 14:27 fal_cfg.h
-rw-r--r-- 1 meika Administrators 2048 Jan  8 13:44 packages.dbsqlite
-rw-r--r-- 1 meika Administrators    2 Jan  8 13:44 pkgs.json
-rw-r--r-- 1 meika Administrators    2 Jan  8 14:59 pkgs_error.json

编译工程,按理说我没有实现指定的接口,应该会报错,但是结果是没有报错,跟之前一样。

最近编辑记录 LinjieGuo (2022-01-08 16:54:13)

离线

楼主 #14 2022-01-08 15:21:43

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

文档的后面还让我们参考这里FAL
说干就干
<1>定义片外 spi flash 设备,可以参考 fal_flash_sfud_port.c
    一会我把这个文件下载下来,捣鼓一下。
<2>定义 flash 设备表
    Flash 设备表定义在 fal_cfg.h 头文件中,定义分区表前需 新建 fal_cfg.h 文件 ,请将该文件统一放在对应 BSP 或工程目录的 port 文件夹下,并将该头文件路径加入到工程。
    fal_cfg.h 可以参考 示例文件 fal/samples/porting/fal_cfg.h 完成。
    一会这个文件我也下载下来,捣鼓捣鼓。

    好,这两个文件弄下来了(复制),那么放在哪里呢?

    想了一下,我编不下去了,source insight包含了整个工程(BSP只包含allwinner_tina_prj_v1,其他没有包含。)。
    好家伙,一个"fal"关键词的文件都没有。感觉是配置了跟没配置一样。

---- fal Matches (0 in 0 files) ----

fal_no_file.png

最近编辑记录 LinjieGuo (2022-01-08 16:54:43)

离线

楼主 #15 2022-01-08 20:10:24

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

回到家里,使用家里电脑,menuconfig之后,选择FAL,然后pkgs --update,成功把包更新到bsp。

Linjie@DESKTOP-NTLR93Q D:\SVN_Public\rt_thread\bsp\allwinner_tina_prj_v1
$ pkgs --update
Start to download package : fal-0.5.0.zip
Downloded 137 KB
Start to unpack. Please wait...
==============================>  FAL v0.5.0 is downloaded successfully.

Operation completed successfully.

Linjie@DESKTOP-NTLR93Q D:\SVN_Public\rt_thread\bsp\allwinner_tina_prj_v1

先看目录里有没有东西

Linjie@DESKTOP-NTLR93Q D:\SVN_Public\rt_thread\bsp\allwinner_tina_prj_v1
$ ls -l packages\
total 11
-rw-r--r-- 1 Linjie Administrators  266 Jan  8 20:00 SConscript
drwxr-xr-x 6 Linjie Administrators 4096 Jan  8 20:00 fal-v0.5.0
-rw-r--r-- 1 Linjie Administrators 4096 Jan  8 20:00 packages.dbsqlite
-rw-r--r-- 1 Linjie Administrators   86 Jan  8 20:00 pkgs.json
-rw-r--r-- 1 Linjie Administrators    2 Jan  8 20:00 pkgs_error.json

        可以看到,fal-v0.5.0已经被下载下来了。
        我们什么都不做,编译看看,因为我们没有实现某些接口,不出意外的话,会报错。
        编译完,果然,报错了。

CC build\libcpu\stack.o
CC build\libcpu\trap.o
CC build\packages\fal-v0.5.0\samples\porting\fal_flash_sfud_port.o
In file included from packages\fal-v0.5.0\samples\porting\fal_flash_sfud_port.c:25:0:
packages\fal-v0.5.0\inc/fal.h:29:21: fatal error: fal_cfg.h: No such file or directory
compilation terminated.
scons: *** [build\packages\fal-v0.5.0\samples\porting\fal_flash_sfud_port.o] Error 1
scons: building terminated because of errors.

最近编辑记录 LinjieGuo (2022-01-08 20:31:56)

离线

楼主 #16 2022-01-09 14:43:00

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

报错是意料之中,好,那我们就按照要求,修改一下fal相关的2个文件。
        [bsp/allwinner_tina_prj_v1/packages/fal-v0.5.0/packge/samples/porting/fal_cfg.h]
        [bsp/allwinner_tina_prj_v1/packages/fal-v0.5.0/packge/samples/porting/fal_flash_sfud_port.c]
        这两个文件修改后,我们将文件挪一下,
(1)h文件复制到[bsp\allwinner_tina_prj_v1\packages\fal-v0.5.0\inc\]目录下
(2)c文件复制到[bsp\allwinner_tina_prj_v1\packages\fal-v0.5.0\src\]目录下
(3)删除[bsp/allwinner_tina_prj_v1/packages/fal-v0.5.0/packge/samples/]这个目录
        (不要问我为什么要这样做,因为我不懂怎么改里面的SConscript脚本,干脆这样干了,~~笑~~)

离线

楼主 #17 2022-01-09 14:43:40

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

文件fal_cfg.h

/*
 * File      : fal_cfg.h
 * This file is part of FAL (Flash Abstraction Layer) package
 * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-05-17     armink       the first version
 */

#ifndef _FAL_CFG_H_
#define _FAL_CFG_H_

#include <rtconfig.h>
#include <board.h>

#define NOR_FLASH_DEV_NAME             "wind25qx"

/* ===================== Flash device Configuration ========================= */
extern struct fal_flash_dev nor_flash0;

/* flash device table */
#define FAL_FLASH_DEV_TABLE                                          \
{                                                                    \
    &nor_flash0,                                                     \
}
/* ====================== Partition Configuration ========================== */
#ifdef FAL_PART_HAS_TABLE_CFG
/* partition table */
#define FAL_PART_TABLE                                                               \
{                                                                                    \
    {FAL_PART_MAGIC_WORD, "sys_partition", NOR_FLASH_DEV_NAME,        	  0,  1*1024*1024, 0}, \
    {FAL_PART_MAGIC_WORD, "root_partition", NOR_FLASH_DEV_NAME, 1*1024*1024, 15*1024*1024, 0}, \
}
#endif /* FAL_PART_HAS_TABLE_CFG */

#endif /* _FAL_CFG_H_ */

        修改完之后,分区表情况是这样的:、
(1)分区0:
分区名字                 :sys_partition,系统分区
分区绑定的块设备      :NOR_FLASH_DEV_NAME
绑定的块设备起始地址:0
本分区的尺寸           :1*1024*1024,也就是1MB
(2)分区1:
分区名字                 :root_partition,根分区
分区绑定的块设备      :NOR_FLASH_DEV_NAME
绑定的块设备起始地址:1*1024*1024,也就是从1MB位置开始。
本分区的尺寸           :15*1024*1024,也就是15MB

最近编辑记录 LinjieGuo (2022-01-09 14:49:23)

离线

楼主 #18 2022-01-09 14:50:10

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

文件fal_flash_sfud_port.c

/*
 * File      : fal_flash_sfud_port.c
 * This file is part of FAL (Flash Abstraction Layer) package
 * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-01-26     armink       the first version
 */

#include <fal.h>
#include <sfud.h>

#ifdef FAL_USING_SFUD_PORT
#ifdef RT_USING_SFUD
#include <spi_flash_sfud.h>
#endif


#ifndef FAL_USING_NOR_FLASH_DEV_NAME
#define FAL_USING_NOR_FLASH_DEV_NAME             "wind25qx"
#endif

static int init(void);
static int read(long offset, uint8_t *buf, size_t size);
static int write(long offset, const uint8_t *buf, size_t size);
static int erase(long offset, size_t size);

static sfud_flash_t sfud_dev = NULL;
struct fal_flash_dev nor_flash0 =
{
    .name       = FAL_USING_NOR_FLASH_DEV_NAME,
    .addr       = 0,
    .len        = 16 * 1024 * 1024,
    .blk_size   = 4096,
    .ops        = {init, read, write, erase},
    .write_gran = 1
};

static int init(void)
{

#ifdef RT_USING_SFUD
    /* RT-Thread RTOS platform */
	
    sfud_dev = rt_sfud_flash_find_by_dev_name(FAL_USING_NOR_FLASH_DEV_NAME);
#else
    /* bare metal platform */
    extern sfud_flash sfud_norflash0;
    sfud_dev = &sfud_norflash0;
#endif

    if (NULL == sfud_dev)
    {
        return -1;
    }

    /* update the flash chip information */
    nor_flash0.blk_size = sfud_dev->chip.erase_gran;
    nor_flash0.len = sfud_dev->chip.capacity;

    return 0;
}

static int read(long offset, uint8_t *buf, size_t size)
{
    assert(sfud_dev);
    assert(sfud_dev->init_ok);
    sfud_read(sfud_dev, nor_flash0.addr + offset, size, buf);

    return size;
}

static int write(long offset, const uint8_t *buf, size_t size)
{
    assert(sfud_dev);
    assert(sfud_dev->init_ok);
    if (sfud_write(sfud_dev, nor_flash0.addr + offset, size, buf) != SFUD_SUCCESS)
    {
        return -1;
    }

    return size;
}

static int erase(long offset, size_t size)
{
    assert(sfud_dev);
    assert(sfud_dev->init_ok);
    if (sfud_erase(sfud_dev, nor_flash0.addr + offset, size) != SFUD_SUCCESS)
    {
        return -1;
    }

    return size;
}
#endif /* FAL_USING_SFUD_PORT */

离线

楼主 #19 2022-01-09 14:53:02

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

为什么fal_cfg.h的这个宏是这样定义呢?

#define NOR_FLASH_DEV_NAME             "wind25qx"

因为,SPI块设备注册进来的名字就是"wind25qx"。
在文件drv_spi_flash.c定义

#define SPI_FLASH_DEVICE_NAME       "spi00"
#define SPI_FLASH_CHIP              "wind25qx"

最近编辑记录 LinjieGuo (2022-01-09 14:55:46)

离线

楼主 #20 2022-01-09 15:01:46

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

scons,编译,编译成功。
跑起来,好像没有看到我们想要看的东西。
rtt_fal_boot.png
        哪里异常呢?
(1)打印出的initialize列表,没有找到fal相关的关键词
(2)输入fal命令,提示,还没有初始化

最近编辑记录 LinjieGuo (2022-01-09 15:03:03)

离线

楼主 #21 2022-01-09 15:04:20

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

也就是说,FAL根本就没有初始化。
        我们让他像elm组件一样,自动初始化。
在fal.c文件底部,加入一个宏修饰

INIT_PREV_EXPORT(fal_init);

        编译,修饰,下载,启动查看串口打印:
rtt_fal_boot_not_find_spi00.png

        一眼看过去,肯定不对劲,关键的红字信息。
initialize fal_init[E/SFUD] ERROR: Flash device spi00 not found!
       在初始化fal的时候,系统跟我们说,找不到spi00。
       咦?我们前面定义的宏,明明是:

#define NOR_FLASH_DEV_NAME             "wind25qx"

       他跟我们说,找不到spi00,那肯定有问题。
       我折腾了很久,发现了问题在menuconfig环节,我手欠的把这一项修改了。
rtt_fal_boot_not_find_spi00_menuconfig.png
       修改这一项为 wind25qx,保存,退出menuconfig,然后编译,修饰,烧写。
rtt_fal_boot_not_find_spi00_menuconfig_wind25qx.png

最近编辑记录 LinjieGuo (2022-01-09 15:14:35)

离线

楼主 #22 2022-01-09 15:16:39

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

果然,这条红色的错误提示,没有了。
initialize fal_init[E/SFUD] ERROR: Flash device spi00 not found!

rtt_fal_boot_not_find_no_red_error.png

最近编辑记录 LinjieGuo (2022-01-09 15:17:19)

离线

楼主 #23 2022-01-09 15:33:26

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

按照官方知道文档,测试一下--> 软件包-FAL
(1)查看有那些分区

msh />fal probe
No flash device or partition was probed.
Usage: fal probe [dev_name|part_name]   - probe flash device or partition by given name.
[I/FAL] ==================== FAL partition table ====================
[I/FAL] | name           | flash_dev |   offset   |    length  |
[I/FAL] -------------------------------------------------------------
[I/FAL] | sys_partition  | wind25qx  | 0x00000000 | 0x00100000 |
[I/FAL] | root_partition | wind25qx  | 0x00100000 | 0x00f00000 |
[I/FAL] =============================================================

(2)指定待操作的 Flash 设备或 Flash 分区
不能选择sys_partition  这个分区,因为这个分区存储了我们的系统程序,擦掉系统就没了。
所以我们选择 root_partition分区:

msh />fal probe root_partition
Probed a flash partition | root_partition | flash_dev: wind25qx | offset: 1048576 | len: 15728640 |.

(3)擦除数据

msh />fal erase 0 4096
Erase data success. Start from 0x00000000, size is 4096.

(4)写入数据

msh />fal write 8 1 2 3 4 5
Write data success. Start from 0x00000008, size is 5.
Write data: 1 2 3 4 5 .

(5)读取数据

msh />fal read 0 64
Read data success. Start from 0x00000000, size is 64. The data is:
Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
[00000000] FF FF FF FF FF FF FF FF 01 02 03 04 05 FF FF FF ................
[00000010] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
[00000020] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
[00000030] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................

(6)性能测试

msh />fal bench 4096 yes
Erasing 15728640 bytes data, waiting...
Erase benchmark success, total time: 36.614S.
Writing 15728640 bytes data, waiting...
Write benchmark success, total time: 61.441S.
Reading 15728640 bytes data, waiting...
Read benchmark success, total time: 4.267S.

离线

楼主 #24 2022-01-09 15:34:58

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

按照官方的流程走,看起来都成功了。
    但是!!!这都不是我们想要的。
    我们捋一下,我们的目的是:
FAL将Flash进行分区,然后,将这个分区注册成块设备,块设备就可以注册进DFS,被DFS虚拟文件系统管理了

最近编辑记录 LinjieGuo (2022-01-09 15:46:41)

离线

楼主 #25 2022-01-12 09:10:18

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

继续前进。
参考文章IOT-OS之RT-Thread(十一)--- FAL分区管理与easyflash变量管理
我们抄袭一下,跟他做法相仿,文件编排略有差异,只为了实现功能。
修改main.c文件,
(1)增加函数 bsp_fal_init()

#include "dfs_posix.h"

#define FS_PARTITION_NAME  "root_partition"

void bsp_fal_init(void)
{
	int fd, size;
    struct statfs elm_stat;
    struct fal_blk_device *blk_dev;
    char str[] = "elmfat mount to W25Q flash.", buf[80];

	/* fal init */
    fal_init();

	 /* create block device */
    blk_dev = (struct fal_blk_device *)fal_blk_device_create(FS_PARTITION_NAME);
    if(blk_dev == RT_NULL)
        rt_kprintf("Can't create a block device on '%s' partition.\n", FS_PARTITION_NAME);
    else
        rt_kprintf("Create a block device on the %s partition of flash successful.\n", FS_PARTITION_NAME);

	/* make a elmfat format filesystem */
    if(dfs_mkfs("elm", FS_PARTITION_NAME) == 0)
        rt_kprintf("make elmfat filesystem success.\n");

    /* mount elmfat file system to FS_PARTITION_NAME */
    if(dfs_mount(FS_PARTITION_NAME, "/", "elm", 0, 0) == 0)
        rt_kprintf("elmfat filesystem mount success.\n");
	
    /* Get elmfat file system statistics */
    if(statfs("/", &elm_stat) == 0)
        rt_kprintf("elmfat filesystem block size: %d, total blocks: %d, free blocks: %d.\n", 
                    elm_stat.f_bsize, elm_stat.f_blocks, elm_stat.f_bfree);

    if(mkdir("/user", 0x777) == 0)
        rt_kprintf("make a directory: '/user'.\n");

    rt_kprintf("Write string '%s' to /user/test.txt.\n", str);

    /* Open the file in create and read-write mode, create the file if it does not exist*/
    fd = open("/user/test.txt", O_WRONLY | O_CREAT);
    if (fd >= 0)
    {
        if(write(fd, str, sizeof(str)) == sizeof(str))
            rt_kprintf("Write data done.\n");

        close(fd);   
    }

    /* Open file in read-only mode */
    fd = open("/user/test.txt", O_RDONLY);
    if (fd >= 0)
    {
        size = read(fd, buf, sizeof(buf));

        close(fd);

        if(size == sizeof(str))
            rt_kprintf("Read data from file test.txt(size: %d): %s \n", size, buf);
    }
}

(2)修改main函数,显示调用bsp_fal_init()

int main(int argc, char **argv)
{
	
	rt_kprintf("Start...\n");
	rt_kprintf("periph_get_pll_clk:%d\n", periph_get_pll_clk());
    rt_kprintf("cpu_get_clk:%d\n", cpu_get_clk());
    rt_kprintf("ahb_get_clk:%d\n", ahb_get_clk());
    rt_kprintf("apb_get_clk:%d\n", apb_get_clk());

	bsp_fal_init();
	
	MainThreadCreat();
    return 0;
}

(3)修改start_task,关掉TF/SD卡挂载相关。

void start_thread(void *parameter)
{
	int ret = 0;
#if 0
	
	if( 0 == dfs_mount("sd0","/","elm", 0,0) )
	{
		printf("sd0 mount to / \n");
	}
	else
	{
		printf("sd0 mount to / faild \n");
	}
#endif		
	
	while(1)
	{
		rt_thread_delay(1);
	}	
}

(4)编译,修饰,烧写。

最近编辑记录 LinjieGuo (2022-01-12 09:15:22)

离线

楼主 #26 2022-01-12 09:19:44

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

开机,看一看
rtt_dfs_spi_nor.png
显然,虚拟文件系统挂载进去了。(红色字体是SD卡相关,没有插卡,所以报故障)
具体的 [分区创建块设备]  [块设备格式化为文件系统] [文件系统挂载到DFS] [创建目录] [创建文件] [写文件]
这些流程,看上面的代码,一目了然。不作过多描述。

最近编辑记录 LinjieGuo (2022-01-12 09:20:43)

离线

楼主 #27 2022-01-12 09:31:07

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

重启单板,咦?我们刚刚创建的whycan文件夹没了??
这一看,那一看,发现,每次开机,bsp_fal_init()函数都会做一遍格式化操作。
我们是不是可以这样:
(1)[分区创建块设备]
(2)尝试挂载块设备到文件系统
   如果成功,就不格式化了
   如果失败,则格式化完在挂载

说干就干!修改一下这个bsp_fal_init()函数:(关键代码)

__mount_fal:
	/* mount elmfat file system to FS_PARTITION_NAME */
    if(dfs_mount(FS_PARTITION_NAME, "/", "elm", 0, 0) == 0)
    {    
    	rt_kprintf("elmfat filesystem mount success.\n");
	}
	else
	{
		/* make a elmfat format filesystem */
   		 if(dfs_mkfs("elm", FS_PARTITION_NAME) == 0)
   		 {
       		 rt_kprintf("make elmfat filesystem success.\n");
			 goto __mount_fal;
   		 }
		 else
		 {
		 	rt_kprintf("make elmfat filesystem faild.\n");
		 	while(1);
		 }
	}

最近编辑记录 LinjieGuo (2022-01-12 09:32:03)

离线

楼主 #28 2022-01-12 09:34:36

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

答案不言而喻(因为开机打印东西有点多,不贴图了)
(1)第一次开机,会因为挂载不上,而格式化FAL分区所创建的块设备,然后挂载这个块设备到dfs
(2)我们手动创建了文件夹whycan之后
(3)无论我们是重启单板,还是重新烧写一样的程序,whycan依然在。

我们再优化一下,流程应该是这样的:
(1)挂载FAL分区所创建的块设备到DFS
    如果挂载成功,则执行正常开机
    如果挂载失败,则执行初始化分区操作。
(2)初始化操作,应该包含以下:
<1>格式化FAL分区为文件系统
<2>挂载文件系统
<3>创建默认工作目录
<4>创建配置文件config到/config目录

最近编辑记录 LinjieGuo (2022-01-12 09:40:46)

离线

楼主 #29 2022-01-12 09:56:01

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

对上一个帖子的要求,我们再度优化bsp_fal_init()函数:

void bsp_fal_init(void)
{
	int fd, size;
    struct statfs elm_stat;
    struct fal_blk_device *blk_dev;
    char str[] = "enable sdcard 1 ", buf[80];

	/* fal init */
    fal_init();

	 /* create block device */
    blk_dev = (struct fal_blk_device *)fal_blk_device_create(FS_PARTITION_NAME);
    if(blk_dev == RT_NULL)
        rt_kprintf("Can't create a block device on '%s' partition.\n", FS_PARTITION_NAME);
    else
        rt_kprintf("Create a block device on the %s partition of flash successful.\n", FS_PARTITION_NAME);

	/* mount elmfat file system to FS_PARTITION_NAME */
    if(dfs_mount(FS_PARTITION_NAME, "/", "elm", 0, 0) == 0)
    {    
    	rt_kprintf("elmfat filesystem mount success.\n");
		return;
	}
	else
	{
		rt_kprintf("elmfat filesystem mount failed.\n");
		goto __do_mount_bolck_dev_fs_failed_fal_action;
		
	}

__do_mount_bolck_dev_fs_failed_fal_action:
	/* make a elmfat format filesystem */
	 if(dfs_mkfs("elm", FS_PARTITION_NAME) == 0)
	 {
		rt_kprintf("make elmfat filesystem success.\n");
		if(dfs_mount(FS_PARTITION_NAME, "/", "elm", 0, 0) == 0)
   		{    
    		rt_kprintf("elmfat filesystem mount success.\n");
			
		}
		 
	 }
	 else
	 {
	 	rt_kprintf("make elmfat filesystem faild.\n");
	 	while(1);
	 }

    /* Get elmfat file system statistics */
    if(statfs("/", &elm_stat) == 0)
        rt_kprintf("elmfat filesystem block size: %d, total blocks: %d, free blocks: %d.\n", 
                    elm_stat.f_bsize, elm_stat.f_blocks, elm_stat.f_bfree);

    if(mkdir("/user", 0x777) == 0)
        rt_kprintf("make a directory: '/user'.\n");
	
	if(mkdir("/sdcard", 0x777) == 0)
		   rt_kprintf("make a directory: '/sdcard'.\n");

	if(mkdir("/config", 0x777) == 0)
		   rt_kprintf("make a directory: '/sdcard'.\n");
	

    rt_kprintf("Write string '%s' to /config/config.txt.\n", str);

    /* Open the file in create and read-write mode, create the file if it does not exist*/
    fd = open("/config/config.txt", O_WRONLY | O_CREAT);
    if (fd >= 0)
    {
        if(write(fd, str, sizeof(str)) == sizeof(str))
            rt_kprintf("Write data done.\n");

        close(fd);   
    }
 
}

编译,修饰,烧写,启动,没啥改变

msh />
msh />
msh />
msh />
msh />ls
Directory /:
user                <DIR>                    
whycan              <DIR>                    
msh />

(使用命令行)擦掉这个这个分区的数据,再试一下:

msh />fal probe
No flash device or partition was probed.
Usage: fal probe [dev_name|part_name]   - probe flash device or partition by given name.
[I/FAL] ==================== FAL partition table ====================
[I/FAL] | name           | flash_dev |   offset   |    length  |
[I/FAL] -------------------------------------------------------------
[I/FAL] | sys_partition  | wind25qx  | 0x00000000 | 0x00100000 |
[I/FAL] | root_partition | wind25qx  | 0x00100000 | 0x00f00000 |
[I/FAL] =============================================================
msh />fal probe root_partition
Probed a flash partition | root_partition | flash_dev: wind25qx | offset: 1048576 | len: 15728640 |.
msh /               
msh />
msh />fal erase 0 4096
Erase data success. Start from 0x00000000, size is 4096.
msh />

最近编辑记录 LinjieGuo (2022-01-12 10:00:58)

离线

楼主 #30 2022-01-12 10:03:01

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

擦掉分区的数据之后,重启,果然OK了。
rtt_fal_erase_reboot.png

我们再做下一步工作:
(1)挂载了spi_nor的一部分分区到根目录,并且创建了sdcard的工作目录,
<1>读入/config/config.txt的内容
<2>根据配置参数,选择要不要挂载SD卡

最近编辑记录 LinjieGuo (2022-01-12 10:06:43)

离线

#31 2022-01-14 22:49:48

435788A
会员
注册时间: 2021-10-27
已发帖子: 23
积分: 36

Re: [记录]f1c200s运行RT-thread

我也来学习,初次接触RTT,文件在那里也不知道,给我来了个错误了
RTT.png

离线

楼主 #32 2022-01-15 08:17:55

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

435788A 说:

我也来学习,初次接触RTT,文件在那里也不知道,给我来了个错误了
https://whycan.com/files/members/7570/RTT.png

哈哈,我上传一下代码啊。
你这个情况,感觉像是源码没有下载全的样子。
可以试试重新拉取系统源码,然后把bsp工程复制进去。
allwinner_tina_prj_v1_fat_elm_dfs.zip

离线

#33 2022-01-15 13:27:37

435788A
会员
注册时间: 2021-10-27
已发帖子: 23
积分: 36

Re: [记录]f1c200s运行RT-thread

@LinjieGuo
下载了,还是出错误。
rtt错误1.jpg
用惯了Keil这种界面,有错误直接跳到出错代码处
这个rtt一时难以上手

离线

楼主 #34 2022-01-15 13:45:22

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 460
积分: 457

Re: [记录]f1c200s运行RT-thread

435788A 说:

@LinjieGuo
下载了,还是出错误。
https://whycan.com/files/members/7570/rtt错误1.jpg
用惯了Keil这种界面,有错误直接跳到出错代码处
这个rtt一时难以上手

rtt的源码重新下载解压了吗?
我把我的整个rtt目录上传上来,你看看。
rt_thread_fal_elm_dfs_20220115.zip

最近编辑记录 LinjieGuo (2022-01-15 14:00:05)

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn