| 发表于:2007-11-13 13:44:30 楼主 |
empress嵌入式实时数据库 ------------工业控制的利器 上海互惠信息技术有限公司 jun88he@163.com 1 empress 介绍(http://www2.empress.com) empress 数据库由加拿大 empress 公司于1979 年推出, 当时是 unix 系统下的常用数据库, 也就是 empress rdbms suites 版, 后来推出其嵌入式版本 empress embedded / empress ultra embedded, 主 要面向军工控制和航天领域, 目前在北美, 加拿大, 日本有广泛的运用. 2 最优点----强大的数据检索功能 在电子地图, 车载导航等需要检索大量数据时, empress 能发挥其强大的优势, 这一点在一些公司招 标中得到证明, empress 不仅支持传统数据库的 sql 语言, 也有自己的高效率 mr (micro relation) 控制语句, 通常把关键的功能用 mr 语句实现(一个函数), 对变动较大的功能用 sql 语句实现, 从而 达到灵活的运用. 3 工业控制 工控系统中运用大量的 plc, 控制稳定可靠, 但 plc 上运行 linux, vxworks 等操作系统有一定的 困难, plc 的计算能力也只有几十 mips, 在很多复杂系统中达不到要求, 采用中高档处理器加嵌入式 操作系统可以成为尝试的方向, 例如有 50---500 个传感器的系统, 如温度传感器 t0, t1, t2..., 速度传感器 s0, s1, s2..., 压力传感器 p0, p1, p2... 注意: 不要用线程, 如果用一个线程对应一个传感器, 几百个线程的时间片如何划分? 时间片的划分本 来就是随即的(否则达不到多任务的效果). 很难保证每一个传感器在规定的时间内得到时间片并做出响 应. 方法一: 开一个二维数组, t0 t1 t2 ... s0 s1 s2 ... p0 p1 p2... time0 time1 . . . timen 把定时器尽量设小(设为最小公约数), 以满足频率最高的传感器的采样, 数据过来之后输入响应的位置, 这样可以把指定时间段内的数据作出处理, 当然, 内存数组容量毕竟有限, 后来的数据会把前面的数据 覆盖掉, 前面有用的数据可以保存起来. 该方法过于理想, 实现起来有很多问题, 如: t0 每 13ms 采样一次, t1 每 19ms 采样一次, 采样时间 间隔就应该设为 1ms, 结果处理器回疲于奔命的采样, 其他什么事情也做不了. 如果情况可能, 可把定时器设为最大公倍数, 把过来的数据缓冲一下, 也能达到要求, 毕竟, 嵌入式系 统要求在规定的时间内作出反应, 而不是在最快的时间内作出反应. 方法二 用 empress 数据库, empress 会帮助解决采样值缓冲的问题, 就象传统数据库一样, 有一定的缓存能力, 减轻了程序员处理缓 存的工作, 同时 empress 可以一边插入数据, 一边把前面重要的数据备份, 为程序员提供高效, 可靠的 模块功能. 4 性能 烧到flash中的代码有 1m大小, 运行时占用 ram 500---800k. number of databases no empress imposed limit. size of database a single database may occupy an entire file system. a single database may also span several file systems. size of table (in bytes) on most machines, this is the size of a 64-bit integer or about 264 bytes. size of record (in bytes) on most machines, this is the size of a 64-bit integer or about 264 bytes. size of attribute (in bytes) on most machines, this is the size of a 64-bit integer or about 264 bytes. number of tables/database 32,767 number of attributes/table 32,767 number of keys/sort no empress imposed limit. number of indices/table no empress imposed limit. number of attributes/index no empress imposed limit. number of levels-of-nesting/subquery 100 5 简单示例 //helloworld.c #include <mscc.h> msmain () { msinit (); printf ("hello world !\n"); msexit (); } 设置环境变量c:\program files\microsoft visual studio\vc98\bin> vcvars32.bat empcc hello.c hello // mr 编程 #include <mscc.h> #define database "testdb" msmain () { addr personnel_tabdesc, personnel_recdesc, id_attrdesc, name_attrdesc, salary_attrdesc; personnel_tabdesc = mropen (database, "personnel", 'u'); id_attrdesc = mrngeta (personnel_tabdesc, "id"); name_attrdesc = mrngeta (personnel_tabdesc, "name"); salary_attrdesc = mrngeta (personnel_tabdesc, "salary"); personnel_recdesc = mrmkrec (personnel_tabdesc); if (! mrputvi (personnel_recdesc, id_attrdesc, 105)) { fprintf (stderr, "name conversion unsuccessful\n"); msend(); return 1; } else if (! mrputvs (personnel_recdesc, name_attrdesc,"who")) { fprintf (stderr, "date conversion unsuccessful\n"); msend(); return 1; } else if (! mrputvi (personnel_recdesc, salary_attrdesc, 5678)) { fprintf (stderr, "amount conversion unsuccessful\n"); msend(); } else if (! mrputvi (personnel_recdesc, salary_attrdesc, 5678)) { fprintf (stderr, "amount conversion unsuccessful\n"); msend(); return 1; } mradd (personnel_recdesc); if (!mraddend (personnel_recdesc)) { fprintf (stderr, "error in writing internal buffers\n"); fprintf (stderr, "mroperr='%d' : %s\n", mroperr, mrerrmsg ()); } if (!mrfrrec (personnel_recdesc)) { fprintf (stderr, "error in freeing record buffers\n"); fprintf (stderr, "mroperr='%d' : %s\n", mroperr, mrerrmsg ()); } if (!mrclose (personnel_tabdesc)) { fprintf (stderr, "unable to close the table\n"); fprintf (stderr, "mroperr='%d' : %s\n", mroperr, mrerrmsg ()); } return 0; } //sql 编程 #include <mscc.h> EXEC sql include sqlca; EXEC sql begin declare section; int oldval; int newval; EXEC sql end declare section; main() { EXEC sql init; EXEC sql database is "testdb"; oldval=5000; newval=6000; EXEC sql update personnel set salary=:newval where salary=:oldval; EXEC sql exit; } |
|
|
|
|