Saleae SDK 二次开发

一、前言

       最近这家公司正在开发一款新产品,经常需要通过Saleae 逻辑分析仪抓取二进制数据,然后经过解析,再转换成16进制,再根据通讯协议对数据进行相关处理。逻辑分析仪官方自带解码器,所以解析二进制波形非常简单。但是,对于一些特定的编码方式有非常多种,所以没有官方提供相应的解码器,因此需要手动计算每个波形的,然后再转换成对应的二进制位,再将每个bit 转换为16进制byte ,所以,这非常的麻烦和累,并且非常容易出错。

         所以,要根据逻辑分析仪的官方提供的SDK ,进行二次开发,开发我们需要的自定义解码器,翻遍度娘发现相关资料少之又少,几乎没有讲解这个该从何做起。由于之前完全没有接触过这方面的东西,因此,有了这篇文章。记录我是怎么从0 开始,编写一个自定义PPM解码器。

二、相关资料

1. Saleae 逻辑分析仪

1.1 逻辑分析仪

是分析数字系统逻辑关系的仪器。逻辑分析仪是属于数据域测试仪器中的一种总线分析仪,即以总线(多线)概念为基础,同时对多条数据线上的数据流进行观察和测试的仪器,这种仪器对复杂的数字系统的测试和分析十分有效。逻辑分析仪是利用时钟从测试设备上采集和显示数字信号的仪器,最主要作用在于时序判定。由于逻辑分析仪不像示波器那样有许多电压等级,通常只显示两个电压(逻辑1和0),因此设定了参考电压后,逻辑分析仪将被测信号通过比较器进行判定,高于参考电压者为High,低于参考电压者为Low,在High与 Low之间形成数字波形。

1.2 采样深度

即对被测信号一次采集的样点总数。它直接决定了一次采样所能采集到的数据量的多少,显然深度越大,一次采集的数据量越大。

1.3 采样率(Sample Rate)

采样率也称采样速率,即对被测信号进行采样的频率,也就是每秒所采集的样点数。它直接决定了一次采样结果的时间精度,采样率越高,时间精度越高。一次采样结果的时间精度就等于“1/采样率”,即一个采样周期。

1.4 采样时间

一次采样过程所持续的时间等于“采样深度÷采样率”,即:

采样时间 = 采样深度 / 采样率.

三、Saleae SDK 开发

3.1 官网介绍:

The Saleae Analyzer SDK lets you make your own custom protocol analyzers. The framework is very flexible. You can do everything we can do (we use the same SDK). You'll be creating a shared library (.dll, .so, or .dylib) that will be loaded by the Logic software as a plugin.

While there are many advantages to providing the SDK in this format, implementation of a custom protocol will probably take an experienced C++ developer at least a full day, and possibly up to a week, to complete. You will probably want to have had considerable programming experience, probably significant C++ experience, before taking it on.

扫描二维码关注公众号,回复: 13466566 查看本文章

That said, you can get away with implementing only a small part of the full capability of the analyzer. For example, you could have only one setting (the input channel(s) to use), and you could skip creating simulated data to test against, not bothering to provide for data export or tabular display.

Further, by default, you will start out with a fully featured and maximally simple analyzer—SimpleSerialAnalyzer. The documentation will walk you through how to modify it to suit your needs, as well as what parts can be left empty.

SDK 官网地址: Protocol Analyzer SDK   

上面简单的意思是说,

Saleae Analyzer SDK 可以制作自己的自定义分析器Analyzer。该框架非常灵活,官方的分析器也是使用相同的 SDK编写出来的。解码器Analyer 是共享动态库(.dll、.so 或 .dylib),该库将由 Logic 软件以插件形式加载。
自定义协议的实现可能需要有经验的 C++ 开发经验,一开始不了解SDK 和 SDK中的API, 可以只实现Analyer 的一小部分功能,然后再进行复杂的扩展。
可以从官网提供的,功能齐全且极其简单的分析器开始学习——SimpleSerialAnalyzer
并且有文档将指导如何修改它以满足需要.
最新 SDK 版本下载地址:

2. 工程构建

2. 1. 根据官网指南,总的分为3步

a. 创建自定义分析器工程   b. 构建自定义分析器   c. 编译和调试自定义分析器

2.2.1 创建自定义分析器工程, 参考官网:

 Setup - Analyzer SDK 
2.2.2 构建自定义分析器    参考:

官网链接 -  Build - Analyzer SDK   

 Build - Analyzer SDK 
2.2.3 编译和调试自定义解密器 参考官网:

Debug - Analyzer SDK 

上面每个步骤官网都有详细描述,需要注意的是,构建分析器时,根据不同平台(x86 和 x64 ),使用不同配置.

关于调试自定义分析器,根据官网提示,在Logic v1.1.18 之后的软件是不支持将自定义分析器附件到软件上,
即,v1.1.18 之后的软件在开发自定义分析器的时候,无法进行断点调试。

如果实在需要进行断点调试,必须要是旧版的 1.1.14 SDK + Logic v1.1.18 Windows 32 独立版本 才能进行断点调试。
注意:  Logic v1.1.18 是32位, 只能调试x86 版本的dll, 并且只能对 1.1.14 SDK 配合进行断点调试,不能用于最新版的sdkti调试如果连接最新版的SDK, 则会提示  "Unable to 'LoadLibrary' on dll ... is not a valid Win32 application"

旧版 1.1.14 SDK 下载地址:
Saleae Analyzer SDK 1.1.14 (包括用户指南)  
​Saleae Analyzer Source Code 1.1.14 (包含所有分析器代码) 

确保SDK只编译 32 位,因为 1.1.14 SDK 是在 Saleae 开始针对 64 位 Windows 之前发布的。
这也是为什么需要 1.1.18 软件的 32 位独立版本的原因。

因此,需要进行SDK 断点调试,只能使用 旧版的 1.1.14 SDK + Logic v1.1.18 Windows 32 独立版本.

3. 工程目录说明(与官方Sample 例程说明)

3.1 AnalyzerSDK:

存放 Saleae SDK 的目录,直接在官网下载后,将Saleae SDK 目录下所有文件拷贝到该目录即可。

3.2 docs

  存放Saleae Analyzer SDK 开发文档 等。

 3.3 LegacyAnalyzerSDK

 旧版SDK 存放目录

3.4 source

工程源代码存放目录

4. Saleae 相关类

4.1 SimpleSerialAnalyzer.cpp 和 SimpleSerialAnalyzer.h

这两个文件主要包含分析器主要部分,由分析器派生的类是分析器的核心。这里个类,可以实时分析和解析波形图,并生成需要的结果.

4.1.1 SimpleSerialAnalyzer API 说明

4.1.1.1 void {YourName}Analyzer::WorkerThread()

WorkThread这个函数是所有东西的关键,在这里你将获取波形数据,开始解码,并且保存.

4.1.1.2 bool {YourName}Analyzer::NeedsRerun()

一般来说,只要在这个函数中返回false.

4.1.1.3 U32 {YourName}Analyzer::GenerateSimulationData( U64 minimum_sample_index, U32

device_sample_rate, SimulationChannelDescriptor** simulation_channels )

这个函数主要用于,被调用来获得模拟数据的函数, 主要在旧版 1.1.14 和 Logic 1.1.18 附加调试时使用,主要调用SimpleSerialSimulationDataGenerator 这个类的函数,为WorkThread, 在附加调试时,提供模拟数据, 其中模拟波形数据是人为生成的.

4.1.1.4 U32 SerialAnalyzer::GetMinimumSampleRateHz()

提示用户采样需要的最小采样速率,一般根据实际需要返回.

4.1.1.5 const char* {YourName}Analyzer::GetAnalyzerName() const

需要返回,在“添加分析工具”下拉列表中看到的名称.

4.1.1.6 const char* GetAnalyzerName()

GetAnalyzerName()  返回一样的字符串即可.

4.1.1.7 Analyzer* CreateAnalyzer()

返回一个指向分析器派生类的新实例的指针.

4.1.1.8 void DestroyAnalyzer( Analyzer* analyzer )

只需在所提供的指针上调用删除项即可.

4.1.1.9 void SetupResults()

设置结果集,其中,

void SimpleSerialAnalyzer::SetupResults()
{
	//1. 创建一个分析器结果集对象, 并将用户的设置参数传入
	mResults.reset( new SimpleSerialAnalyzerResults( this, mSettings.get() ) );
	
	//2. 将结果集对象放置到 分析器对象中
	SetAnalyzerResults( mResults.get() );
	
	//3. 设置需要在哪个通道上显示通过气泡显示数据
	mResults->AddChannelBubblesWillAppearOn( mSettings->mInputChannel );
}

4.1.1.10 AnalyzerChannelData* GetAnalyzerChannelData( Channel inputChannel)

获取指定通道的波形数据本身,就是采样的数据.

4.1.1.11 U32 GetSampleRate(void)

获取当前逻辑分析仪采样速率.

4.1.1.12  BitState 位状态

在Saleae SDK 中,经常使用的一种类型,表示一个通道的口号状态,状态有两个,  BIT_LOW or BIT_HIGH

BIT_LOW  表示下降沿, 电平变化由 高 -> 低

BIT_HIGH  表示上升沿,电平变化由 低 -> 高。

4.1.2 AnalyzerChannelData

解析选定通道采集到的数据,AnalyzerChannelData 是一个可以访问Saleae采集到数据的类。Saleae 以序列化数据流的形式提供数据,数据的访问不会“随机访问”所保存的数据中的任何一个bit。相反,而是从数据的开始按顺序访问,并随着访问更多可用的数据而继续前进(Advance)或移动,直到一轮数据访问完毕。

4.1.2.1 AnalyzerChannelData - State

AnalyzerChannelData 类相关API

4.1.2.2 U64 GetSampleNumber(void)

获取当前采样数据的位置

4.1.2.3 BitState GetBitState(void)

获取当前某个位置对应的电平状态

AnalyzerChannelData 是每个采样点都有一个Number记录着表示前进(Advance)或移动的位置,要在进行数据流访问时,想知道当前在整个数据流的位置时,可以使用 GetSampleNumber() 这个函数, 需要获取当前位置对应的电平,可以使用GetBitState() 函数。

4.1.3 AnalyzerChannelData – Basic Traversal 

采样数据流的基本遍历访问,在数据流中前进或移动时,需要用到一些API.

4.1.3.1 U32 Advance( U32 num_samples )

这个函数作用时在整个样本数据流中前进移动,前进移动num_samples个样本,此函数将返回输高低电平切换次数(从高到低,或从低到高).

这样子解释可能晦涩难懂,我刚才开始也是难以理解。简单来说,Saleae 逻辑分析仪采集到的数据是数据流来的,每个采样点对应一个高低电平信号,并且每个采样点,都有sample 记录着 它在数据流中的位置。而这个位置是可以向前移动的,怎么样移动呢? 就是调用这个Advance 这个函数实现,移动样本数量(即: 采样点的个数) 就是 num_samples 这个参数。

4.1.3.2 U32 AdvanceToAbsPosition( U64 sample_number )

函数的功能是,前进移动到采样到数据流中的某个绝对位置,它还将返回在移动过程中更改的输入的次数。这个函数是移动到指定样本的位置,sample_number 是样本编号,即样本的地址,表示第几个样本。

4.1.3.3 void AdvanceToNextEdge()

移动到下一个边沿, 即电平变化的位置,此时可以通过GetSampleNumber(), 获取当前进到样本的位置.

4.1.4 AnalyzerChannelData – Advanced Traversal (looking ahead without moving)

高级遍历样本数据API.

4.1.4.1 U64 GetSampleOfNextEdge(void)

获取下一个边沿变化的样本位置,此函数不会移动在流中的位置。记住,不能在流中向后移动,所以有时不移动就看到前面的东西是非常重要的。

4.1.4.2 bool WouldAdvancingCauseTransition( U32 num_samples )

移动num_samples 个样本,函数不会移动在流中的位置。在这里,可以发现向前移动给定数量的样本是否会导致位状态(低或高)发生变化。

4.1.4.3 bool WouldAdvancingToAbsPositionCauseTransition( U64 sample_number );

移动到指定位置,函数不会移动在流中的位置。

4.1.5 Filling in and saving Frames 

上面讲述的是怎么解析数据,这里讲述如何保存数据,在Saleae 保存数据的基本单位是Frame,每个数据保存都在Frame  实例化对象中。

4.1.5.1 Frame frame;

frame.mStartingSampleInclusive;   //记录帧在样本流中的开始位置

frame.mEndingSampleInclusive ; //记录帧在样本流中的结束位置

frame.mData1;  //帧有效数据1

//frame.mData2;  //帧有效数据2

//frame.mType               //数据类型  

frame.mFlags ;                //标识

一般的,在帧解析中,一般mData1 和 mData2 用来保存有效数据,不一定所有都要用到,mType 和 mFlag 标识帧的类型,这两个都可以自定义,mStartingSampleInclusive 和 mEndingSampleInclusive 这两个记录在样本流中的位置,主要用于当需要在Logic 软件显示数据时,数据气泡的开始位置和结束位置.  而且, mStartingSampleInclusive  必须大于 mEndingSampleInclusive。

4.1.5.2 void AddMarker( U64 sample_number, MarkerType marker_type, Channel& channel )

主要用于标记帧的位置,或者在数据流中添加标记。

 

4.2 SimpleSerialAnalyzerSettings.cpp 和 SimpleSerialAnalyzerSettings.h

这个使用在Logic 软件中提供给用户界面上,设置分析器需要用到的参数。至少有一个参数,用于选定需要输入数据的通道。

变量类型可以是任何你喜欢的类型——字符串、双变量、int、枚举等等。请注意,这些变量需要序列化(稍后保存到文件),因此如果有疑问,请坚持使用简单类型(而不是自定义类或结构)。SDK提供了一种序列化和存储变量的方法。

4.2.1 SimpleSerialAnalyzerSettingsAPI 说明

关于各个API 这个很简单,可以去看官方说明文档,不需要过多解释。

4.3 SimulationDataGenerator.cpp 和 SimulationDataGenerator.h

这个类主要生成仿真数据,即模拟逻辑分析仪接收的数据。生成可控的、可预测的波形来测试WorkThread中的分析器代码。通常应该使模拟数据与用户设置匹配,因此可以在各种预期条件下进行测试。此外,模拟数据为最终用户提供了一个在使用分析器时会发生什么的示例,以及波形应该是什么样的示例。

值得注意的是,我在调试代码过程中,多次实验和总结:

这个类只有在Saleae SDK 版本位 1.1.14 和 Logic.exe 1.1.18 才能用到,在新版的由于新版的SDK 不支持 Logic 1.1.18 的在线调试,所以不能使用,而新版本的Logic.exe 不支持SDK附加调试,因此。只能用于 Saleae SDK 1.1.14 和 Logic 1.1.18 win32 才能使用,在x64 都不能使用。

如,模拟波形

4.3.1 一些概念

4.3.1.1 Sample Rate (samples per second)

采样频率:采样率是指数据每秒的样本数量。通常,它指的是我们采样数据的速度,但对于模拟数据,它指的是我们生成样本数据的速度。

4.3.1.2 Sample Number

样本编号,这是绝对样编号,从样本0开始。当采样数据收集开始时,收集的第一个样本是样本号0。下一个采集的样本是样本1,以此类推。这在模拟数据中也是如此。提供的第一个样本是样本编号0,以此类推。

4.3.1.3 U32 GenerateSimulationData( U64 largest_sample_requested, U32 sample_rate, SimulationChannelDescriptor** simulation_channel )

这个API 主要由Logic.exe 调用,Logic.exe 通过反复调用此函数以请求更多的模拟波形数据。因此,用户需要在重写这个函数,在函数里面生成自定义分析器Analyzer 需要的样本数据,

值得注意的是,这个函数虽然由Logic.exe 调用, 但是也只有在调试模式时用得到。 意思是,如果对自己WorkThread 写的自定义分析器代码有信心,不需要模拟波形调试,这个方法可以空着。

在新版的Logic.exe 是不允许进行附件调试的,也就是,这个函数一般用户 Saleae SDK 1.1.14 和 Logic 1.1.18 一起调试时用到。

4.4 SimulationChannelDescriptor

模拟通道描述符,这类使用于定义访问单个通道的模拟样本数据,以及它的波形。

通道的初始状态(一般为BIT_LOW,或BIT_HIGH)。

通道的初始位状态永远不会改变,因此,一个特定样本数的状态(高或低)可以通过知道它切换到该点的次数(偶数或奇数)来确定。

换句话说:在一开始,指定了模拟通道的初始状态(BIT_LOW或BIT_HIGH),这是样本号(Sample Numer)为0的状态。接着,可以继续移动和向前(Advance)一些样本。

例如,移动或则前进20个样本, 即:Advance(20) 然后,我们切换通道(低变高,高变低, 如:Transition 或 TransitionIfNeeded) ,然后我们继续向前(Advance)一些。

这次可能有100个样本或则N个样本,然后我们再次切换状态,然后我们再次前进,然后我们再次切换,等等。

值得注意的是:

a. 前进(Advance) 多少个样本,是根据用户使用协议决定的,而不是固定需要多少个样本。 

b. 切换状态是指BitState 上面也讲述过, BIT_LOW 表示下降沿, BIT_HIGH 表示上升沿。

4.4.1 SimulationChannelDescriptor API 说明

4.4.1.1 void Advance( U32 num_samples_to_advance );

这个函数主要在模拟波形中前进的方式,即在样本流中移动,这函数会改变样本流的位置。在SimulationChannelDescriptor对象内部,对象会跟踪并记录其样本号Sample Number是什么, 即 Sample Number 会跟着改变。

样本编号固定从0开始。

例如:

Advance(10);

Advance(20);

Advance(30);

则 Sample Number 从 0 前进或移动到 10 + 20 + 30 = 60, 即: 上面成功调用3次函数后,当前样本编号为 60.

4.4.1.2 void Transition();

这函数切换通道的BitState, 将通道当前的BitState, 由BIT_LOW变成了BIT_HIGH,BIT_HIGH变成了BIT_LOW。

切换后,当前为新的BitState (BIT_LOW或BIT_HIGH),之后的所有Sample Number BitState 也将成为新的BitState,直到我们再次调用Transition()切换。

4.4.1.3 void TransitionIfNeeded( BitState bit_state );

一般的用户不会主动跟踪当前的BitState,但是, 它在每次调用Transition 时都会切换,

使用Transition,每次需要调用GetCurrentBitState()检查当前的BitState,并且只有在当前的BitState与我们需要的BitState不同时才会进行Transition。

换句话说,“如果改变这个bit_state,我们还没有”。

因此,官方提供了,TransitionIfNeeded 这个函数是不需要用户知道或跟踪当前Sample Number 的BitState 是什么,只有当前BitState 与 需要切换的BitState 不同

才会切换,如果一样则保持。

4.4.1.4 BitState GetCurrentBitState();

这个函数允许直接询问当前Sample Number的BitState是什么.

4.4.1.5 U64 GetCurrentSampleNumber();

这个函数允许您询问当前的样本编号Sample Number是什么.

4.5SimpleSerialAnalyzerResults.cpp 和 SimpleSerialAnalyzerResults.h

这个类主要是用于当自定义分析器Analyzer, 根据协议成功解析完通道的样本数据后,如何在Logic.exe 中显示解析后的样本数据。

4.5.1 SimpleSerialAnalyzerResults API 说明

4.5.1.1 void GenerateBubbleText( U64 frame_index, Channel& channel,

DisplayBase display_base )

这个函数主要用于生成泡泡文本,将解码后的数据文本放入气泡中显示的Logic屏幕上。

气泡可以显示不同长度的字符串,这取决于有多少可用的空间。

最简单的可能简单地表示内容的类型(例如数据的D”),较长的可能表示完整的数字(“0xFF01”)

需要注意的是,在添加任何字符串结果之前,始终调用ClearResultStrings() 清除上一次的显示。

连接多个字符串,多次调用AddResultString() 即可。

4.5.1.2 void GenerateExportFile( const char* file, DisplayBase display_base, U32 export_type_user_id )

这个函数主要用于,当用户试图将分析器结果导出到文件中时,将调用此函数。

4.5.1.3 void SerialAnalyzerResults::GenerateFrameTabularText( U64 frame_index, DisplayBase display_base )

这个函数用于生成Logic.exe 框架表格文本, 添加文本,调用AddTabularText(),清除文本,调用 ClearTabularText().

如,解析后数据在1.2x 和 2.x 版本数据

上面讲述了各个API 使用,应该足够使用,更多可以参考官方提供的说明文档,

关于调试,需要注意的是,

1. Logic 1.1.18 使用使用32位分析器, Logic 1.2 以上版本,根据安装时的系统不同,需要的插件也不同,即x64 只能使用 64位版本分析器,x86 使用32位版本分析器。

同理,Logic 2.x 版本也是。

2. 无论那个 Logic.exe 都需要在指定分析器插件目录后,再重启软件才能加载插件。

3. 在使用Logic 1.1.18 需要设置加载自定义分析器插件时,在某些系统可能找不到设置按钮。因为开启玻璃特效,所以被隐藏了。在win10 就是被隐藏掉。

 设置按钮位于右上角

 

可以取消玻璃设置效果,如下图

 

 终于写完了。。。。。。。。。。。。。。。

/**
 *         ┏┓   ┏┓+ +
 *        ┏┛┻━━━┛┻┓ + +
 *        ┃       ┃
 *        ┃   ━   ┃ ++ + + +
 *        ████━████ ┃+
 *        ┃       ┃ +
 *        ┃   ┻   ┃
 *        ┃       ┃ + +
 *        ┗━┓   ┏━┛
 *          ┃   ┃
 *          ┃   ┃ + + + +
 *          ┃   ┃    Code is far away from bug with the animal protecting
 *          ┃   ┃ +     神兽保佑,代码无bug
 *          ┃   ┃
 *          ┃   ┃  +
 *          ┃    ┗━━━┓ + +
 *          ┃        ┣┓
 *          ┃        ┏┛
 *          ┗┓┓┏━┳┓┏┛ + + + +
 *           ┃┫┫ ┃┫┫
 *           ┗┻┛ ┗┻┛+ + + +
 *
 * @author chenxi
 * @date 2021-11-29 22:05:41
 */

猜你喜欢

转载自blog.csdn.net/gd6321374/article/details/121479807
今日推荐