- 博客(98)
- 资源 (7)
- 收藏
- 关注
原创 liteOS中双向循环链表的一些设计思想
1. 问题提出看liteOS的源码,发现这些伙计们的水平还是高的。对于一个双向链表,一般我们的写法都是:typedef struct Node { int data; struct Node *prev; struct Node *next;} NODE但是这就诞生了一个问题,节点Node中的数据类型是int时我们定义了一个链表类型NODE0,如果是float data又定义了一种链表类型NODE1,或者有多个业务变量时我们又定义了NODE2,这时候如果我们想写一个链表遍历函数,希望能够对所
2022-03-05 15:35:19 497
原创 内存管理01——链接脚本
新年的第一篇博文,先祝我工作顺利,万事如意!祝福大家的话就不赘述了。在开始操作系统的内存管理相关内容前,首先来关注链接脚本,因为动态内存即堆区的地址是在链接脚本中分配的,知道了堆的起始地址和长度才能进行内存的分配和管理。1. 链接脚本的作用是什么?链接的作用就是把编译生成的多个目标文件(.o)合并起来,生成最后的可执行文件(.elf)。如上图中间的就是.o目标文件,最右的则是链接生成的.elf文件。除此之外,链接脚本还关注一个问题,就是生成的各个段被加载在内存的什么位置。举个例子很容易就明白,下面
2022-02-12 17:52:24 2681
原创 变量究竟是存在寄存器还是堆栈?
1. 变量是放在寄存器里还是堆栈里?堆栈对于处理器来说就是一块内存区域,而寄存器是处理器触手可及的存储,对于RISC 处理器而言,堆栈中的数据CPU并不能直接进行运算,还是要先加载到寄存器中才行。对于编译器而言,我猜测还是优先会选择将变量用寄存器保存。那什么时候需要用到堆栈呢?什么东西需要保存到堆栈呢?一种是需要切换上下文的地方,另一种是需要传参的地方。函数调用就是一种典型应用。2. 函数调用时的栈与寄存器一个典型的函数调用流程如上图所示,关键的涉及栈和寄存器的步骤如下:首先,在调用其他函数前,
2022-01-18 16:43:46 2809
原创 编程与人生
我们都知道,一个函数返回成功的时候,我们一般都是return 0;失败的时候则return 非零的值,究其原因呢,因为成功的时候只有一种情况,就是按照我们预定的功能运行了;而失败的情况则各不相同,可能是输入参数错误了,可能是执行失败了,可能是出异常了等等。于是零和非零很自然地,选择零作为执行成功的输出;非零作为失败的各种情况。这让我想起那句话怎么说来着,“幸福的家庭都是相似的,不幸的家庭各有各的不幸。”所以,运行成功的代码都是相似的,不成功的代码各有各有的BUG。哈哈哈,写这个小段子的时候突然又想起.
2022-01-15 14:32:49 199
原创 RISC-V汇编学习中的一些思考
1. 立即数立即操作数,immediate operand,是我觉得在汇编中比较难理解的概念之一了。立即数简单理解就是被编译在指令中的,能被处理器立即使用的常数。在CPU的算数逻辑计算单元 (ALU) 中,能接触到的值只能是来自寄存器的值或者是立即数,他没法儿直接去内存中获取值,内存中的数值必须先被取到寄存器中,然后才能被运算。比如下面这几句C代码:int a , b;a = 5;b = b + a;ALU要处理a和b的值,就必须先把他们的值取到寄存器中,因为a和b都是变量,他们在内存中都有自己
2022-01-11 15:56:28 1752
原创 为什么CPU需要不同的特权等级?
如下图是一个经典的x86的特权等级示意图,x86有0~3共4级特权等级,但一般只有0级和3级常用。操作系统/内核工作于特权等级0,用户则工作于最低的特权等级3。1. 特权等级是谁实现的?当我们描述特权等级的时候,一定要区分的一个概念是:特权等级是CPU实现的,还是操作系统实现的?答案是CPU实现的。操作系统的不同模式是在CPU实现的基础上进行对应的。2. 特权等级怎么实现的?这里举一个RISC-V处理器的例子如下,RISC-V处理器定义了三种不同的特权等级,M,S,U三种,其中M是最高的等级,可以
2022-01-04 15:10:34 1132
原创 STM32的完整启动流程分析
关于STM32的启动流程,网上有的资料在讨论几种boot模式,有的在回答启动文件的内容,在查阅了很多资料后,本文给出一个比较全面的总结和回答。1. 根据boot引脚决定三种启动模式复位后,在 SYSCLK 的第四个上升沿锁存 BOOT 引脚的值。BOOT0 为专用引脚,而 BOOT1 则与 GPIO 引脚共用。一旦完成对 BOOT1 的采样,相应 GPIO 引脚即进入空闲状态,可用于其它用途。BOOT0与BOOT1引脚的不同值指向了三种启动方式:从主Flash启动。主Flash指的是STM32的内
2021-12-03 11:03:12 17120 6
原创 STM32 HAL库IIC驱动
关于STM32的IIC驱动,网上有很多争论,究竟是使用STM32自带的硬件IIC还是用IO口和软件模拟IIC呢?下面这个图形象展示了这些争论。总结一些:ST为了规避IIC硬件的专利问题,将其设计地有点复杂,但是其提供的标准驱动库并没有很好地适配,导致出现一些BUG。但是下图中那位叫theuit的网友指出了:**“难道ST不知道吗?到底有没有改呢?”**目前,至少从我测试的结果来看,可以得到结论:用HAL库来驱动ST的IIC没问题!首先,我们给出两种IIC器件。第一种是带器件中带有寄存器的一类,对这
2021-12-02 17:06:23 4322 1
原创 STM32F4定时器介绍
1. 定时器的种类从下面这个这个图看出,高级定时器相比于通用定时器,高级在其有“带可编程死区的互补输出”。这在H桥等电机控制场景中十分重要。如何理解死区?通常,大功率电机、变频器等,末端都是由大功率管、IGBT等元件组成的H桥或3相桥。每个桥的上半桥和下半桥是是绝对不能同时导通的,但高速的PWM驱动信号在达到功率元件的控制极时,往往会由于各种各样的原因产生延迟的效果,造成某个半桥元件在应该关断时没有关断,造成功率元件烧毁。死区就是在上半桥关断后,延迟一段时间再打开下半桥或在下半桥关断后,延迟一段时间再
2021-11-30 20:49:00 3064
原创 基于深度图像的多人姿态检测
本文主要是对"Efficient Convolutional Neural Networks for Depth-Based Multi-Person Pose Estimation"论文的一个介绍,2019年发表,作者是ANMG等,很优秀的一篇论文。链接:https://arxiv.org/pdf/1912.00711.pdf概述首先,本文的目标是在一副深度图像中获取出人体的关键点坐标,本文中认为有17个,结果实例如下图所示。本文采用的架构如下:包含两个大的阶段,前一阶段使用CNN进行特征提
2021-11-16 17:02:57 4693 1
原创 YOLOv1——YOLOv3的一些理解和总结
每一代YOLO中最亮的亮点。1.1 YOLOv1YOLOv1最值得说的当然是YOLO网络提出本身,使用回归的方法端到端解决了目标检测问题。一个值得一提的细节就是,YOLOv1采用了将一副图片划分为多个grid cell的方法,每个grid cell仅预测出两个框,最终的输出张亮大小为:S x S x (B x 5 + C),其中S是grid cell在某一维的数目,B是每个grid cell预测出的框的数目,5代表了框的中心x,y坐标和框的宽w、高h,以及框的IOU值,C代表了每个物体类别的概率.
2021-11-11 19:58:16 2671
原创 Xilinx SDK如何将Console的内容复制出来?
整理自:https://www.amobbs.com/thread-5738341-1-1.html上图界面处,无法ctrl+C,也无法右键。有两种方法将内容复制出来:按住ctrl+shift+c就可以复制啦!debug configuration - common - standard input and output - output file第一种方法亲测可用,第二种没试过。...
2021-07-05 17:40:58 806
原创 ZYNQ7020确定EMIO的引脚编号的方法
有一段时间没有使用ZYNQ7020了,突然捡起来用一下,发现我找不到EMIO的引脚号应该是多少了!在此简单记录下。从UG585中可以看到,7020的GPIO分为了4组,其中BANK0和BANK1是MIO,共有54个,编号为0 ~ 53;BANK2和BANK3是EMIO,共有64个,编号为54 ~ 117。当我们在vivado中配置EMIO的时候,也并没有指定其编号,只是指定了需要的EMIO的数目。当在SDK中编程使用时,EMIO的编号永远就是从54开始数。如果上面指定的位宽是2,则编号是54, 5
2021-06-01 17:04:57 3864 4
转载 使用JTAG是如何烧写SPI/BPI Flash的?
这天突然琢磨了下这个问题,就搜索了一下答案,转载如下:Xilinx的JTAG电缆可以通过FPGA“直接”烧写SPI/BPI。很多对xilinx开发环境不熟悉的用户,如果第一次接触这种烧写模式可能会有疑惑,FPGA是如何做到JTAG和Flash之间的桥接的,难道FPGA内部有专用的电路去实现这一功能吗?其实不是的。FPGA内部并没有设计(预留)专用的电路去实现JTAG到Flash的转换,在我们通过JTAG烧写Flash时,电脑其实是先要预下载一个bit文件到FPGA的,就是这个临时bit文件起到了一个桥接
2021-05-26 19:19:03 5802
原创 opencv中Size与Rect的宽高顺序
opencv中关于Rect和Size的宽高顺序折磨了我很久,略作记录。Size_(_Tp _width, _Tp _height)Size是先宽后高,这一点如果不记得可以随时查看Size定义来确认;Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height)在opencv中x方向指的都是水平方向;y方向指的都是y方向,这一点在各处都是一样的。其实对于Size也是按照先x后y的顺序的。matrix.at<char>(row, col)数组的访问当然还是按照先
2021-05-18 10:20:08 807
原创 numpy数组运算时的数据类型
今天在进行numpy运算的时候碰上了一个数据类型转换的坑,记录一下。问题:假设n1是uint8类型的,n2是float64类型的,请问n1 = n1 + n2得到的n1是什么类型呢?n1[1:5] = n1[1:5] + n2[1:5](数组的大小不止6个,取部分运算)得到的n1的数据类型呢?答:n1 = n1 + n2将会得到一个float64的数组;而n1[1:5] = n1[1:5] + n2[1:5]依旧是一个uint8的数组。如果n1[1:5]中有负数如-4,则会被转换为252,我就是在这翻车
2021-04-15 20:08:41 395 1
原创 PyQt的代码之道
addwidget()方法用于向布局中添加控件;addLayout()方法用于向布局中添加子布局;QSplitter需要添加到QBoxLayout中进行配合使用,两者的布局方向要保持一致。hbox.addWidget(splitter1)QFrame, QSplitter与QBoxLayout之间的相互关系:来自https://www.cnblogs.com/lipx9527/p/14020423.html,总结得很好。可使用QSplitter进行动态布局,通过拉动网格线改变大小;QHBoxL.
2021-04-09 11:20:13 396
原创 C++ Opencv中Mat的操作
Mat 是一个类,由两个数据部分组成:矩阵头(包含矩阵尺寸,存储方法,存储地址等信息)和一个指向存储所有像素值的矩阵(根据所选存储方法的不同矩阵可以是不同的维数)的指针。OpenCV使用引用计数机制。其思路是让每个 Mat 对象有自己的信息头,但共享同一个矩阵。这通过让矩阵指针指向同一地址而实现。而拷贝构造函数则 只拷贝信息头和矩阵指针 ,而不拷贝矩阵。初始化拷贝构造函数初始化:Mat A, C; // 只创建信息头部分A = im
2021-03-15 10:13:06 4097 1
原创 给opencv函数写一个python装饰器
今天这个话题很有意思,能够帮助理解python装饰器的含义。使用过VS做图像处理的同学可能接触过Image Watch这个调试工具,其界面如下图所示。可参见如下链接:https://blog.csdn.net/iracer/article/details/83413877今天,在python下找到了一个类似的工具,叫pyimagewatch. 虽然没有完全理解其使用,但其思路可以参考一下:实现相关功能的方式就是给相应的opencv函数写一个装饰器。比如想查看一个opencv函数的执行结果(Watcher
2021-02-02 15:35:24 357
原创 VS+QT快速入门教程
昨天快速入门了一下在VS上开发QT,主要参考的Qt入门教程:1天玩转Qt。本文也算是这个简单教程的摘要。1. 背景Qt 不仅仅是一个GUI库,它除了可以创建漂亮的界面,还有很多其他组件,例如,你不再需要研究STL,不再需要C++的头文件,不再需要去找解析XML、连接数据库、Socket 的各种第三方库,这些 Qt 都已经内置了。独立安装:Qt 程序最终会编译为本地代码,不需要其他库的支撑,而 Java 要安装虚拟机,C#要安装 .NET Framework。但是,由于Android本身支持Java
2021-01-30 11:13:21 24423
原创 3D重建 “Real-time 3D Reconstruction at Scale using Voxel Hashing“
Real-time 3D Reconstruction at Scale using Voxel Hashing是一篇比较经典的实时3D重建的论文,这里介绍一些看了本文后的一些理解。论文下载链接:https://graphics.stanford.edu/~niessner/papers/2013/4hashing/niessner2013hashing.pdf论文的核心其实是采用了稀疏的哈希表来存储体素数据,从而减少了存储量和计算时间。体素Voxel的数据结构如下,其中sdf其实是TSDF,即截断带
2021-01-18 11:34:00 1186
原创 安全函数最全总结:字符串拷贝,内存拷贝,字符串格式化等
对于安全函数和非安全函数有几个方面需要比较:入参。安全函数会比非安全函数多一个目的缓冲区长度,这个参数一般紧跟着目的缓冲区指针,作为函数的第二个入参。函数返回值。非安全函数也就是系统函数,比如字符串拷贝函数strcpy的返回值是一个指向最终的目标字符串 dest 的指针(非安全函数不知道返回什么的时候就会返回这个);而安全函数strcpy_s返回一个整形错误码errno_t,表示函数执行是否成功及相应的错误类型(成功时返回零,错误时返回非零值),调用者应该校验该返回值。发生缓冲区溢出会怎么办!非安全
2020-11-09 20:24:24 6607
原创 教你如何记住二叉树的遍历方式!
二叉树的前序,中序,后序遍历真是看一遍就会,看过就忘的小妖精啊,在这里总结一下窍门。实际上前序,中序和后序遍历的命名是体现在根节点的位置的,也就是说根节点在前的是前序,根节点在中间的是中序,根节点在后的是后序,而左子树和右子树的顺序是不变的,先左后右,男左女右(呸呸呸)。前序遍历顺序:根节点,左子树,右子树中序遍历顺序:左子树,根节点,右子树后序遍历顺序:左子树,右子树,根节点还有一点关键的是,比如前序遍历顺序并不是根节点,左孩子,右孩子;而是根节点,左子树,右子树,里面是蕴含了递归思想的,记
2020-11-07 17:45:54 472
原创 教你如何记住卷积后图像大小的公式
假设输入图像的尺寸为i x i,输出图像尺寸为 o x o, 步长stride为s, 某一边的padding为p,kernal的大小为k x k,则公式为:如何快速记住这个公式呢?如上图画了一个实例,输入图像大小为3 x 3, i = 3; p = 1; s = 1; k = 3.3 x 3的图像经过padding以后变为5 x 5,即i + 2p。而 i + 2p - k 的含义则是图中的蓝色kernal有几个像素可以走,每一步的步长是s,(i + 2p - k) / s 的意思显然就是蓝色ke
2020-11-05 09:52:13 1668 1
原创 python图像处理中的卷积函数
scipy.ndimage.filters.convolve函数def convolve(input, weights, output=None, mode='reflect', cval=0.0, origin=0)函数定义如上,其中weight代表卷积核/滤波器,mode代表填充方式,cval代表使用常数填充时的常数值,origin代表卷积核的中心位置偏移。函数返回值代表处理后的结果。cv2.filter2D函数opencv中提供的函数。def filter2D(src, d.
2020-10-26 11:23:36 3294 1
原创 Xilinx SDK程序Debug无法在main函数入口处停住解决
问题描述:采用的芯片是ZYNQ7020,设计好逻辑程序,导出hdf文件后在Xilinx SDK中调试软件程序。采用Debug的方式,发现程序不能在main函数入口停下,且暂停程序时,程序跑飞。定位过程遇到这个问题,首先在Debug Configuration中配置将stop at program entry这个选项选上,这会让你的程序从软件的第一句开始执行,也就是中断向量表的位置,见下下图。然后可以单步跟踪程序看是在哪里跑飞导致没有进去main函数的。在我的程序中进行了这样的调试之后,发现第一.
2020-08-19 10:26:43 6124
原创 ASPICE总结2——软件详细设计与软件测试过程
软件详细设计在ASPICE中代号是SWE3,处于V模型的左侧; 软件测试则包含软件单元测试(SWE4),软件集成测试(SWE5)以及软件合格性测试(SWE6)三部分,处于V模型的右侧。下面我会比较详细地介绍一下各过程域的实施要点和迎审会面对的主要问题。软件详细设计软件详细设计要准备的第一份交付件就是:软件详细设计文档!文档的输入是软件的需求,内容应该涵盖数据结构定义,全局变量和宏定义描述,动态行为描述(任务/中断/需求方案分析等),每个函数的实现(输入/输出/返回/伪码等),详细设计评估(关键性、复杂
2020-08-12 15:25:32 8297 9
原创 ASPICE总结——1
为了应对外部A客户的迎审,最近包括去年都做了比较久的ASPICE准备工作,作为一个软件研发,我的任务主要集中在软件详细设计,软件单元测试,软件集成测试,也涉及了一点软件合格性测试。但是前几天得知迎审取消了,有喜有忧,喜的是终于迎来一个双休,不用每天听英语听力了;忧的是这些工作要搁置了。所以,整理一下我在做ASPICE与准备迎审过程中的一些总结和感悟吧。ASPICE,全称“Automotive Software Process Improvement and Capacity Determination”
2020-08-11 10:17:07 6478 6
原创 ASPICE所有过程域介绍
虽然题目叫所有过程域介绍,但其实不是我来介绍哈哈哈哈。发现了一个NB的链接包含了这些介绍,很适合用来做快速查询,如下:https://www.flecsim.de/images/download/AutomotiveSpiceShortened/index.htmlSWE1部分截图如下我发现我最近没写博客,给我点赞评论关注的人都变少了,CSDN你给我个说法!...
2020-07-11 16:39:02 2892 2
翻译 锁步核(lock-step core)、软件冗余设计与可分核(Split-Lock)的比较
这是一篇翻译文,原文题目为:Evolving safety systems: Comparing Lock-Step, redundant execution and Split-Lock technologies原文地址:https://community.arm.com/developer/ip-products/system/b/embedded-blog/posts/comparing-...
2020-03-03 10:43:02 30597
原创 如何便捷获取枚举类型的最大值?
今天在看LWIP的代码,在定义一个枚举类型的时候使用了下面的操作,**即在类型中定义了一个没有意义的MEMP_MAX类型。**这就保证了不管在这之前你定义了多少种类型,MEMP_MAX这个值就是该枚举种类的数量。后面可以使用该值初始化数组啊什么的,非常灵活。typedef enum { #define LWIP_MEMPOOL(name,num,size,desc) MEMP_##name,...
2020-02-28 19:37:56 2288
原创 网络编程入门教程03——socket机制
再一次地,把网络7层模型放在前面:1. socket的位置在介绍了传输层(TCP/UDP)、网络层(IP),理论上,我们已经可以开始编写应用程序来使用这些层了。然而由于这些协议过于复杂,操作系统在应用程序与协议栈之间提供一个软件接口socket套接口。第一个值得注意的地方就是socket套接口的位置,套接字承上启下,应用层可直接使用套接口实现网络编程。2. socket类型sock...
2020-02-04 17:02:19 281
原创 网络编程入门教程02——IP和TCP/UDP
上一篇我们介绍了OSI网络七层模型中的链路层和物理层,今天要介绍的内容是关于网络层和传输层。还是先把OSI七层模型摆出来,如下图:1. 网络层在数据链路层中提到了每块网卡都有一个独一无二的MAC地址,数据由一块网卡传到另一块网卡需要知道对方的MAC地址。在知道对方MAC之后,如何将数据包发送过去呢?广播是种办法,即将数据发给本子网中的所有电脑,接受到数据的电脑比较自己的MAC地址是否匹配,...
2020-02-03 11:31:25 237
Cyclone 10LP Remote Update Intel FPGA IP 官方工程实例
2018-12-20
Generic Serial Flash Interface Intel FPGA IP Core工程实例
2018-12-13
Generic Serial Flash Interface Intel FPGA IP Core User Guide
2018-12-12
EPCS,EPCQ, Cypress, Micron Datesheet
2018-12-12
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人