最近画了块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)
离线
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)编译,修饰,烧写。
复位单板,启动,看起来较为正常了,但是还是有些问题。
插上TF卡,还是这个样子,怀疑是板子引脚不匹配导致的。
最近编辑记录 LinjieGuo (2022-01-05 13:16:08)
离线
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)编译、修饰、烧写、查看启动日志
可以看到,启动的时候,执行了哪些组件的初始化。(BOARD/PREV/DEVICE/COMPONENT/ENV/APP)
打印日志上面2条红色的错误依然醒目,得看看是什么原因导致的。
最近编辑记录 LinjieGuo (2022-01-05 16:41:44)
离线
6、搜索相关内容
通过搜索关键字:[E/[MMC]] [err]:0x00000100, RTO
找到相关帖子
(1)f1c100s 运行时提示错
看来RTT论坛并不重视答疑,从2020年的帖子,到现在都没有解答。
(2)找不到相关内容~~~~难受!
离线
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)
离线
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卡创建文件夹。
最近编辑记录 LinjieGuo (2022-01-05 16:36:49)
离线
楼主高效! 这跑的是rt-smart?
离线
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)
离线
rtthread studio 里面已经有f1c100s了 ,可以直接一键生成工程 效果一样
离线
bootloader分析笔记.md(右键另存为)
bootloader分析笔记.pdf(右键另存为)
最近编辑记录 LinjieGuo (2022-01-07 22:14:12)
离线
@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)
离线
上面是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)
离线
文档的后面还让我们参考这里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) ----
最近编辑记录 LinjieGuo (2022-01-08 16:54:43)
离线
回到家里,使用家里电脑,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)
离线
报错是意料之中,好,那我们就按照要求,修改一下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脚本,干脆这样干了,~~笑~~)
离线
文件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)
离线
文件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 */
离线
为什么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)
离线
也就是说,FAL根本就没有初始化。
我们让他像elm组件一样,自动初始化。
在fal.c文件底部,加入一个宏修饰
INIT_PREV_EXPORT(fal_init);
编译,修饰,下载,启动查看串口打印:
一眼看过去,肯定不对劲,关键的红字信息。
initialize fal_init[E/SFUD] ERROR: Flash device spi00 not found!
在初始化fal的时候,系统跟我们说,找不到spi00。
咦?我们前面定义的宏,明明是:
#define NOR_FLASH_DEV_NAME "wind25qx"
他跟我们说,找不到spi00,那肯定有问题。
我折腾了很久,发现了问题在menuconfig环节,我手欠的把这一项修改了。
修改这一项为 wind25qx,保存,退出menuconfig,然后编译,修饰,烧写。
最近编辑记录 LinjieGuo (2022-01-09 15:14:35)
离线
按照官方知道文档,测试一下--> 软件包-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.
离线
继续前进。
参考文章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)
离线
重启单板,咦?我们刚刚创建的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)
离线
答案不言而喻(因为开机打印东西有点多,不贴图了)
(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)
离线
对上一个帖子的要求,我们再度优化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)
离线
我也来学习,初次接触RTT,文件在那里也不知道,给我来了个错误了
离线
我也来学习,初次接触RTT,文件在那里也不知道,给我来了个错误了
https://whycan.com/files/members/7570/RTT.png
哈哈,我上传一下代码啊。
你这个情况,感觉像是源码没有下载全的样子。
可以试试重新拉取系统源码,然后把bsp工程复制进去。
allwinner_tina_prj_v1_fat_elm_dfs.zip
离线
@LinjieGuo
下载了,还是出错误。
用惯了Keil这种界面,有错误直接跳到出错代码处
这个rtt一时难以上手
离线
@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)
离线
最近在研究LCD显示的方案,先是从Altera的FPGA出发,用Nios2 + LVGL,但Nios2 CPU速度太慢(100MHz),LVGL跑起来非常卡顿。。。。
后来转移到Zynq7000系列的SOC芯片上,折腾了几天,也是没有搞定。。。。
这几天在淘宝上浏览串口屏方案时,发现了这个F1C100/200的芯片,感觉这个芯片太牛了,紧接着一搜,就跳到这边了。。。
离线
rtthread studio 里面已经有f1c100s了 ,可以直接一键生成工程 效果一样
尝试了一下,可以用RT-thread studio生成工程,但缺少好多驱动文件,有人在RT-thread studio环境下成功编译过吗?
刚刚接触RTT,有点迷糊,运行命令的方法太深奥,在RT-thread studio下感觉还好一些[捂脸]
最近编辑记录 sh200436 (2023-02-24 22:08:33)
离线
rtthread studio 里面已经有f1c100s了 ,可以直接一键生成工程 效果一样
怎么配置?
离线
jhon 说:rtthread studio 里面已经有f1c100s了 ,可以直接一键生成工程 效果一样
怎么配置?
--同问,如何配置?
离线
@sh200436
我正在使用 rtthread studio 搞F1C200S 好像跟我的开发板不是很配套 没次更新组件 更新包 都刷新rtconfig.h文件 之前配好的有全废了
有一个坑人的地方就是 我的开发板 //#define TINA_USING_SPI1 这个配置不屏幕 之前不启动,搞得我怀疑人生
现在GT911 也有时候好使有时候不行 ,换个工程有时候不行,有时候写着写着又不行, 不知道有动了哪的配置导致的
还有里面自带的LVGL 我就编译成功过LV8.3.0版本 其余的都因为各种原因最终放弃
离线
@sh200436
我从别人工程把显示和触摸驱动加进去了 是可以的
不过自带有各种触摸驱动芯片的库 但我没使用成功
离线
@tangloong
厉害厉害。我只想把它当成单片机来用,越简单越好。正在尝试坛友们开发的各种编译环境:keil,RT-THREAD, Linux等。不过到目前为止,还没有搞通一个。。。。
离线
@tangloong
厉害厉害。我只想把它当成单片机来用,越简单越好。正在尝试坛友们开发的各种编译环境:keil,RT-THREAD, Linux等。不过到目前为止,还没有搞通一个。。。。
keil 做项目的话不建议 学习可以,我目前还没找到带很全驱动的keil 工程,很多需要自己动手,新手估计很难实现自己想要的东西,RTT相对可能稍微好一些
离线
@tangloong
厉害厉害。我只想把它当成单片机来用,越简单越好。正在尝试坛友们开发的各种编译环境:keil,RT-THREAD, Linux等。不过到目前为止,还没有搞通一个。。。。
https://github.com/nminaylov/F1C100s_projects
从这里下载这个工程,常用驱动都有。在UNBUNTU下编译,一次成功。
离线
我要用这个芯片跑RT-thread加多任务加屏
离线
@tongshezheng
https://github.com/nminaylov/F1C100s_projects
这个很有参考价值,正在研究中
离线
bootloader和rt-thread一起,是不是每回下载程序都只能用电脑识别的usb设备,可以用bootloader更新吗?
离线
@sh200436
现在最好用的已经不是F1C100S了,是ESP32S3
离线
rtthread studio 里面已经有f1c100s了 ,可以直接一键生成工程 效果一样
试过,rtthread studio依然需要Bootloader引导,rtthread studio并没有Bootloader,能编译,能跑,得改东西
离线