目前用d133定时采集can总线上的数据,然后在rgb屏幕上的lvgl界面上显示出来。
但是想保存采集到的数据,方便其他设备查询历史记录,或者在lvgl界面上查询历史记录。
请教,有什么好的办法?
问了几个群里,有推荐sqlite3和flashdb的。想知道,使用数据库有什么好处?
还有就是目前使用的spi nor flash,如果用fatfs,好想说并不适合频繁擦写。
目前有两种需求:
1, 采集can总线上定时发送过来的数据,每次保存,或几次采集后保存一次,可能保存频率很高;
2, 采集can总线上不定时发送过来的,一般是系统出现问题时才发送过来,保存频率较低。
最近编辑记录 Gentlepig (2024-06-25 09:23:01)
离线
建议用日志型(ext4,jffs2...)的文件系统,按时间段分文件存储。
如果没有后备电池和断电检测,做好最后一个文件阵亡的心理准备。
我这不是linux系统啊,是rtt,目前看sdk里默认打开了fatfs和littlefs。
离线
手头的板子没焊接sd相关,打算先用spi nor flash存储做个尝试。
rtt配置里勾选了littlefs和sqlte,sqlite里勾选了example。
/rodata配置为fatfs,分配了5M;/data配置为littlefs,分配了7M。
student_dao.c里默认数据库存在/data/stu_info.db。
编译后烧录到板子上,执行crate_student_tbl命令,按说应该在/data目录下生成stu_info.db数据库,可串口终端一直卡在这个命令这里,不过光标还是闪烁的。
等了几分钟后,仍是这个效果,就重启板子,发现/data下有stu_info.db文件,虽然大小为0。
执行stu命令,应该显示数据库所有数据,结果仍是卡住且光标正常闪烁。
以为是文件系统的问题,将student_dao.c里创建数据库的位值改为/rodata,这个是fatfs格式的。
结果执行create_student_tbl命令后,还是卡住,重启后,在/rodata目录下,并没有db数据库文件生成。
离线
@Gentlepig
写一大串没用的,难道你就没有怀疑是你输入的命令有问题?写了一大串也没有把重要细节show出来!
输入命令如下:
dlk /> df /rodata
disk free: 4.8 MB [ 9968 block, 512 bytes per block ]
dlk /> df /data
disk free: 6.8 MB [ 1764 block, 4096 bytes per block ]
dlk /> create_student_tbl
/rodata/stu_info.db
对应函数如下,无参数,目的是创建数据库:
static int create_student_tbl(void)
{
int fd = 0;
db_set_name("/data/stu_info.db");
fd = open(db_get_name(), O_RDONLY);
rt_kprintf(db_get_name());
if (fd < 0)
{
/* there is not the .db file.create db and table */
const char *sql = "CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(32) NOT NULL,score INT NOT NULL);";
return db_create_database(sql);
}
else if (db_table_is_exist("student") > 0)
{
/* there is the table int db.close the db. */
close(fd);
LOG_I("The table has already existed!\n");
return RT_EOK;
}
else
{
/* there is not the table int db.create the table */
const char *sql = "CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(32) NOT NULL,score INT NOT NULL);";
return db_create_database(sql);
}
}
MSH_CMD_EXPORT(create_student_tbl, create sqlite db);
详细文件见:
https://gitee.com/artinchip/luban-lite/blob/master/packages/third-party/sqlite/student_dao.c
离线
还是得看readme.
358 ## 注意事项
1 - SQLite资源占用:RAM:250KB+,ROM:310KB+,所以需要有较充足的硬件资源。
2 - 根据应用场景创建合理的表结构,会提高操作效率。
3 - 根据应用场合理使用SQL语句,如查询条件,插入方式等。
4 - 如涉及到多表操作或联表查询,最好使用PowerDesigner等工具合理设计表。
我是在msh里执行create_student_tbl命令的,应该是需要比较大的内存,而msh默认分配了4k内存,改成40k后,可以创建数据库成功了。使用stu add xxx命令来增加数据条出错了,还在解决:
dlk />
dlk /> cd data
dlk /data> ls
Directory /data:
123 4
stu_info.db 12288
ui_font_Big.c 102408
dlk /data> stu add 1
01-01 08:31:52 E/app.dbhelper: bind failed errmsg:database disk image is malformed
01-01 08:31:52 E/app.dbhelper: db operator failed,rc=1
01-01 08:31:52 E/app.student_dao: add failed!
dlk /data>
dbhelper.c文件里,该行报错:
268 sqlite3_finalize(stmt);
1 if ((rc != SQLITE_OK) && (rc != SQLITE_DONE))
2 {
3 LOG_E("bind failed errmsg:%s", sqlite3_errmsg(db));
4 goto __db_exec_fail;
5 }
-------------------------------
msh栈空间改为400k,结果仍一样。
尝试改为1M,结果上电后,不运行了...
---------------------------------
student_dao.c里,执行stu add命令后,会调用到这个函数。
int student_add(rt_list_t *h)
{
return db_nonquery_operator("insert into student(name,score) values (?,?);", student_insert_bind, h);
}
db_nonquery_operator()执行一系列操作后,调用的是如下函数。
static int student_insert_bind(sqlite3_stmt *stmt, int index, void *arg)
{
int rc = 0;
rt_list_t *h = arg, *pos, *n;
student_t *s = RT_NULL;
rt_list_for_each_safe(pos, n, h)
{
s = rt_list_entry(pos, student_t, list);
sqlite3_reset(stmt); //reset the stmt
sqlite3_bind_text(stmt, 1, s->name, strlen(s->name), NULL); //bind the 1st data,is a string
sqlite3_bind_int(stmt, 2, s->score); //bind the 1st data,is a int
rc = sqlite3_step(stmt); //execute the stmt by step
}
if (rc != SQLITE_DONE)
return rc;
return SQLITE_OK;
}
感觉是这个函数执行后返回的值rc,根据rc值执行了报错输出。
最近编辑记录 Gentlepig (2024-06-26 17:45:54)
离线
感谢各位,板子是有网口的,目前是通过tcp将数据发送给局域网pc。
本机存储是想以后可能会用到,某些不定时的,数量较少的数据,希望存储到板子上。
离线
https://club.rt-thread.org/ask/question/9faea7447d375649.html
这个sqlite在spi和sd卡上没法用,慢到无法忍受.归根结底是文件系统速度太慢.我有在uffs和yaffs文件系统上测,文件系统速度是上去了。但是数据量增加到一定量数据库就报SQL error: database disk image is malformed。不知道什么鬼。
但是在SD卡文件系统上测试就不会
在rtt论坛搜到同样报错的帖子,我还是放弃单片机上跑sqlite吧,或者等artinchip来解决。
话说,artinchip的lunban-lite sdk里带的这个sqlite,也许是给d21x这类片子运行的吧。
最近编辑记录 Gentlepig (2024-06-27 16:57:15)
离线
莫名奇妙的例程能正常运行了。
dlk /data> create_student_tbl
/data/stu_info.dbdlk /data>
dlk /data> ls
Directory /data:
stu_info.db 12288
dlk /data> stu add 10
Insert 10 record(s): 1166ms, speed: 116ms/record
dlk /data> stu
test get all students
id:1 name:Student44408 score:40
id:2 name:Student44409 score:41
id:3 name:Student44411 score:43
id:4 name:Student44414 score:46
id:5 name:Student44418 score:50
id:6 name:Student44423 score:55
id:7 name:Student44429 score:61
id:8 name:Student44436 score:68
id:9 name:Student44444 score:76
id:10 name:Student44453 score:85
record(s):10
dlk /data> stu score 40 60
-------------------------------------
创建数据库,新增数据、删除、按分数范围查找,都能执行。
执行stu score时有个坑,按说stu score 40 60,就可以查找40-60分数的数据,结果本来是4个参数,有个可选的第5个参数,程序里只判断参数大于4个的情况下,也会去读取第5个参数,结果就卡住了。加个条件即可,参数大于5时才读第5个参数。
msh线程分配了10k空间,占用率85%。
-------------------------------------
上午发现stu add命令可以成功执行后,觉得之前尝试给msh分配的空间太大了,就由512k逐渐减下去,减到10k后sqlite例程的几个命令还可以使用,以为没事了。
下午切到win下,又试着重新编译sdk里的sqlite,结果又出现了上次的问题,create_student_tbl命令可以成功创建数据库,但是stu add命令就会失败,仍报错:
bind failed errmsg:database disk image is malformed
msh线程空间也改大了,无效。怀疑是spi速度的原因影响spi nor flash里的littlefs分区的读写,降低spi速度,无效。
又切回到ubuntu下,由于下午想尝试libmodbus,重新编译过。发现ubuntu下编译烧录后,stu add命令也是报错。
最近编辑记录 Gentlepig (2024-06-28 17:13:46)
离线
https://club.rt-thread.org/ask/question/9faea7447d375649.html
看这篇文章,发现需要打开SAL选项,估计是
enable bsd socket operated by file system api.
但是我搜目前的rtt组件,没搜到这个,目前打开的是:
│ │ [*] SAL: socket abstraction layer ---> │ │
│ │ -*- Enable network interface device --->
而且,和local package里的lwip寸在冲突。
现在不用local lwip时,sqlite功能正常了。
-----------------------------------------------
一次插入8000条数据,可以成功,插入9000条,就卡住了,重启后发现目录下多了个journel.db。
删掉数据库,创新创建,多次插入8000调数据,可以成功,但发现插入一条数据的时间比插入8000调数据的时间还长。
比如,插入一条数据要16秒,插入8000调要12秒。
多次插入后,就出错了,用stu score再也无法查询出某范围的条数。复制数据到到pc,用db brower查看,也看到数据内容。
此时文件系统没有被占满,分配了7M空间,数据库才700多k。
------------------------------
删掉数据库,重新创建,然后每次只插入一条数据,发现时间大概话非1秒,有点难受啊。
用stu命令可以看到列出数据,看数据库最大条数是8564, 再新增也是这个数字。那么,数据库最大容量是8564?但实际不是,用stu score m n,可列出score值巍在m和n范围内的数据条,可以看的id有超过8664的。
最近编辑记录 Gentlepig (2024-06-29 16:24:10)
离线
@海石生风
你的d21x也是运行的rtt还是linux?
按说d13x和d21x主频相比差不算太大。d13x 480M, d21x 504/600M.
剩下的,内存大小差异?8M不够用?新做了一版,打算试试16M的。
我插入9000条数据就卡死,但是连续插入8k条数据可以成功。最后放弃了sqlite这一方案。
后来尝试了flashdb。
想问下,nand flash,是不是就不用考虑擦写均衡了?
我看flashdb的几个例程,都是spi nor flash和onchip flash的。
最近编辑记录 Gentlepig (2024-07-24 14:53:59)
离线