DSView源码阅读笔记(持续更新中···)

6 篇文章 0 订阅
2 篇文章 0 订阅

一、DSView源码阅读笔记

主线任务
将源码成功编译运行
提取示波器功能代码
添加示波器通道数量
找到接收数据部分源码
在win平台上使用qt开发环境进行代码重构
支线任务

以下笔记内容部分是猜测内容

DSView\

pv:

mainwindow.cpp:

​ void MainWindow::device_detach();//设备分离

​ void MainWindow::device_attach();//设备连接

​ void MainWindow::capture_state_changed(int state)//捕获状态改变

​ bool MainWindow::load_session_json(QJsonDocument json, bool file_dev);//

sigsession.h:
storesession.cpp:

注释部分代码,运行测试,结果显示逻辑分析仪功能下的波形显示一条直线

将读取到的一段数据存储在一个缓冲区,显示界面再读取缓冲区数据,将其显示在界面上

session

libsigrok4DSL\

dsdevice.c:

​ SR_API int sr_dev_probe_name_set(const struct sr_dev_inst *sdi,

​ int probenum, const char *name); //设置指定设备探针的名字


​ SR_API int sr_dev_probe_enable(const struct sr_dev_inst *sdi, int probenum,

​ gboolean state); //启动或者关闭指定设备 的探针


SR_API int sr_dev_trigger_set(const struct sr_dev_inst *sdi, uint16_t probenum,

​ const char *trigger); //向指定的设备(和指定的探针)添加一个触发器,如 果 这个设备上指定的探针已经有一个触发器,它将静态地被替换


​ #ifdef HAVE_LIBUSB_1_0

​ SR_PRIV struct sr_usb_dev_inst *sr_usb_dev_inst_new(uint8_t bus,

​ uint8_t address, struct libusb_device_handle *hdl);

​ SR_PRIV void sr_usb_dev_inst_free(struct sr_usb_dev_inst *usb);


​ SR_PRIV struct sr_serial_dev_inst *sr_serial_dev_inst_new(const char *port,

​ const char *serialcomm);

​ SR_PRIV void sr_serial_dev_inst_free(struct sr_serial_dev_inst *serial);

​ //这两个参数(pathname , serialcomm)都被复制到新分配的字符串中,并由sr_serial_dev_inst_free()自动释放。

hwdriver.c:(硬件驱动程序)
libsigrok.h:

​ 关于如何连接到设备的规范。结合SR_CONF_SERIALCOMM,这是一个串行端口对操作系统有意义的形式(例如,/dev/ttyS0)。


libsigrokdecode4DSL\

二、涉及的知识

串口通讯

读取串口数据并处理(C语言)

读取串口数据程序的编程逻辑示意图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lOvTsvf1-1629789294072)(C:\Users\jingwenwei\AppData\Roaming\Typora\typora-user-images\image-20210823133253144.png)]

c程序

//main.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "openDev.h"

int main()
{
    int fd;
    int nread;
    char buffer[MAX_BUFF_SIZE];

    serial_parse phandle;
    phandle.rxbuffsize = 0;

    char *dev_name = "/dev/ttyUSB0";//根据实际情况选择串口

    while(1) 
    {  
        fd = OpenDev(dev_name); //打开串口 

        if(fd>0)
        {
            set_speed(fd,9600); //设置波特率
            printf("set speed success!\n");
        }     
        else  
        { 
            printf("Can't Open Serial Port!\n"); 
            sleep(1);  //休眠1s
            continue; 
        } 
        break;
    }

    if(set_Parity(fd,8,1,'N')==FALSE) //设置校验位 
    {
        printf("Set Parity Error\n"); 
        exit(1);
    }
    else
    {
        printf("Set Parity Success!\n"); 
    }

    while(1) 
    { 
        usleep(10000);  //休眠1ms
        nread = read(fd , phandle.buff + phandle.rxbuffsize, MAX_BUFF_SIZE - phandle.rxbuffsize);
        phandle.rxbuffsize += nread;
        phandle.buff[phandle.rxbuffsize] = '\0';
		/*
		处理 phandle.buff
		*/
	}

	return 0;
}

//openDev.h
#ifndef OPENDEV_H
#define OPENDEV_H

#include <math.h>

#define TRUE 1
#define FALSE 0
#define MAX_BUFF_SIZE (256)

typedef struct _serial_parse
{
    char buff[MAX_BUFF_SIZE];
    int rxbuffsize;
}serial_parse;

int OpenDev(char *Dev);
void set_speed(int fd, int speed);
int set_Parity(int fd,int databits,int stopbits,int parity);

#endif


//openDev.c
#include <termios.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "openDev.h"

#define TRUE 1
#define FALSE 0
 
int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = {38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300, };
 
int OpenDev(char *Dev)
{
  int fd = open(Dev,O_RDWR | O_NOCTTY | O_NONBLOCK);
  if(-1 == fd)
    {
      perror("Can't Open Serial PPPPort");
      return -1;
    } 
  else 
    {
      printf("Open com success!\n");
      return fd;
    }
} 

void set_speed(int fd, int speed)
{ 
  int i; 
  int status; 
  struct termios Opt;
 tcgetattr(fd, &Opt); 
  for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++)
   { 
      if (speed == name_arr[i]) 
        { 
          tcflush(fd, TCIOFLUSH); 
          cfsetispeed(&Opt, speed_arr[i]);
         cfsetospeed(&Opt, speed_arr[i]);
         status = tcsetattr(fd, TCSANOW, &Opt); 
          if (status != 0) perror("tcsetattr fd1");
         return;
       } 
    tcflush(fd,TCIOFLUSH);
    }
}

int set_Parity(int fd,int databits,int stopbits,int parity) 
{ 
  struct termios options; 
  if ( tcgetattr( fd,&options) != 0) 
  {
   perror("SetupSerial 1");
   return(FALSE);
 } 
  bzero(&options,sizeof(options)); 
  options.c_cflag |= CLOCAL | CREAD;
 options.c_cflag &= ~CSIZE; 
  switch (databits) 
  { 
    case 7: 
    options.c_cflag |= CS7;
   break;
   case 8:
   options.c_cflag |= CS8;
   break; 
    default: fprintf(stderr,"Unsupported data size\n");
   return (FALSE); 
  } 
  switch (parity) 
  {
   case 'n': 
    case 'N':
   options.c_cflag &= ~PARENB;
   options.c_iflag &= ~INPCK; 
    break; 
    case 'o':
   case 'O': 
    options.c_cflag |= (PARODD | PARENB);
   options.c_iflag |= (INPCK | ISTRIP); 
    break; 
    case 'e': 
    case 'E': 
    options.c_cflag |= PARENB;
   options.c_cflag &= ~PARODD; 
    options.c_iflag |= (INPCK | ISTRIP); 
    break; 
    case 'S': 
    case 's': 
    options.c_cflag &= ~PARENB; 
    options.c_cflag &= ~CSTOPB;
   break;
   default: fprintf(stderr,"Unsupported parity\n"); 
   return (FALSE); 
  } 
  switch (stopbits)
 { 
    case 1:
   options.c_cflag &= ~CSTOPB; 
    break; 
    case 2: 
    options.c_cflag |= CSTOPB;
   break; 
    default: fprintf(stderr,"Unsupported stop bits\n"); 
    return (FALSE); 
    } 
    if (parity != 'n') 
    options.c_iflag |= INPCK; 
    options.c_cc[VTIME] = 0;
   options.c_cc[VMIN] = 0;
   tcflush(fd,TCIFLUSH); 
    if (tcsetattr(fd,TCSANOW,&options) != 0)
   {  
        perror("SetupSerial 3"); 
        return (FALSE);
   } 
    return (TRUE);
}

snapshoot快照

qt信号与槽函数

DSO数字存储示波器

两个重要参数:带宽采样率

Oscilloscopes

这个页面记录了配置键是编写控制示波器的libsigrok前端所需的各种其他信息。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0pNzFEr5-1629789294074)(C:\Users\jingwenwei\AppData\Roaming\Typora\typora-user-images\image-20210816133721796.png)]

Frame-based

通常示波器的工作方式是触发被测信号或外部触发信号。然后,该设备测量尽可能多的它的内部缓冲区可以容纳。当缓冲区满时,设备停止测量并将其缓冲区发送到libsigrok驱动程序。这个传输代表了一帧数据的价值。驱动程序将这些数据转换为libsigrok内部模拟格式,然后像这样发送到前端:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1nHe3fME-1629789294075)(C:\Users\jingwenwei\AppData\Roaming\Typora\typora-user-images\image-20210816133747346.png)]

示波器然后重新开始采集,有时是在驱动程序刺激之后。因此,从示波器接收到的数据不是连续的从一帧到下一帧:在这之间有一个周期,该设备不进行测量。

Streaming

有些设备可以作为连续流示波器,不涉及帧。值得注意的是,具有模拟前端的基于fx2的设备,如Nexus-Computing ossciprime,就是这样工作的。

Config keys

一个用于示波器的libsigrok驱动程序实现了以下配置键的全部或部分。

SR_CONF_OSCILLOSCOPE

表示一种可以充当示波器的设备,即随时间测量一个或多个模拟通道上的电压,并将这些测量值作为模拟值发送到前端。

SR_CONF_LIMIT_FRAMES

基于帧的示波器实现了这个关键帧集,即在SR_DF_FRAME_BEGIN和SR_DF_FRAME_END包之间要捕获和发送的帧数。

它只用于设置这个值;获取它只会返回先前设置的值。默认值为0,表示连续抓取帧,直到被告知停止。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hNQ8jQB4-1629789294077)(C:\Users\jingwenwei\AppData\Roaming\Typora\typora-user-images\image-20210816134428465.png)]

SR_CONF_NUM_TIMEBASE

示波器在其水平(时间)轴上的分割数。这对应于设备显示的方格上的垂直线所标记的区域。即使在无头示波器上,这个概念仍然存在;例如,如果没有这个数字,SR_CONF_TIMEBASE设置就没有意义。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RQh6PpV5-1629789294077)(C:\Users\jingwenwei\AppData\Roaming\Typora\typora-user-images\image-20210816134513938.png)]

SR_CONF_TIMEBASE

采集过程中单个水平(时间)分割采样的持续时间。分割的数量由SR_CONF_NUM_TIMEBASE返回,因此将这个数字乘以这个持续时间就得到了对单个帧的有效采样的度量。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hZ1s29Up-1629789294078)(C:\Users\jingwenwei\AppData\Roaming\Typora\typora-user-images\image-20210816134602330.png)]

告知停止。

[外链图片转存中…(img-hNQ8jQB4-1629789294077)]

SR_CONF_NUM_TIMEBASE

示波器在其水平(时间)轴上的分割数。这对应于设备显示的方格上的垂直线所标记的区域。即使在无头示波器上,这个概念仍然存在;例如,如果没有这个数字,SR_CONF_TIMEBASE设置就没有意义。

[外链图片转存中…(img-RQh6PpV5-1629789294077)]

SR_CONF_TIMEBASE

采集过程中单个水平(时间)分割采样的持续时间。分割的数量由SR_CONF_NUM_TIMEBASE返回,因此将这个数字乘以这个持续时间就得到了对单个帧的有效采样的度量。

[外链图片转存中…(img-hZ1s29Up-1629789294078)]

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Loafer_W

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值