【中科蓝讯AB32VG1 RISC-V板“碰上”RTT测评】四:挂载文件系统,读取SD卡
[复制链接]
本帖最后由 数码小叶 于 2021-5-9 21:10 编辑
照例是新建一个工程
在硬件驱动配置里打开SD卡
SD卡配置打开后,默认会开启DFS、Fatfs、 POSIX组件
保存配置,编译一下,报错rt_hw_us_delay未定义
根据给的资料自己添加是不可能的,不像STM32那样,可以自己去配置,那就只能稍微改造下了,将us延时屏蔽,ms延时+1,误差就是1个ms以下
这样再次编译就没有错误了,试着下载到开发板上。
下载完成后,没任何反应,才意识到,跳线帽忘记了
再次上电,已经可以输出SD卡的信息
此时就可以对SD卡进行操作了,可以直接在串口下也可以在程序中进行,就是Downloader不支持中文输入,最好不要有中文目录了
在串口中操作已经ok,那就再来在代码中操作一下,新建一个text文本文件
int fd, size;
char s[] = "RT-Thread Programmer!", buffer[80];
rt_kprintf("Write string %s to test.txt.\n", s);
fd = open("/text.txt", O_WRONLY | O_CREAT);
if (fd>= 0)
{
write(fd, s, sizeof(s));
close(fd);
rt_kprintf("Write done.\n");
}
fd = open("/text.txt", O_RDONLY);
if (fd>= 0)
{
size = read(fd, buffer, sizeof(buffer));
close(fd);
rt_kprintf("Read from file test.txt : %s \n", buffer);
if (size < 0)
return ;
}
}
首先新建一个text.txt文件,如果存在则直接打开,不存在则新建一个,然后往text.txt写入一个字符串,再将这个字符串读取出来
代码下进去无任何效果,从代码来看,应该是打开失败了,因为不支持在线调试以及仿真,所以只能修改下代码,增加打开失败的执行语句
else
{
rt_kprintf("Open failed!\n");
}
确实确实是打开失败的原因,那就很容易猜到这个出错的原因是盘符挂载失败造成的,但是上面通过串口操作,一切是正常的,继续往下寻找原因
在挂载sd卡的代码上,有这么一段
rt_thread_mdelay(500);
if(rt_device_find("sd0") != RT_NULL)
{
if (dfs_mount("sd0", "/", "elm", 0, 0) == RT_EOK)
这里就造成了一个时间先后的顺序问题,有两个解决办法,自己去挂载,去掉这个自动挂载,这个自动挂载,实际是在rtthread的自动初始化阶段里的第六个阶段app_init阶段进行的。
第二个办法就是等它挂载成功后,再去进行操作,第一个操作过于简单,就选择第二种方法吧,等它挂载完再去操作。
这就需要一个信号量了
rt_sem_t sem_mount =RT_NULL;
sem_mount = rt_sem_create("sem_mount", 0, RT_IPC_FLAG_FIFO);
if (sem_mount == RT_NULL)
{
rt_kprintf("create dynamic semaphore failed.\n");
}
else
{
rt_kprintf("create dynamic semaphore ok.\n");
}
当SD卡挂载成功后,便会释放一个信号量sem_mount,这样就可以进行我们的操作了,包括读写操作,重命名文件、文件夹,新建文件夹等
但是过程总是伴随着新的error出现的
中间省去一堆操作,最后发现简单改下main线程栈大小就行了
rt_thread_t tid;
#ifdef RT_USING_HEAP
tid = rt_thread_create("main", main_thread_entry, RT_NULL,
RT_MAIN_THREAD_STACK_SIZE, RT_MAIN_THREAD_PRIORITY, 20);
RT_ASSERT(tid != RT_NULL);
#else
rt_err_t result;
tid = &main_thread;
result = rt_thread_init(tid, "main", main_thread_entry, RT_NULL,
main_stack, sizeof(main_stack), RT_MAIN_THREAD_PRIORITY, 20);
RT_ASSERT(result == RT_EOK);
修改之后,一切操作OK
对于这个片子,没有任何调试手段的多线程,找bug的原因真的很耗时
|