技术博客

19/04/2016 作者 Magnus Carlsson

使用kvmlib配置SD卡

这是使用Kvaser Memorator第二代设备通过kvmlib进行配置和读取记录数据4篇系列文章的最后一篇:

  1. kvmlib入门指南
  2. 在配置中添加脚本和触发器
  3. 深入了解kvmlib
  4. 使用kvmlib配置SD卡

之前我们通过 kvmlib配置设备,检索配置和记录的数据以进行进一步分析。现在我们要看看如果我们只使用插入到设备中的SD卡,那么会有哪些不同的操作。这种情况取决于SD卡在物理日志位置和我们之间传输的位置。

为了达到这项工作的目标,我们会使用一个已经在Windows中格式化的16G的SD卡,初始化并配置该卡,这样我们就能将此SD卡插入到我们的Kvaser Memorator Pro 5xHS(编码00778-9)中使用,其固件版本为3.0。运行日志会话之后,我们会从设备上移除SD卡,读取并重置日志文件。全部程序列表可在GitHub上获得。

4.1 初始化SD卡

如果你手头没有相关设备,你也可以用你的电脑和mhydraformat.exe程序初始化SD卡。但是这种方式会比使用设备格式化花费更多的时间,初始化一个16G的卡大约需要花费3分钟。

mhydraformat.exe 程序可以在Kvaser Memorator配置工具的安装目录中找到。1 你可以使用–help参数运行格式化程序来查看使用帮助文本。

[C:\]mhydraformat.exe --help
Disk formatting program for Kvaser Memorator (2nd generation) devices.
-h       --help            | Print this information.
-d=DRIVE --drive=DRIVE     | The drive to format, e.g. F:
-r=X     --reserve=X       | The number of MB to reserve for user files.
-c=X     --config=X        | The number of MB to reserve for configurations.
         --fat16           | Format the disk with FAT16. Default is FAT32.
-i       --interactive     | Require the user to confirm before format.
-q       --quiet           | Stop all outputs. Overrides -i.
         --bin5            | Use the older, smaller version 5 of PARAM.LIF.
         --lio3            | Use the older LIO data format 3 for KMF files.

Example:
         mhydraformat -d=F: -r=100 -c=10 --interactive

将你的SD卡连接电脑,请注意驱动器盘符。我的示例中,指定SD卡在E:。检查过SD卡的内容后,我们运行mhydraformat.exe程序初始化该卡。请注意,用于指定要分配给DATABASE.BIN的空间的命令行开关在此处命名为–config。在使用Windows dir命令格式化之后,我们也要再查看SD卡的内容。

dir E:
 Volume in drive E has no label.
 Volume Serial Number is 5C92-4738

 Directory of E:\

2016-02-23 08:41                  0 dummy_file
              1 File(s)               0 bytes
              0 Dir(s)   16 129 335 296 bytes free
mhydraformat.exe -d=E: -r=10000 -c=10
Formatting...done.
dir E:
 Volume in drive E has no label.

 Directory of E:\

2016-02-23 08:45 10 485 760 PARAM.LIF
2016-02-23 08:45 1 073 741 824 LOG00000.KMF
2016-02-23 08:45 1 073 741 824 LOG00001.KMF
2016-02-23 08:45 1 073 741 824 LOG00002.KMF
2016-02-23 08:45 1 073 741 824 LOG00003.KMF
2016-02-23 08:45 1 073 741 824 LOG00004.KMF
2016-02-23 08:45 736 649 216 LOG00005.KMF
2016-02-23 08:45 10 010 624 DATABASE.BIN
8 File(s) 6 125 854 720 bytes
0 Dir(s) 10 004 480 000 bytes free
echo
ECHO is on.

在此我们看到的是二进制配置文件(PARAM.LIF)、日志文件容器(从LOG00000.KMFLOG00005.KMF)以及为Kvaser Memorator配置工具保留的配置文件(10 MB DATABASE.BIN)。我们也可以看到我们所需的10000MB可用空间。

4.2 将配置保存到磁盘

为了直接下载配置到SD卡,我们需要打开文件系统,而不是像之前发布的博文中那样打开设备。我们还需要通知kvmlib我们的SD卡安装在哪。这是通过调用函数kmfOpen()来实现的,并向LOG00000.KMF文件提供完整路径,其一直存在于已正确初始化的SD卡内。2

我们现在也使用kvaMemoLibXml直接将二进制配置文件编写到SD卡里。

如前所述,我们仍需提供正确的设备型号。

# Our SD card is mounted under E:, so that is where our
# binary configuration should be placed.
filename = "E:\\PARAM.LIF"
 
xl = kvaMemoLibXml.kvaMemoLibXml()
print "kvaMemoLibXml version: v%s" % xl.getVersion()
 
# Convert the previously validated XML configuration file
# and write the resulting binary configuration to SD card
xl.kvaXmlToFile("config.xml", filename)

列表18:将二进制配置文件编写到SD卡里

要以明文形式下载配置,我们只需像之前文章里提到的那样做即可,除此之外可通过Windows安装点将压缩文件直接写入SD卡。

import zipfile
 
# Our SD card is mounted under E:
filename = "E:\\config.zip"

# Creating zip archive
with zipfile.ZipFile(filename, mode='w',
                     compression=zipfile.ZIP_DEFLATED) as zipf:
    # Adding files to zip archive
    zipf.write("config.xml")
    zipf.write("myCanGenerator.txe")

列表19:使用zip包编写明文配置

如果我们现在查看我们的SD卡里的内容,我们会看到如下内容。

d:\temp\blog>dir E:
 Volume in drive E has no label.

 Directory of E:\

2016-02-19 07:58 40 308 PARAM.LIF
2016-02-11 14:43 1 073 741 824 LOG00000.KMF
2016-02-11 14:43 1 073 741 824 LOG00001.KMF
2016-02-11 14:43 1 073 741 824 LOG00002.KMF
2016-02-11 14:43 1 073 741 824 LOG00003.KMF
2016-02-11 14:43 1 073 741 824 LOG00004.KMF
2016-02-11 14:43 744 030 208 LOG00005.KMF
2016-02-11 14:43 10 002 432 DATABASE.BIN
2016-02-19 10:10 2 406 config.zip
              9 File(s) 6 122 784 474 bytes
              0 Dir(s) 10 010 435 584 bytes free

4.3 从SD卡读取结果

当我们从现场获取SD卡时,我们将SD卡重新连接到我们的计算机,并开始验证SD卡上的LIO数据格式版本。

ml = kvmlib.kvmlib()
  
# Our SD card is mounted under E:, so our LOG00000.KMF can
# be opened from here
filename = "E:\\LOG00000.KMF"

try:
    # Open the SD card
    # We have firmware version 3.0 in the device this SD card will
    # be inserted into, this means that the FW is using Lio Data
    # Format v5.0 and we should use kvmDEVICE_MHYDRA_EXT as
    # the deviceType
    lioDataFormat = ml.kmfOpenEx(filename,
                                 deviceType=kvmlib.kvmDEVICE_MHYDRA_EXT)
    print "Lio Data Format v%s" % lioDataFormat

    # Close SD card
    ml.close()

    # Verify that the LIO data format of the card corresponds to
    # the device type we used when opening the device
    if lioDataFormat != '5.0':
        print "Unexpected Lio Data Format:", lioDataFormat
        if lioDataFormat == '3.0':
            print("This log file can be read if you reopen the"
                  " device as kvmDEVICE_MHYDRA.")
        exit(1)
except kvmlib.kvmDiskNotFormated:
    print "SD card is not initialized..."
    exit(1)

列表20验证SD卡上的LIO数据格式

下一步是读出记录的数据。与之前博文中使用连接设备唯一不同之处在于打开SD卡而非设备。具体详情请查阅之前博文。

import glob
import os

ml = kvmlib.kvmlib()

# Our SD card is mounted under E:, so our LOG00000.KMF can
# be opened from here
filename = "E:\\LOG00000.KMF"

# Directory to put the resulting files in
resultDir = "result"

# Make sure the result directory exists and is empty
if os.path.isdir(resultDir):
    files = glob.glob(os.path.join(resultDir, "*"))
    for f in files:
        os.remove(f)
else:
    os.mkdir(resultDir)
os.chdir(resultDir)
 
# Open the SD card
# We have earlier verified that the SD card is using Lio Data Format v5.0
# and we should use kvmDEVICE_MHYDRA_EXT as the deviceType
ml.kmfOpen(filename, deviceType=kvmlib.kvmDEVICE_MHYDRA_EXT)
  
# Read number of recorded logfiles
fileCount = ml.logFileGetCount()
print "Found %d file%s on card:" % (fileCount,
                                    "s" if fileCount > 1 else "")

# Loop through all logfiles and write their contents to .kme50 files
for fileIndx in range(fileCount):
    eventCount = ml.logFileMount(fileIndx)
    print "\tFile %3d: %10d events" % (fileIndx, eventCount)
    logEvent = ml.logFileReadEventLogFormat()
 
    # The first logEvent contains device information
    memoEvent = logEvent.createMemoEvent()
    sn = memoEvent.serialNumber
    ean_lo = memoEvent.eanLo
    ean_sn = "%05x-%x_%d" % ((ean_lo >> 4) & 0xfffff, ean_lo & 0xf, sn)

    # Add EAN and serial number info to filename
    logfileName = "log_%s_%d.kme50" % (ean_sn, fileIndx)
    ml.kmeCreateFile(logfileName, kvmlib.kvmFILE_KME50)
    while logEvent is not None:
        # Write event to stdout
        print logEvent
        ml.kmeWriteEvent(logEvent)
        # Read next event
        logEvent = ml.logFileReadEventLogFormat()
    ml.kmeCloseFile()
  
# Delete all logfiles
ml.logFileDeleteAll()
  
# Close device
ml.close()

列表21:从SD卡读取记录的数据并保存至.kme50文件

4.4 从SD卡读取配置

还剩最后一件事:如何读回我们之前使用Windows安装点置于SD卡上的压缩配置。

import glob
import os
import shutil

# Our SD card is mounted under E:, so our LOG00000.KMF can
# be opened from here
filename = "E:\\LOG00000.KMF"

for file in glob.glob(os.path.join(os.path.dirname(filename), "*")):
    if(os.path.splitext(file)[1].lower() == '.kmf'
       or file.lower() == 'param.lif'
       or file.lower() == 'database.bin'):
        print "Skipping %s" % file
    else:
        print "Copying %s" % file
        shutil.copy(file, ".")

列表22:从SD卡复制所有用户文件

Copying E:\\PARAM.LIF
Skipping E:\\LOG00000.KMF
Skipping E:\\LOG00001.KMF
Skipping E:\\LOG00002.KMF
Skipping E:\\LOG00003.KMF
Skipping E:\\LOG00004.KMF
Skipping E:\\LOG00005.KMF
Copying E:\\DATABASE.BIN
Copying E:\\config.zip

至此,该运行程序的所有输出都已放入结果文件目录内。

d:\temp\blog>dir result
 Volume in drive D is HDD
 Volume Serial Number is 26E3-B474

 Directory of d:\temp\blog\result

2016-02-22 16:06     <DIR>          .
2016-02-22 16:06     <DIR>          ..
2016-02-22 16:06              2 406 CONFIG.ZIP
2016-02-22 16:06         10 002 432 DATABASE.BIN
2016-02-22 16:06             40 308 PARAM.LIF
              3 File(s)      10 045 146 bytes
              2 Dir(s)   961 850 183 680 bytes free

d:\temp\blog>More?

以上就是全部的文章内容,希望该文章系列能够帮你了解到kvmlib的更多知识,当管理Kvaser记录仪设备时,让你了解程式库的具体运用。

脚注

1 Kvaser Memorator配置工具的默认安装位置为:

C:\Program Files (x86)\Kvaser\MemoratorConfigTool\mhydraformat.exe

2 我们只为容器文件的第一个日志文件提供文件名,因为其余的将紧跟在卡上的第一个文件之后。

Author Image

Magnus Carlsson

Margus Carlsson是Kvaser AB公司的软件开发人员,从2007年以来深度参与了Kvaser固件和软件的开发。他还为Kvaser的技术博客撰写了许多用流行的Python语言编写应用程序的文章。