本文主要介绍在英创Linux工控主板(ESM8000、ESM7000和ESM6800H)上,采用Python和C#编程,实现SQLite数据库访问的方法。数据库为应用程序展现的是纯粹的数据,更便于像Python、C#这样的高级语言处理。而数据的获取则通过Linux系统的后端程序(Backend),采用效率更高的C来实现,以满足数据采集过程中的协议需求和时序需求。从系统程序架构上看,SQLite数据库把上层的Python, C#应用程序与后端的C程序连接在一起。
本文的Python和C#实例,均采用Visual Studio Code作为基本的编程工具,其代码可在主板 + ESMARC评估底板上运行,其基本的硬件环境采用采用ESM8000工控主板 + 评估底板构成,如下图所示:
本文实例中SQLite数据库包含以下信息:
ID | Name | Value | 简要说明 |
INT | TEXT | TEXT | 字段数据类型 |
0 | refresh | - | 数据更新周期,ms单位 |
1 | cpu-temperature | - | CPU芯片温度,℃单位 |
2 | cpu-payload | - | CPU当前负载率,包括各个核的负载率 |
3 | eth0 | - | 网口信息,包括名称、类型(RJ45、WiFi、4G等)、IP参数、连接状态(down、up、信号强度) |
4 | eth1 | - | |
5 | eth2 | - | |
6 | … | - | 更多网口信息。。。 |
SQLite数据库文件保存在”/mnt/mmc/sysinfo.db”。
系统的程序架构由客户应用程序、数据库、后端程序组成,它们与硬件环境的关系如下图所示:
对简单的接口操作,Python,C#可通过各自的通用IO库来实现,如在《英创Linux主板的Python, C#实例简介之一》一文中介绍的那样。若接口通讯需要满足特定的协议,或有特殊的实时性要求,则可采用C编程的后端程序来实现,访问硬件获得所需数据,更新至SQLite数据库中。上层的Python,C#应用程序则直接访问数据库,无需关心数据获取过程的细节。
Python应用程序
应用程序负责创建SQLite数据库。
import sqlite3
from time import sleep
conn = sqlite3.connect("/mnt/mmc/sysinfo.db")
with conn:
cur = conn.cursor()
# Create table
cur.execute("CREATE TABLE IF NOT EXISTS EMINFO(
id INT, name TEXT, value TEXT)")
# Select a row of data
cur.execute("SELECT * FROM EMINFO where id=0")
row = cur.fetchone()
if row:
t = int(row[2])
else:
t = 1000
# Insert a row of data
cur.execute("INSERT INTO EMINFO VALUES(0,'refresh','1000')")
#Show all row of data from EMINFO table
while True:
cur.execute("SELECT * FROM EMINFO")
rows = cur.fetchall()
for row in rows:
print(row)
print("\n")
sleep(t/1000.0)
conn.close()
C#应用程序
需要添加Microsoft.Data.SQLite类库。
using System;
using Microsoft.Data.Sqlite;
using System.Threading;
namespace Step5_Sqlite
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Step5_Sqlite");
//打开系统数据库
var connection = new SqliteConnection("Data Source=/mnt/mmc/sysinfo.db"); //打开系统内存中的数据库
connection.Open();
//创建table
var createCommand = connection.CreateCommand();
createCommand.CommandText =
@"
CREATE TABLE IF NOT EXISTS EMINFO(
id INTEGER PRIMARY KEY,
name nvarchar(30),
value nvarchar(100)
)
";
createCommand.ExecuteNonQuery();
//修改refresh值
int n;
var refreshCommand = connection.CreateCommand();
refreshCommand.CommandText = @"UPDATE EMINFO SET value='10' WHERE name='refresh'";
n = refreshCommand.ExecuteNonQuery();
if(n == 0) //如果没有refresh项,则添加
{
refreshCommand.CommandText = @"INSERT INTO EMINFO (name,value) VALUES ('refresh','10')";
refreshCommand.ExecuteNonQuery();
}
//查询table内容并打印
string str;
var queryCommand = connection.CreateCommand();
queryCommand.CommandText =
@"
SELECT * FROM EMINFO
";
SqliteDataReader reader;
while(true)
{
reader = queryCommand.ExecuteReader();
while(reader.Read())
{
str = reader.GetValue(0).ToString() + " " + reader.GetValue(1).ToString() + " " + reader.GetValue(2).ToString();
Console.WriteLine(str);
}
reader.Close();
Thread.Sleep(100);
}
//关闭数据库
connection.Close();
}
}
}
后端C程序
后端C程序打开已创建的SQLite数据库,根据更新率,周期性地把CPU和网络端口信息提交至数据库。
后端C程序源码test_emdb.c可点击下载,对不同主板需要相应的GCC编译工具如下:
主板类型 | GCC |
ESM6800 | cortexa7hf-neon-poky-linux-gnueabi |
ESM7000 | cortexa7hf-neon-poky-linux-gnueabi |
ESM6802 | cortexa9hf-neon-poky-linux-gnueabi |
ESM8000 | aarch64-poky-linux |
相对说来,后端C程序比上层的Python,C#程序要复杂得多,这也正好体现了Python,C#的高效简洁的特性。