自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(93)
  • 收藏
  • 关注

原创 程序的二进制布局

真正的程序员对自己所写的程序的每个字节都有所把握,虽然用一些OOP语言进行开发时,我们几乎不可能做到这一点,但我们还是应该对我们程序的二进制布局有个整体把握。下面,我将参考《程序员的自我修养》逐字节分析两个"程序",一个是目标文件,一个是可执行文件。1 目标文件分析...

2021-06-11 11:25:43 484 2

原创 二叉树的遍历

1 递归遍历typedef struct _BiTNode{ int data; struct BiTNode* lchild; struct BiTNode* rchild;} BiTNode, *BiTree;//前序遍历 根左右void preOrder(BiTree T){ if(T == nullptr) return; cout << T->data << endl; preOrder(T->lchild); preOrder(

2021-06-04 10:14:36 200

原创 常见查找算法

1 常见查找概念查找指根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素。查找表是由同一类型的数据元素或记录构成的集合。关键字是数据元素中某个数据项的值,又称为键值,主关键字可以唯一地标识一个记录,次关键字可以标识多个数据元素或记录。静态查找表:只做查找操作的查找表,可用线性表结构来组织数据。动态查找表:在查找的过程中同时插入查找表中不存在的数据元素,或者从查找表中删除已经存在的某个数据元素。可以用二叉排序树来组织数据。从逻辑上来说,查找所基于的数据结构是集合,集合中的记录之间没

2021-06-01 15:28:36 361

原创 常见排序算法

1 常见排序概念排序稳定性:假设关键字ki = kj,且在排序前的序列中ri领先于rj,如果排序后ri仍领先于rj,则称所用的排序算法为稳定的。若有可能使排序后rj领先于ri,则排序算法是不稳定的。内排序:在整个排序过程中,待排序的所有记录都被放置在内存中。外排序:排序过程中由于排序的记录个数太多,不能同时放置在内存中,整个排序过程需要在内外存之间多次交换数据才能进行。我们主要研究内排序,内排序排序算法性能受三方面影响(1)时间性能。内排序主要进行两种操作,比较和移动。(2)辅助空间。(3)

2021-05-31 17:18:48 129

原创 C++中的类型转换

c++除了能使用c语言的强制类型转换外,还新增了四种强制类型转换:static_cast、dynamic_cast、const_cast、reinterpret_cast,主要运用于继承关系类间的强制转化。新式转换较旧式转换更受欢迎。原因有二,一是新式转型较易辨别,能简化“找出类型系统在哪个地方被破坏”的过程;二是各转型动作的目标愈窄化,编译器愈能诊断出错误的运用。尽量少使用转型操作,尤其是dynamic_cast,耗时较高,会导致性能的下降,尽量使用其他方法替代。static_caststa.

2021-05-18 17:11:29 89

原创 C++的RAII机制

什么是RAIIRAII是Resource Acquisition Is Initialization的简称,是C++语言的一种管理资源、避免泄漏的惯用法。利用的就是C++构造的对象最终会被销毁的原则。RAII的做法是使用一个对象,在其构造时获取对应的资源,在对象生命期内控制对资源的访问,使之始终保持有效,最后在对象析构的时候,释放构造时获取的资源。我们也可以使用STL中的shared_ptr来完成RAII的思想,参考下面例子。为什么要使用RAII在计算机系统中,资源是数量有限且对系统正常运行具

2021-05-07 21:50:52 130

原创 STL库算法概览

1、 查找对象的算法下面的STL算法都在头文件algorithm中,命名空间为std。简单查找算法find(beg, end, val)find_if(beg, end, unaryPred)find_if_not(beg, end, unaryPred)count(beg, end, val)count_if(beg, end, val)查找重复值算法adjacent_find(beg, end)adjacent_find(beg, end, binaryPred)sear

2021-05-07 11:32:00 364

原创 ANSI C标准中的预定义宏

LINE:在源代码中插入当前源代码行号FILE:在源文件中插入当前源文件名FUNCTION:在源文件中插入当前函数名DATE:在源文件中插入当前的编译日期TIME:在源文件中插入当前编译时间STDC:当要求程序严格遵循ANSI C标准时该标识被赋值为1__cplusplus:当编写C++程序时该标识符被定义...

2021-03-29 11:13:29 140

原创 在ZYNQ ARM平台上交叉调试qt程序

环境说明: 交叉编译器为petalinux2018.3自带的arm-linux-gnueabihf-g++。QT库版本为5.9.1。1 在虚拟机安装gdb-multiarch sudo apt install gdb-multiarch2 下载Qt5.9.1的源码,然后交叉编译该源码并安装到某文件夹下。3 在Qt设置中添加新的Qt versions,如下图所示4 在Compilers中添加petalinux自带的交叉编译器arm-linux-gnueabihf-..

2021-03-02 14:11:08 1256

原创 c++在delete后要把指针赋值为nullptr

在C++中我们new了一个对象后,返回的是这个对象的指针,如QObject* pObject = new QObject();在使用完对象后,我们用delete删除这个对象,如delete pObject;如果我们没有在delete后将pObject赋值为nullptr,其实指针pObject是会指向之前的那个地址的,只是这个地址处的对象已经被析构了。所以如果我们用if(pObject)这样的条件来判断对象是否已被析构,其实是会有问题的。如果想要这样判断,我们可以在delete后将该指针赋值为nul.

2021-02-05 17:56:23 1792

原创 qt多线程编程之使用moveToThread

Qt有两种多线程的方法,其中一种是继承QThread的run函数,另外一种是把一个继承于QObject的类用moveToThread函数转移到一个QThread对象里。 Qt4.8之前都是使用继承QThread的run这种方法,但是Qt4.8之后,Qt官方建议使用第二种方法。1)用原始的QThread的started信号触发自定义的slot启动线程,而不是派生QThread的类重载run函数启动线程。将一个类派生自QObject,然后实现所有的signal/slot,然后通过调用movetothrea.

2021-02-05 16:48:07 797 2

原创 Qt用共享内存代替信号与槽机制

信号与槽在使用时会涉及内存间的数据拷贝,如果emit时传递了大量的数据到槽函数,这样效率可能较低。因此考虑只使用信号与槽的事件通知机制,不将数据emit出去,而将数据通过共享内存QSharedMemory在信号触发函数和槽函数间共享。...

2021-01-24 23:49:47 285

原创 大小端与结构体释疑

本人在做项目过程中需要在ARM对从FPGA读取到的数据进行处理,在实际过程中产生了一些问题,在思考了后记录在此。1 大小端模式大小端指数据在内存中的存储方式。小端指数据的高字节保存在内存的高地址处,低字节保存在内存的低地址处。大端模式则正好相反。ARM和x86的CPU一般情况下都为小端模式。对于值unsigned int value = 0x12345678,在内存中的存储方式如下。内存地址小端模式存放内容大端模式存放内容0x000040000x780x120.

2021-01-23 00:26:41 1708 1

原创 用petalinux工具制作linux系统启动映像

1 SD_SD启动在真正的工程应用中我们使用的都是QSPI_EMMC的启动方式,因为SD_SD这种启动方式需要SD卡与数字板一直保持连接,所有在恶劣使用场景下稳定性不好。在用QSPI_EMMC启动系统前我们需要先制作系统映像使系统通过SD_SD这种方式启动起来。下面介绍用petalinux制作系统映像的步骤。SD_SD启动指的是FPGA配置文件及系统引导文件BOOT.BIN和系统镜像ima...

2021-01-21 22:04:57 3230 1

原创 QString与char *的相互转换

1. QString 转换为 char *方法一将 QString 转 char *,需要用到 QByteArray 类。因为 char * 最后都有一个’\0’作为结束符,而采用 QString::toLatin1() 时会在字符串后面加上’\0’。QString str;char* ch;QByteArray ba = str.toLatin1(); // mustch=ba.data();注意第3行,一定要加上,不可以 str.toLatin1().data() 这样一步完

2020-10-07 23:16:22 646

原创 在zynq上用xillybus实现PL与PS上的linux系统间的数据传输

1 xillybus介绍xillybus是由Xilinx的合作伙伴xillybus推出的用于在FPGA和主机间进行数据传输的解决方案。在FPGA端通过标准FIFO与用户逻辑相连接,在主机端(Window或Linux)安装了相应的驱动程序后,可以以读写设备的方式接收数据或发送数据。本文主要介绍Linux系统下的数据传输。xillybus有三种数据传输的方案。第一是通过PCIE实现FPGA和外部PC主机间数据的传输。第二是通过转接ZYNQ的ACP、HP、GP接口实现FPGA和PS间数据的传输。第三是

2020-09-29 22:00:44 3650

原创 ZYNQ-7000芯片用u-boot启动linux系统方法

0. 芯片启动概述ZYNQ-7000系列芯片运行Linux操作系统需要BOOT.BIN文件、image.ub文件和rootfs。BOOT.BIN文件由fsbl.elf、bitstream和u-boot.elf(裸机elf程序)文件组成。fsbl.elf是由xilinx设计的,由OCM加载执行,有两个主要功能。第一是用于加载bitstream到PL,第二是根据BOOT.BIN文件组成,执行u-boot或是裸机elf程序。bitstream文件是FPGA的配置文件。裸机elf程序用于在不启动操作系统的情况

2020-09-20 19:14:18 4086 2

原创 STL queue/priority_queue类模板

队列是一种先入先出(FIFO)的数据结构,数据从一端进入而从另一端移除。实际上queue是把各项操作转化为内部容器的对应调用,可以使用任何序列式容器来支持queue,默认为vector。#include <queue> //包含头文件#include <iostream>using namespace std; //定义 queue<int> que1; queue<int, list<int>> que2; que1.p.

2020-09-16 19:40:42 135

原创 STL stack类模板

栈是一种先入后出的容器,STL中的stack默认采用deque实现,我们在声明栈时可以使用其它的序列式容器(如vector,list)实现栈。#include <stack> //包含头文件#include <iostream>using namespace std; stack<int> s1; stack<int, vector<int>> s2; //用vector实现栈 s1.push(1); //push.

2020-09-16 13:08:05 165

原创 STL map与multimap类模板

容器map是一种关联数组,是键值对的集合,一个键只能对应一个值,可以通过键为下标获取对应的值。multimap一个键可以对应多个值。key和value必须是可赋值和可复制的,对象以数据对的形式存放在二叉树中。初始化,清空,删除,插入等基本操作#include <iostream>#include <map> //包含头文件using namespace std; //以给定的排序准则定义map, map<int, double> m1; ..

2020-09-16 00:14:00 167

原创 STL vector类模板

vector是一个序列式容器,可以实现队列、数组和堆栈的所有功能。像一个动态数组,可以随机访问元素,迭代器也是随机存取迭代器。#include <vector> //包含头文件#include <string>using namespace std;void main(){ vector<string> myvt; //初始化 myvt.push_back("a"); //将对象放入容器尾部 myvt.pop_back(.

2020-09-13 22:04:24 121

原创 debug: QObject::connect: Cannot queue arguments of type

在使用自定义类的时候如果遇到这个问题,一般出现这种情况都是自定义的类型进行型号槽连接的时候出现的,在编译时不会出现问题,但当信号触发,对应的connect起作用时,会发现信号与槽并未连接在一起。使用qRegisterMetaType(“MyClass”), 注册之后就可以正常的进行信号和槽连接qRegisterMetaType<qintptr>("qintptr");...

2020-09-13 21:43:24 683

原创 指针的大小由什么决定

指针的大小,即存储指针的空间到底由谁决定?是CPU位数,OS位数,还是编译器呢?都不是,指针大小是由当前CPU运行模式的寻址位数决定! int* p; cout << sizeof(p);字长:在同一时间中处理二进制数的位数叫字长。通常称处理字长为8位数据的CPU叫8位CPU,32位CPU就是在同一时间内处理字长为32位的二进制数据。二进制的每一个0或1是组成二进制的最小单位,称为一个比特(bit)。 一般说来,计算机在同一时间内处理的一组二进制数称为一个计算机的“字”,而这组二进制数

2020-09-11 19:12:57 1246

原创 QThread多线程的使用

点击创建线程,程序会创建一个线程每隔1s打印自增数, 点击删除线程会删除最近创建的线程。下方的数字显示当前的线程数量。printThread类继承了QThread,通过start调用执行run函数。结束线程时,调用quit函数使线程退出。下面两个函数是按钮的槽函数,用STL MAP管理线程的ID与线程对象指针。注意:正常情况下通过线程对象调用start函数,会去执行run函数。从该函数返回后,线程实际就已经结束了。在run函数的默认实现中,它会去调用exec函数进入事件循环机制。我们也可以在重..

2020-09-09 21:33:43 276

原创 交叉编译器 arm-linux-gnueabi 和 arm-linux-gnueabihf 的区别

1 什么是ABI和EABIABI: 二进制应用程序接口(Application Binary Interface (ABI) for the ARM Architecture) 在计算机中,应用二进制接口描述了应用程序(或者其他类型)和操作系统之间或其他应用程序的低级接口。ABI涵盖了各种细节,如:数据类型的大小、布局和对齐;调用约定(控制着函数的参数如何传送以及如何接受返回值),例如,是所有的参数都通过栈传递,还是部分参数通过寄存器传递;哪个寄存器用于哪个函数参数;通过栈传递的第一个函数参数是最先

2020-08-21 16:15:56 326

原创 Linux编译源码树外的内核模块

Documentation/kbuild/modules.txtBuilding External ModulesThis document describes how to build an out-of-tree kernel module.=== Table of Contents === 1 Introduction === 2 How to Build External Modules --- 2.1 Command Syntax --- 2.2 Options.

2020-08-21 15:28:30 886

原创 AXI GPIO的使用

1 AXI GPIOMIO和EMIO 是直接挂在PS上的GPIO,而AXI_GPIO相当于 GPIO 的 IP 核,该IP核通过AXI总线与PS互联实现了GPIO。 在PS端通过对该IP核的控制寄存器进行读写,即可控制GPIO端口的状态。AXI GPIO 可以使用两个通道,分别是 GPIO 和 GPIO2。当PS的GPIO端口不够用时,我们可以用这种方法把GPIO挂接在AXI总线上与PS交互,大大拓展了PS可用的GPIO数量。1.1 PL逻辑部分设计我们用一个开发板上的按钮控制4个LED灯的

2020-08-21 10:21:33 6502 1

原创 Xilinx AXI4总线概述

1 ZYNQ-7000与AXI1.1 AXI总线概述1.1.1 三种类型ZYNQ支持AXI4-Lite,AXI4和AXI4-Stream三种AXI(Advanced eXtensible Interface)总线协议。AXI4:主要面向高性能地址映射通信的需求,是面向地址映射的接口,允许最大 256 轮的数据突发传输。AXI4-Lite:是一个轻量级的地址映射单次传输接口,占用很少的逻辑单元。AXI4-Stream:面向高速流数据传输;去掉了地址项,允许无限制的数据突发传输规模。1.1.

2020-08-20 17:39:18 1293

原创 ZYNQ-7000 最小系统的搭建

1 最小系统分析注意:这里的最小系统指裸机情况下的,此时没有操作系统运行。我们的最小系统需要DDR控制器和UART串口控制器、网口控制器、QFLASH控制器、SD控制器。DDR控制器已经与zynq芯片连接死,而UART串口控制器、网口控制器、QFLASH控制器、SD控制器通过MIO与外部串口连接。搭建好的最小系统如下图所示,FCLK_CLK_0是PS的输出时钟,可以给PL部分使用。修改时钟配置。PS输入时钟设置为33.333333MHZ,CPU PLL时钟设置为666.666666MHZ,PL

2020-08-20 12:59:01 1768

原创 ZYNQ-7000 GPIO使用

1 ZYNQ-7000 GPIO介绍1.1 MIO与EMIO区别GPIO(Generous Purpose Input Output)是指CPU引出的,可以配置为输入或输出的端口,用于CPU与外界进行数据的传输。ZYNQ-7000 架构由 PL+PS 组成,所以它的 GPIO 与一般的 ARM 不同。ZYNQ 的 GPIO,分为两种,MIO(multiuse I/O)和 EMIO(extendable multiuse I/O)。MIO 有54个,分配在 GPIO 的 Bank0 和 B

2020-08-19 17:57:18 1224

原创 ZYNQ-7000 SPI通信

1 SPI通信协议SPI是串行外设接口(Serial Peripheral Interface)的缩写,是 Motorola 首先提出的全双工三线同步串行外围接口。采用主从模式(Master Slave)架构,支持多 slave模式应用,一般仅支持单 Master。时钟由 Master 控制,在时钟移位脉冲下,数据按位传输,高位在前,低位在后(MSBfirst)。1.1 接口定义SPI 接口共有 4 根信号线,分别是:设备选择线、时钟线、串行输出数据线、串行输入数据线。为全双工通信,目前应用

2020-08-19 15:50:53 6139 2

转载 MAKEFILE学习

1 Makefile中的变量1.1 变量的定义在 Makefile 中,变量是一个名字(像是 C 语言中的宏),代表一个文本字符串(变 量的值)。在 Makefile的目标、依赖、命令中引用变量的地方,变量会被它的值所取代。Makefile 传统做法是变量名是全采用大写的方式。推荐的做法是在对于内部定义定义的一般变量(例如:目标文件列表 objects)使用小写方式,而对于一些参数列表(例如:编译选项 CFLAGS)采用大写方式,但这并不是要求的。当我们定义了一个变量之后,就可以在 Makefil

2020-07-17 20:32:51 2158

原创 ZYNQ_FSBL学习

1 FSBL介绍1.1 fsbl涉及的启动流程zynq内部的BootROM存储有一段在CPU复位后固定执行的代码。称为stage-0启动代码。这段代码用来配置一个ARM CPU和一些必要外设,从而能从一个启动设备中获取FSBL(first stage boot loader)执行。BootROM是一个ROM,不可写,PL的配置不是通过BootROM实现的。BootROM不能使用DDR和SCU,因为它们还没有初始化。FSBL通常存储在FLASH中,BootROM从选定的FLASH中拷贝FSBL到

2020-06-28 21:57:30 11202 2

原创 debug u-boot编译报错./tools/../lib/rsa/rsa-sign.c:279:21: error: dereferencing pointer to incomplete

编译u-boot时报错百度后知,由于openssl api更新,要到github上下载补丁。链接地址补丁下载后,找到rsa-sign.c文件,对其进行打补丁。patch rsa-sign.c ./../../tools/210-openssl-1.1.x-compat.patch。注意每个人补丁放置的位置可能不同。下图是我的位置。打完补丁后,编译通过...

2020-06-17 16:54:52 1862 1

原创 debug 使用QWT用MSVC产生error LNK2001的原因及解决方法

使用QWT库时,用MSVC编译器,链接时报错明明库的指定路径都已设定正确,为什么会链接报错?出现这样的连接错误一般都是由于Qwt类库的头文件中没有加Q_OBJECT而导致的,这对于一个成熟的类库来说是不可能的。在网上搜索得出解决办法:在pro文件中定义预处理宏QWT_DLL,然后clean,再qmake,然后build,编译通过。这是为什么呢????这是由于预处理所带来的问题QWT通过动态库抛出类的方式将类QwtPlot抛出供使用者使用,我们来看一下抛出地方时如何定义的(位于qwt_golb.

2020-06-03 22:21:50 214

原创 QThread线程的使用

通过moveToThread//mainwindow.cpp#include "mainwindow.h"#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow){ ui->setupUi(this); myThread1 = new myThread; myThread2 = new

2020-05-27 22:02:02 222

原创 debug——QByteArray与int之间的转化

QByteArray从名字上看是字节数组,但它里面实际上是以字符数组的形式存储数据的。QByteArray a;a[0] = 0xff;a[1] = 0xff;a[2] = 0xa1;a[3] = 0x89;qDebug() << a.size();qDebug() << a;我们看到a中存储的是字节型数据,大小为4QByteArray b = a.toHex();qDebug() << b.size();qDebug() <&lt.

2020-05-22 18:53:41 2284

原创 利用迭代器指定区间

一般我们用迭代器指定区间时都是用begin和end方法,但当我们不想遍历至end是该怎么办呢?利用迭代器指定区间时不能将迭代器加上一个整数,否则会报错,如下所示会报错list_two.assign(list_one.begin(),list_one.begin() + 3);print(list_two);所以可以利用迭代器自增的方法实现list<double>::iterator it = list_one.begin();for(int i = 0;i < 3;i++)

2020-05-21 16:52:30 437

原创 debug 在模板函数中定义迭代器不识别

定义了如下的模板函数template <typename T> void print(list<T>& mylist){ list<T>::iterator it; for(it = mylist.begin();it != mylist.end();it++) cout << *it << ","; cout << endl;}未编译便报错如下main.cpp:10:5: e

2020-05-21 16:37:32 953 1

转载 CMake的安装及使用

1 安装windows下安装首先下载,CMake官网下载地址,里面好多版本,根据自己需要版本进行下载。安装过程中选择了自动添加环境,所以安装完后不用手动添加环境了,但是此时必须得重启电脑,变量才能使用,否则无法对Cmake安装进行测试。在cmd窗口中,输入cmake,看到提示信息,说明cmake安装成功。Linux下安装首先输入cmake -version查看下系统安装了没有,没有的话继续安装,输入sudo apt install cmake安装。之后输入cmake -version看到

2020-05-15 11:22:15 13044 1

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除