![](https://img-blog.csdnimg.cn/20201014180756916.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C/C++
文章平均质量分 60
驱动,SDK
六个九十度
嵌入式软件工程师
展开
-
将ISP DMA写到DDR的数据unpack成可被7yuv预览的RAW图
ISP DMA的特点是一端字节对齐访问,一端流式访问,且净荷数据不一定是8bit的整数倍原创 2023-04-21 10:19:07 · 598 阅读 · 0 评论 -
分析C语言位域的访问开销
访问位域有开销,这包括移位、截断等操作,但考虑到内存局部性原理,这些操作都不影响cache,因此性能并不会差多少。原创 2023-02-15 09:17:33 · 350 阅读 · 0 评论 -
C语言的预处理器无法先展开宏再拼接符号?可以!
拆分成2个宏定义!原创 2022-12-13 09:58:05 · 432 阅读 · 0 评论 -
gcc对void型指针的类型检查有问题?
不要使用void **参数原创 2022-11-11 10:02:09 · 896 阅读 · 0 评论 -
原来函数入参类型不匹配gcc也能编译通过啊
入参类型不匹配可能会导致内存访问越界!原创 2022-10-13 19:47:47 · 480 阅读 · 0 评论 -
使用枚举实现编译时可变长数组
枚举值是编译时可确定的,所以能用于定义数组长度。原创 2022-08-12 09:57:46 · 204 阅读 · 0 评论 -
浮点型数值强转成整型时,发生了什么?
当我们将值类型强转时,必定有对应的CPU指令实现,不要以为没有开销。原创 2022-07-05 15:29:32 · 2451 阅读 · 0 评论 -
对匿名联合体的一些理解
概念匿名联合体是一种语法糖,用于定义结构体内一类互斥的字段,但这些字段从语义层面上来说又是跟结构体内其他字段平级的。它跟匿名结构体的语法类似,但用处感觉比后者更大些。注意事项1. 可以定义多个匿名联合体,只要字段不重复即可,匿名结构体同理。2. 包含匿名联合体的`命名类型`不一定非得是struct,也可以是另一个union,代表`互斥`场景内的`子互斥`场景。原创 2022-04-16 10:54:23 · 938 阅读 · 0 评论 -
C语言宏的空展开应用案例:定义仅在debug版本执行的打印函数
使用函数宏,并根据配置展开成printf或空宏原创 2022-03-13 08:24:21 · 389 阅读 · 0 评论 -
查看浮点数的内部存储格式
浮点数所有浮点数的内部存储格式都遵照IEEE 754标准。如果想验证一下自己的电脑是否真的如此,就需要查看浮点数在内存中的表示,而这里存在一个强制类型转换的注意事项:不要直接强转浮点数,而是强转浮点数的内存地址因为强转浮点数对应的编译器操作是向下取整!验证代码#include<stdio.h>int main(){ float a; printf("enter a float:"); scanf("%f", &a); printf("%x原创 2021-08-31 11:52:57 · 325 阅读 · 0 评论 -
USBTMC设备端驱动的一些开发心得
背景最近2个多月主要在忙USBTMC设备端驱动的重构,原来的驱动是参考gtzhai的github工程linux-driver-usbtmc-gadget,然后根据公司需求做了一堆单片机风格的魔改,可读性惨不忍睹,BUG不多但都很棘手,于是决定重构。重构后所有BUG都解决了,没解决的也知道为啥不能解决。为了对自己这段时间死掉的脑细胞聊表纪念(压力也有点大),决定将心得分享一下。重构思路首先让驱动能实现建链版本的驱动充斥着关中断操作,这使得设备不出错则已,一出错就是整机卡死的严重故障。于是我首先将所有原创 2021-08-23 14:52:12 · 3615 阅读 · 5 评论 -
Linux内核函数wait_event_interruptible的condition参数踩坑
wait_event简介wait_event_interruptible(以及wait_event打头的其他变体)是Linux的wait queue机制提供的线程同步接口,它的定义如下#define wait_event_interruptible(wq, condition) \({ \ int __ret = 0; \ might_sleep(原创 2021-07-06 11:55:28 · 1618 阅读 · 0 评论 -
实现一个简单的日志收集程序
背景之前定位过一个fclose导致的性能问题,最终结论是日志收集程序的主线程调用fclose函数,触发操作系统sync磁盘操作,导致上游业务程序被阻塞在某条随机的打印日志语句里,最终扰乱业务。当时为了规避问题,将日志收集程序在系统启动脚本里注释掉了,并提醒业务同事尽快重构日志收集程序,没想到业务的同事一直不改,直到最近因为另一个业务问题,牵扯到驱动,于是我决定替他们重构。解决方案思路触发sync磁盘操作的fclose必须挪到子线程。主线程的写日志操作不能被子线程的fclose卡住,否则拆分线程原创 2021-05-06 16:40:27 · 402 阅读 · 0 评论 -
【俗话编程】什么是类
类就是基因,生命个体就是对象实例,计算机上我们只跟对象打交道,就像自然界我们只跟生命个体打交道一样类在实例化对象时需要消耗内存等资源,就像生命孕育新生命时需要消耗营养。类能实例化多少对象取决于资源容量,本身是贪婪的,基因也是如此,它希望殖民整个宇宙对象有生命周期,类没有,就像动物有生老病死,基因没有。当然如果拉长时间尺度,基因也会产生和灭绝,就像java的类也会加载、卸载一样类之间存在继承树,就像物种树、基因树一样类包含了属性和行为,就像基因也编码了性状跟本能类也会演化,但突变不像生命个体那样自.原创 2021-03-24 08:57:23 · 584 阅读 · 0 评论 -
【俗话编程】什么是对象?
俗语解释对象可以是一个人,他有鼻子、眼睛,他能嗅、看对象也可以是一个鼻子,它有鼻梁、鼻头,它能垫高、长黑头对象还可以是一粒黑头,它有皮脂、细胞屑,它能堵塞毛孔、吸纳尘埃对象是任何你能想出来的名词现实例子编程中的对象,是一块内存区域,举例Person对象来说,区域头4个字节记录的是他的身高,接下来的4个字节记录的是他的跳跃功能——通常是个函数指针,指向另一块存储函数代码的内存区域——,再下来是2个字节的年龄,等等Personheightjump->age原创 2020-11-22 10:40:57 · 4132 阅读 · 1 评论 -
extern关键字的一个妙用——为宏函数添加时间戳
extern和宏函数简介extern简介extern是C语言的一个关键字,用于修饰全局变量和函数,它告诉编译器,当前编译单元(即.c文件)里引用的某个变量,并没有在本单元内部定义,而是在其他编译单元里定义,所以找不到变量定义的时候别报错,就当变量存在。至于生成可执行文件的时候咋办,这是链接器(linker)要操心的事,编译器不管。举个例子timer.c定义了一个全局变量g_sys_tick和中断处理程序Timer_ISR,用于记录系统当前已运行时间,每当Timer中断触发,g_sys_tick就会加原创 2020-10-26 14:46:59 · 856 阅读 · 1 评论 -
记一次fclose导致的性能问题
背景最近在做功率分析仪的研发,这玩意儿就是个大号的万用表,可以测量用电器的各项电气参数,比如电压、电流、功率,等等。有款产品一直存在一个性能问题,就是上位机通过USB连接下位机时,下位机上报的测量值经常丢失。下位机应用看应用日志,发现经常有两条日志间隔2s左右,但间隔的位置不固定,用top命令查看CPU占用率,也没有特别高的进程。我查看驱动日志syslog,没发现任何报错,哪怕是超时报错也没有。但是在应用代码调用write系统调用的前后加日志,发现确实有write耗时200ms的时候,这是不正常的,所原创 2020-09-22 15:06:04 · 1182 阅读 · 0 评论 -
「俗话编程」什么是指针?
俗语解释你有事想找朋友帮忙会直接打朋友电话但是你想找明星谈合作就必须先联系明星的经纪人经纪人觉得你靠谱才会带着你去见明星这个经纪人,就是编程领域的指针现实例子C/C++中的指针,是一种变量,它长度为机器字长(32位系统就是4字节,64位系统就是8字节),储存一个对象的地址——地址长度=机器字长,巧不巧?对象可以是简单对象,例如int,这时候用指针就感觉很矫情,因为你想找朋友帮忙直接他打电话就行,何必先打电话给他老婆问他在不在?对象也可以是复杂对象,例如FILE,你要操作文件,就必须获取一原创 2020-08-16 09:54:07 · 453 阅读 · 0 评论 -
突破海康相机255预置点的限制
背景什么是相机的预置点?预置点就是一条记录,它记录下云台的俯仰角、偏转角,镜头的焦距、相机的光圈、曝光、白平衡等拍照参数,储存在相机内部的SD卡上,并被赋予一个编号以供用户索引。用户可以让相机根据指定编号的预置点,将自身拍照参数恢复到预置点记录的参数值,以实现拍摄预定区域的画面,这在安防领域很常用。海康相机的云台最多支持255个预置点,对于安防一般够了,但对巡检机器人来说就不够,因为机器人是移动的,它的巡视面积非常大,很容易就突破这个数目。预置点的用法一般通过调用NET_DVR_PTZPreset(原创 2020-08-08 11:04:34 · 5464 阅读 · 2 评论 -
C++调用Matlab Compiler Runtime库函数的最简方法
Matlab Compiler Runtime的官方简介但是下载安装该runtime后,发现没有示例代码,直接调用某个函数测试,比如说用mxCreateDoubleMatrix分配一个1x1的矩阵,会返回空指针,看该函数的官方文档,分配失败的原因是heap内存不够,怀疑此heap非彼heap用mclmcrrt(runtime对应的lib文件)和32bit(我的x86机器)两个关键字搜百原创 2016-04-19 09:30:20 · 1916 阅读 · 0 评论 -
将C语言宏定义转换成字符串!
适用场景举例流媒体处理系统中,采样率是个很重要的参数,很多地方都要用,如果用来分配内存,则#define SAMPLE_RATE 16000如果用来配置第三方库,则#define SAMPLE_RATE "16000"这样每次改采样率都要改两处地方,容易遗漏网上搜到第一篇文章,匆忙试了试,并未达到我想要的效果,然后在GNU的官网找到了第二篇文章,看懂了,原来第一篇文原创 2016-01-28 19:15:47 · 22503 阅读 · 2 评论 -
C语言printf函数格式化打印之长整型
有符号长整型 printf("recv %ld bytes audio data!\n", len);无符号长整型 printf("recv %lu bytes audio data!\n", len);跟整型相比,就是在前面加个l原创 2015-12-22 15:18:36 · 18012 阅读 · 0 评论 -
weak symbol的设计意图
简言之,就是一种link-time的overloading原创 2015-04-13 11:44:59 · 1006 阅读 · 0 评论 -
遇到g++的最不靠谱报错!
当表达式是赋值语句时,且左值表达式类型已知,但右值表达式中有未定义类型,此时g++不会报‘类型未定义’,而报‘invalid conversion’先来简单的场景,左值表达式和右值表达式都未定义#include #include using namespace std;int main(){ A a = new A; return 0;}报原创 2015-04-11 21:47:00 · 1324 阅读 · 0 评论 -
静态变量的用处:文件句柄的妥善放置
最近做的一个任务,是在一个线程中不断接收UDP包,并将包dump到文件内代码这么写#include #include #include //Linux system call for thread id#include #include void logMsg(){ int loop = 0; FILE *fp = fopen("/tmp/mo_原创 2014-12-08 20:33:01 · 1170 阅读 · 0 评论 -
Linux下获取线程ID的方法
gettid函数的使用原创 2014-12-06 19:39:16 · 31019 阅读 · 0 评论 -
extern关键字放到函数体内而导致的linkage问题
不要在C++函数体内extern引用C对象原创 2014-11-18 20:55:59 · 2109 阅读 · 0 评论 -
return C++构造函数的返回值
看到这个标题估计大家都很诧异,C++构造函数是没有返回值原创 2014-11-01 16:43:39 · 4967 阅读 · 0 评论 -
Lua调用只有头文件的C++动态库函数
前段时间公司让我寻找一个for C++Lua Binder库,要求能够C++原创 2014-10-15 22:16:24 · 2074 阅读 · 0 评论 -
定义自己的assert语句
C语言的assert函数在判断失败时,会停止程序执行,这在某些场合——比如自动化测试——是非常不方便的,这时只需要打印一个错误提示,然后继续执行后面的 测试项我参考了网上一篇讲述C语言的单井号和双井号在预处理中应用,写了一个自己的实现:#include #inc原创 2011-09-15 22:21:16 · 1007 阅读 · 0 评论 -
用reinterpret_cast将10进制小数转换成16进制单精度浮点小数
先进行名词解释reinterpret_cast是C++里的强制类型转换符。该操作符修改了操作数类型,但仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换。以下这段话摘自csdn网友 gzmhero因为单精度浮点是32bits,而整型一般也是32bits的。所以直接将地址取出,按想要的格式输出即可实现单精度到整型的转化。 我的代码: float x原创 2009-10-27 20:50:00 · 1046 阅读 · 0 评论 -
一道一维数组与二级指针的问题
深信服科技的笔试题问:以下程序的运行结果是多少?#include using namespace std;int main(){ int num[5]={1,2,3,4,5}; cout<<*((int *)(&num+1)-2)<<endl; return 0;} 一开始,我觉得num是个常量整型指针,那么&num就是个二级指针,那么原创 2009-10-22 21:16:00 · 1428 阅读 · 0 评论 -
二维数组的指针访问方法
前几天参加迅雷的笔试遇到了这种题,认真实验了下,代码如下#include using namespace std;const int row = 2, col = 3;int main(){ int a[6][9]; cout << a[row][col] << endl; *(*(a+row)+col) = 10; cout << a[原创 2009-10-21 20:53:00 · 4070 阅读 · 4 评论 -
c++中的负数取整问题
今天在了解纹理映射的wrapping时,突然想知道负数怎么取整,是向上取整还是向下取整?结论是:统一按绝对值向下取整,而后再加上符号(正或者负)。敲了个代码段std::cout原创 2009-09-23 14:16:00 · 12969 阅读 · 1 评论 -
sizeof 操作符的一个注意事项!
先猜猜代码的输出#include int main(int argc, char **argv){ int a[10]; printf("数组a的大小:%d", sizeof(a)); return 0;} 代码的输出结果是“数组a的大小:40”这告诉我们1、sizeof(a) != 4,sizeof求的是数组的大小,不是指针a的大小(4)2、si原创 2009-09-02 19:02:00 · 704 阅读 · 0 评论 -
mysql的C API中的一个极不厚道的陷阱!
#include #include #include mysql.h头文件用到了windows.h,却不包含人家,结果我建了一个控制台工程导入mysql.h后就以为可以连数据库了,结果爆出mysql_com.h的一堆错误,郁闷!MySQL后来者切记,不论你的工程是否是win32的,都得导入windows.h文件,而且必须放在mysql.h之前!原创 2009-05-27 14:57:00 · 640 阅读 · 0 评论