嵌入式参数配置工具(python+pylink)(二)--bin文件生成和调用

背景:设备中包含大量参数,需要配合非程序员同事修改参数进行测试。没有可用的人机交互接口,只能通过串口AT指令或烧录的方式访问。

目标是做成一款人人可以上手的工具,快速对设备进行自定义的配置。

系列文章:

产品参数配置工具(python+pylink)(一)--方案设计-CSDN博客

产品参数配置工具(python+pylink)(三)--pylink的使用-CSDN博客

产品参数配置工具(python+pylink)(四)--pyqt界面设计-CSDN博客

产品参数配置工具(python+pylink)(五)--打包exe-CSDN博客

目录

bin文件生成

bin文件格式定义

excel设计要点

文件生成

写入准备

参数读取

文件填充

生成crc

bin文件调用

更新源文件再生成bin


bin文件生成

输入源选择了大众比较容易接受和熟悉的excel,不需要花费大量时间做输入接口界面,且用户基本都安装有可编辑excel的软件。这一部分需要先定义bin文件格式,设计excel表呈现数据,编写python脚本解析excel表并转换成指定格式的bin文件。

bin文件格式定义

固件中打算使用结构体指针的方式访问bin文件,因此定义以下格式存储bin文件

excel设计要点

1、为了方便python读取数据,尽量将需要转换的数据设计到同一列,每个数据需要包含数据本身和这个数据占用的字节数,用于后续转换进bin文件。

另外需要注意的是,尽量将一样大小的数据放在一个区域,这样pandas读取时不需要分太多块。当然本着用户优先的原则,表格的可读性和可查性还是需要放在第一位考虑

设计表格时第一行用于python读入数据,给需要python读入的列命名。可以将它的属性设置为隐藏,打开工作表保护后用户就看不见了。

2、需要限制表格的可更改区间,避免用户误修改导致文件生成失败

1)选中需要修改的表格,右键菜单选择设置单元格格式,在保护标签中,去掉锁定的选定

2)在审阅窗格中,选择保护工作表,在弹出窗口中设置取消保护的密码,只选择选定解除锁定的单元格允许用户修改。

3、对可编辑的数据进行简单的判断和验证,限制可设置的区间,格式等

选择需要验证的单元格,在数据窗格中选择数据验证

在弹出的窗口中按照需求设置验证条件,提示信息,出错警告信息等内容即可。这里只写一个比较复杂的验证,要求数据输入值是0-1000中50的倍数

公式如下:

=(A1>0)*AND(A1<1001)*AND(MOD(A1,50)=0)    (A1替换为要做验证的单元格位置)

文件生成

使用python做bin文件生成脚本,需要使用的库有pandas,numpy,os.path

1)清空文件,写入header;
2)然后按照结构体定义的顺序,逐个读入配置参数数据,转换成bytes格式,写入bin文件中;

结构体定义时需要注意,优先占空间更大的数据,避免C语言结构体数据对齐导致的数据浪费。这样生成bin文件时也可以不需要刻意考虑数据对齐问题。

例如:

下图中param_struct1占用6个字节,生成bin文件需要考虑占位问题

而param_struct2只占4个字节,生成bin文件时不需要考虑占位,直接向文件末尾append数据即可

typedef struct {
    uint8_t a;
    uint16_t b;
    uint8_t  c;
} param_struct1;

typedef struct {
    uint16_t b;
    uint8_t a;
    uint8_t  c;
} param_struct2;

3)计算文件大小,填充0xff,保证bin文件大小固定(方便将默认参数bin文件嵌入固件中);

4)计算crc写入文件结尾。

写入准备

 由于写入使用追加的方式,重新生成文件时需要将文件清空从头开始写

def clear_binfile(fpath):
    binfile = open(fpath, 'ab+')
    #定位到文件最开始
    binfile.seek(0)
    #截断文件,定位后面的内容全部删除
    binfile.truncate()
    binfile.close()
参数读取

使用pandas库,读入数据,为了避免excel表读入时数据格式异常,可以优先定义dtype读入为指定格式数据。

import pandas as pd
import numpy as np

 dtype = {
     'data1': np.int64,
     'data2': np.int64
 }
 alldata = pd.read_excel(inputpath, index_col='index', sheet_name='main', dtype=dtype)

选中指定区域,一块一块的读取,转换成bytes写入bin文件

def write_binfile(data,length,fpath):
    #pandas读入格式为np.int64,to_bytes方法是int的方法,所以需要先转换
    if type(data) == np.int64:
        data = data.item()
    #little表示小端序的方式转换数据到bytes,length表示转换后占用多少字节
    content = data.to_bytes(length, 'little') 
    binfile = open(fpath, 'ab+')
    binfile.write(content)
    #print("content:", content)
    binfile.close()


def write_data_block(data,fpath,config):
    for i in data.index:
        write_binfile(data[config[0]][i],data[config[1]][i],fpath) 


#这里要根据表格的情况自行调用,可以进一步封装
config = ['data1', 'length1']
datablock1 = alldata[config]
datablock1 = datablock1.iloc[4:]
write_data_block(datalock1, outputpath, config)
文件填充

根据当前文件大小,计算出需要填充0xff的数量,使用write_binfile填写到bin文件后面

def get_length_tobe_filled(fpath):
    #获取当前文件中已经写入的字节数
    size = os.path.getsize(fpath)
    return target_length - size - crc_length
生成crc

这部分要写的和mcu解析那端一致,才能达到校验效果。

参考资料:CRC校验原来这么简单-腾讯云开发者社区-腾讯云

一个crc库:https://github.com/whik/crc-lib-c

crc8算法摘录如下:

bin文件调用

当文件烧录入ROM指定地址后,可以通过结构体const指针的方式访问。

定义一个全局的const结构体指针,根据不同的需求,将const指针指向想要使用的数据地址。只需要将调用参数的方式改成通过指针访问即可。

例如:

//定义const指针并指向默认参数
const param_struct2 * pp = (const param_struct2*)(ROM_ADDR_PARAM_NORMAL);

//需要使用参数的时候通过指针访问,当前指针指向哪个地址,就访问的哪套参数
use_param1(pp->param1);

更新源文件再生成bin

由于生成bin文件比较慢,当源文件没有更新时,可以跳过这个过程。

python提供了三个函数分别获取文件的生成时间,修改时间,修改属性的时间:

os.path.getctime('path')

os.path.getmtime('path')

os.path.getatime('path')

最终决定比较源文件的修改时间,和bin文件的修改时间,若源文件修改时间更新,则重新生成bin;否则不再重新生成bin文件。

上一篇:产品参数配置工具(python+pylink)(一)--方案设计-CSDN博客

下一篇:产品参数配置工具(python+pylink)(三)--pylink的使用-CSDN博客

  • 18
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
可以使用PythonPyQt5库来开发嵌入式系统测试工具PyQt5是一个Python的GUI开发框架,能够提供丰富的GUI组件和工具,使得开发者可以轻松地创建漂亮、交互式的用户界面。 下面是一个简单的示例,展示了如何使用PyQt5来创建一个嵌入式系统测试工具: ```python import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("嵌入式系统测试工具") self.setGeometry(100, 100, 400, 300) label = QLabel("欢迎使用嵌入式系统测试工具", self) label.move(100, 50) button = QPushButton("开始测试", self) button.move(150, 150) button.clicked.connect(self.start_test) def start_test(self): # 在这里添加测试代码 print("开始测试...") if __name__ == "__main__": app = QApplication(sys.argv) mainWindow = MainWindow() mainWindow.show() sys.exit(app.exec_()) ``` 在这个示例中,我们创建了一个MainWindow类,继承了QMainWindow,并在构造函数中设置了窗口的标题和大小。我们还添加了一个标签(label)和一个按钮(button)。 当用户点击按钮时,会触发start_test函数,我们可以在这里添加测试代码。 最后,我们创建了一个QApplication实例,将MainWindow实例作为主窗口,并启动了应用程序。 通过使用PyQt5库,我们可以轻松地创建一个漂亮的、交互式的嵌入式系统测试工具

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值