- 博客(86)
- 收藏
- 关注
原创 Qt QCheckBox 使用
QCheckBox 继承了 QAbstractButton、QWidget、QObject 和 QPaintDevice,父对象的接口都能用,另外独有接口checkState等。
2025-05-10 10:46:57
531
原创 模数转换【1】AD7699
一款可以模数转换芯片,兼容通用 SPI 接口,支持最多支持 8 个通道和 500KSPS 的采样率。支持单个通道采集和扫描采集模式。扫描读取0-3 = 单极性 + IN3 + 全带宽 + 内部基准电压源 + 扫描IN0至IN[7:0]例如读取通道 0 = 单极性 + IN0 + 全带宽 + 内部基准电压源 + 禁用序列器。需要注意的是 需要给定 __weak 的接口,否者读不到数据。配置内部参考电压4.096V,实现单个通道采集和扫描采集模式。同系列的芯片还有 AD7682 和 AD7689 等。
2025-04-21 19:51:17
344
原创 Ubuntu 源码安装 Qt5
Ubuntu 下安装指定版本的 Qt,最新的Qt官方已经不支持 Qt5.15.2 版本以下版本,所以有必要用旧的源码编译 Qt 库。-nomake examples 和 -nomake tests:不编译示例和测试。-prefix /opt/Qt5.12.2:指定安装路径。-confirm-license:自动确认许可协议。-qt-xcb:使用 XCB 作为 X11 后端。源码安装 Qt5.12.2。目标版本:Qt5.12.2。-opensource:选择开源版本。-release:编译发布版本。
2025-03-11 20:00:03
372
原创 根文件系统 Debian10【2】基础功能配置
(8)root ssh 登录配置 修改 /etc/ssh/sshd_config 追加 PermitRootLogin 配置。(2)添加高速源,访问外网还是没有内网快,修改 /etc/apt/sources.list。(6)初始系统可以上网,但是没有 ifconfig 等命令行软件,需要安装对应的工具。修改 /etc/profile,追加路径 /usr/sbin。(2)修改 /etc/hosts,追加主机名 rk3568。(1)修改 /etc/resolv.conf。(3)命令行设置主机名。
2025-02-10 17:53:19
294
原创 根文件系统 Debian10【1】移植
一般根文件系统使用 Busybox 或者是 Buildroot 构建,这样构建出来的文件系统比较小,但是不具备上网功能,扩展性比较差。随着 ARM 的日益强大,ARM 可以搭载更庞大复杂的系统,可以是 Ubuntu 或者 Debian 等发行版本。最初构建的文件系统密码是不知道的,如果直接挂载到板卡上也进不去,所以需要修改密码和添加必须的用户,我们可以使用 chroot 从开发端直接进入文件系统。下载最新的 Debian10,即 Debian10.13,移植系统成功在板卡上运行。板卡芯片:RK3568。
2025-02-08 18:00:32
464
原创 Qt 数据库SQLite 使用【01】基本功能
Qt 开发过程中难免需要存储数据,可以选择保存到本地文件,但是查找比较麻烦,所以就有了数据库,主要是方便查找数据,增删改查等操作,而 SqLite 属于数据库中轻量级的存在,适合本地数据存储功能。主要是可以查看数据库的实际情况,使用方法如下,可以看到写入的字段。可以实现基本的增删改查,还可以,数据库的操作需要熟悉数据库语句。Qt 界面上管理数据多个表的数据增删改查。xxx.pro 文件添加 sql 模块。
2025-02-07 16:53:53
533
原创 STM32F407 越界问题定位【2】CmBacktrace
屏蔽原代码中的 HardFault_Handler 函数,cmb_fault.S 中使用了 HardFault_Handler 函数,保存关键寄存器后跳转到 cm_backtrace_fault。由于源代码 CmBacktrace 只打印一次,如果出错时没有接串口,可能会错过问题的复现,所以这里稍微修改源码 cm_backtrace.c,保证持续打印错误信息。(4)CMB_CPU_PLATFORM_TYPE # 选择 CPU 平台,STM32F4 的 CPU 是 M4 架构。
2025-02-05 18:04:20
815
原创 Python 基础篇【02】模块安装
Python 安装了基础环境后,只具备基础功能,使用 Python 更多依赖 Python 支持的依赖库,使用别人的轮子来快速开发功能。搭建 Window 和 Linux 下安装模块,以 numpy 为例。Linux 下如果存在多个 python 版本,可以指定版本安装。
2025-01-09 14:46:43
210
原创 Python 基础篇【01】安装开发环境
解压 -> 进入文件夹 -> 配置安装(默认)-> 编译并安装,make install 可能需要权限 sudo。添加 PATH,免得后面麻烦,毕竟后面需要命令行操作,其他的默认就行,可以自行选择路径。Python 是一种快速开发的语言,由于当下使用人比较多,支持库丰富,可以学习使用。打开命令行 cmd,输入python,显示版本即安装成功。下载得到文件 amd64 安装包,选择稳定版本即可。搭建 Window 和 Linux 下开发环境。直接命令行下载安装包,并解压。
2025-01-09 13:35:22
751
原创 Linux C 程序 【05】异步写文件
其中常用的写文件方式是同步写操作,但是如果是写大文件会对 CPU 造成比较大的负荷,采用异步写的方式比较合适,并且需要直接越过内核,直接通过 IO 访问,直接访问磁盘,关键词 O_DIRECT。Linux 系统提供了各种外设的控制方式,其中包括文件的读写,存储文件的介质可以是 SSD 固态硬盘或者是 EMMC 等。异步写硬盘速度更快,并且 CPU 占用更低,只有不到 20%,同步写硬盘 CPU 占用超过 90%1)使用同步写硬盘的方式连续 100MB 的数据 10 次并统计每次写入的时间和速度。
2024-12-16 19:53:26
333
原创 FreeRTOS【18】系统运行监控
基于 FreeRTOS 的学习已经接近尾声,事实上看似没问题的任务可能存在分配合理的地方,某个线程任务长期占用控制器,甚至是线程任务的内存已经开始慢慢泄漏并且越界使用,如果全然不知可能导致程序崩溃。代码中使用了 2 种方法获取任务的运行时间,不推荐使用 vTaskGetRunTimeStats,因为返回的数据是一大段字符串,很容易出现内存溢出,当然带来的好处就是显示清晰明了。理论上应该使用更高的时钟去监控系统的行为,这里只是要粗略估算 CPU 的使用率,所以直接使用了系统时钟,计算比较粗糙。
2024-12-06 10:02:18
481
原创 温湿度传感器【1】HDC1080
如上图所示为可读写的寄存器,其中 0xFB~0xFF 是读取 ID 相关的,可以上电后读取 ID 判断芯片是否存在。0x00 可以读取温度,0x01可以读取湿度,0x02主要是写配置信息。但是这里涉及到一个问题,就是采集数据是需要时间的,不是立刻就能采集到数据的,根据不同位数的采集时间,采集数据需要几毫秒到十几毫秒不等。一款可以检测环境温度和湿度的传感器,外部接口是通用 IIC 接口,并且采集数据的速度比较有限,特别是数据的位数比较高的情况下,需要毫秒级别的等待时间。,这样是一直采集不到数据的。
2024-11-14 09:18:54
571
原创 FreeRTOS【17】常用功能使用
上述是部分源码,可以看出 xPortSysTickHandler 中断调用 xTaskIncrementTick,进而实现每次中断 xTickCount 递增,并且当 xConstTickCount 递增到 0 时(计数器16位或者24位)会触发xNumOfOverflows溢出计数递增。基于 FreeRTOS 熟悉使用其他 API 接口。获取局部变量或者使用。
2024-10-10 09:30:30
431
原创 Zynq7020 SDK 初学篇(5)- 中断
PS 和 PL 按键输入中断,并输出对应的日志打印。基于上一个篇章 GPIO 使用,引入中断的使用。
2024-09-10 14:06:48
901
原创 Zynq7020 SDK 初学篇(4)- PL 端 GPIO
事实上通过 EMIO 复用和 MIO 使用方法一样,唯一需要注意的是 GPIO 的映射关系,所以GPIO从54 - 56。由于 PL 端不像 PS 端一样绑定 GPIO,所以需要对上面的 3 个 GPIO 绑定引脚 RTL IO。基于 PS 端 GPIO 的基础上,如何调用 PL 端 GPIO 的输入输出。PL 端按键控制 PL 端 LED。这里设置 PIO 数量 3 个。
2024-09-09 19:59:08
554
原创 紫光同创PDS自动构建
随着开发进度的不断迭代,需要对代码实行管控,FPGA代码管控也很重要,这个篇章主要是对紫光同创 PDS 开发环境下实现代码自动构建功能。powershell 脚本 build.ps1,主要实现将 sbit 文件转换成 sfc 文件。bat 脚本 build.bat,主要使用 pds_shell.exe 工具实现编译功能。1) 点击 build.bat,执行编译。2)工程路径和环境安装目录可配置。3)编译生成 .sfc 烧录固件。1)点击一个脚本自动编译工程。
2024-09-03 15:58:16
672
原创 Linux C 程序 【04】线程分离
线程的的创建可以分为 joinable 和 detached 共 2 种状态,其中 detached 属于分离状态,线程的创建模式是可结合状态,即 joinable,这种情况下线程结束后需要调用 pthread_join 回收资源,否则有出现内存溢出,同时 pthread_join 也起到了等待线程执行完成的功能。使用 top 查看内存变化如下,一直递增,由于 top 并非事实刷新,只能看到内存的变化趋势。至于 detached 状态指的是线程分离,即不需要特意调用线程回收功能,线程结束后自动回收。
2024-08-09 13:44:43
254
原创 Linux C 程序 【03】线程栈空间
代码里递归函数 recursive_function 每递归一次消耗 1024KB 内存,完成了 0 - 6 共 7 次递归,第 8 次递归直接越界,产生段错误,内存溢出。由测试结果可知,线程的内存堆栈是可以设置的,而且有最小值,这里的最小内存是 128KB,小于128KB的按照默认大小 8192KB 配置。上一个篇章创建了线程,参考 FreeRTOS,每个线程都是有自己的内存空间,Linux上面也是一样的,这个篇章主要描述线程栈空间的设置。1)创建线程,并配置线程内存大小。
2024-08-07 20:04:57
663
原创 MDK Keil5 关键配置
针对 MDK 界面配置功能的记录,特别是在重新移植工程时出现各种问题,这里记录一下。建议勾选,不勾选出现:下载代码不运行,在线调试却可以运行。建议勾选,不勾选出现:使用dwt定时器第一次下载程序卡死。
2024-08-07 09:08:10
550
原创 Linux C 程序 【02】创建线程
上一个篇章,基于 RK3568 平台的基础上,运行了最简单的程序,然而我们使用了 Linux 系统,系统自带的多线程特性还是比较重要的,这个篇章主要描述线程的创建。进程号相等 12025,线程号不等,测试OK。创建一个线程,主程序等待线程运行。
2024-06-27 15:37:21
485
1
原创 Linux C 程序 【01】最小程序
由于 RK3568 作为宿主机,在上面编译程序比较慢,所以还是采用在 Ubuntu 下交叉编译后再拷贝到宿主机上运行。基于 RK3568 平台的基础上,编译一个在系统上运行的最小程序。Makefile 的创建和使用参考 Makefile 篇章。编译代码后自动发送到目标机,这样就可以直接测试程序了。1)搭建 Makefile。2)创建一个最小运行程序。本章的测试源代码很简单,不涉及功能。
2024-06-27 14:02:00
406
原创 FreeRTOS【16】直达任务通知使用
事实上本人使用得比较少,常用的项目内存都比较多,对响应时间也没有特别苛刻,需要快速响应的最好还是硬实时中断。直达任务通知,FreeRTOS 的线程任务提供的接口,可以用作线程唤醒,或者是传递数据,因为是基于线程本身的操作,是轻量级,速度响应更快,适合小内存芯片使用。ulBitsToClearOnExit 写入 0xFFFFFFFF 在成功触发后清除所有位。ulBitsToClearOnEntry 写入 0xFFFFFFFF 在调用前清除所有位。
2024-06-03 14:32:54
452
原创 FreeRTOS【15】事件组使用
其中信号量可以实现线程同步,对标的是裸机的 Flag 标识,但是在裸机中经常使用的不止一个标识,如果用二值信号量去实现无疑是增加了系统内存开销,申请多个信号量,实现本质是队列,消耗比较大并且带有迟滞性,所以 FreeRTOS 针对这种情况设计了事件组。事件组是按 bit 操作的,每一个位都可以触发事件,需要注意的是时钟的配置会影响可用的位配置,源码解释如果设置 configUSE_16_BIT_TICKS 系统时钟 16 位,只能用 0~7bit,否则可以使用 0~23 bit。设计试验2:位事件同步。
2024-06-03 11:42:08
577
原创 FreeRTOS【14】软件定时器使用
基于以上的章节,这个篇章主题是软件定时器使用,能使用 FreeRTOS 的基本都是从裸机 MCU 过来的,基本都知道 MCU 最基本的功能之一就是定时器,确切的说是硬件定时器,外围电路已经构建好的,精度很高,基本都是微秒级别定时,稳定性也不错,唯一的缺点就是资源太少,定时器的数目有限。既然实现的方式是线程,那就必须配置线程的参数,例如线程优先级考核堆栈大小,定时器的回调函数实际是运行在定时器线程中的,注意堆栈大小,如果想要定时器回调快速响应就需要提高优先级。注意查看的是,打圈的就是软件定时器控制线程。
2024-06-01 15:08:04
581
原创 FreeRTOS【13】流缓冲区使用
其中,队列的使用规定了队伍成员的大小,然而现实使用场景下,很多数据不都是定长大小了,例如不定长的通讯协议亦或者是缓存日志信息,如果在这种场景下使用队列传递信息显然不合适,会导致队伍中空间没有利用起来。创建流缓存区还需要注意的是,触发的字节数 xTriggerLevelBytes,接收数据的时候需要达到触发字节数才会触发接收,一般设置为 1 即可。:流缓冲区相对于队列没有设置临界区保护,只有一对一传输才是安全的,一对多或者多对多需要自行进入临界区保护。3)接收线程接收流缓存区的数据。
2024-06-01 11:26:46
546
原创 FreeRTOS【12】队列集使用
基于以上的章节,了解了 FreeRTOS 多线程间的信号量、队列的使用,已经满足了日常使用场景。这个篇章要介绍的是队列集,实际上队列的升级版,存储信号量和队列等的触发事件。队列集在实际的开发项目中应用相对比较少,事件存储在队列中,在一定程度上影响了系统的实时性,优点就是一个线程处理多种事件,减少了线程的个数,适合资源使用比较少的场景。1)创建 2 个线程,控制线程和接收线程。3)接收线程接收队列集后再获取对应的信息。2)控制线程发送不同的信号量和队列。
2024-05-31 14:38:59
377
原创 FreeRTOS【11】递归互斥锁使用
基于上一个篇章,解释了 FreeRTOS 的互斥锁,可以看出互斥锁是可以保护资源访问的完整性,但是,随着代码的复杂程度提高,有可能存在代码段递归的情况,这样就有可能会出现多次上锁的情况,而 FreeRTOS 提供了递归上锁的操作,即一个锁可以在一个线程中多次上锁,只有解锁同等次数才能真正解锁。实际上,递归互斥锁是互斥锁的一种特殊形态,类似计数信号量和二值信号量的关系,当然,递归互斥锁拥有和互斥锁相同的特性,那就是优先级继承。2)其中一个线程多次上锁后解锁同等次数。3)另一个线程等待多次解锁完成。
2024-05-30 14:29:03
368
原创 FreeRTOS【10】互斥锁使用
【如果另一个更高优先级的任务尝试获取相同的互斥锁, 则将暂时提高“获取”互斥锁的任务的优先级。这意味着必须始终“归还”互斥锁,否则 优先级较高的任务将始终无法获得互斥锁,而优先级较低 的始终无法“取消继承”优先级。FreeRTOS 提供了多线程控制,并且是支持高低优先级抢占,这就意味着低优先级线程在执行任务时有可能被高优先级线程打断,如果两个线程共同操作同一个资源可能会导致不可意料的结果,因此,访问共享内存时需要添加互斥操作,因此互斥锁就有了。4)等待高优先级线程获取互斥锁后,再获取当前线程优先级。
2024-05-30 11:09:02
867
原创 FreeRTOS【9】计数信号量使用
FreeRTOS 基于上一篇了解了二值信号量后,如果需要设计需要累计信号量的次数就不行了,所以有了计数信号量,可以设置计数的最大值。同样,可以理解二值信号量是计数信号量的一种特例,即二值信号量是计数信号量最大计数为1时的特例。由上图和代码可以分析,本实验设置最大信号量值为5,发送的信号量次数为10,实际上计数信号量累计到最大计数值就不会继续累计了。2)发送线程发送多个信号量,信号量个数大于计数信号量的最大值;1)接收线程一直等待信号量唤醒;3)按键中断发送信号量;
2024-05-29 15:14:20
329
原创 FreeRTOS【8】二值信号量使用
FreeRTOS 提供了队列可以在线程间快速交换信息,那么还有没有其他交互渠道?答案是有的,相对于队列传递信息,还有更轻量级的线程唤醒操作,那就是信号量,而二值信号量就是最简单的一种。二值信号量就是二进制的 0 和 1,或者是 bool 类型的 true 和 false,二值信号量代替了传统编程中的循环等待。1)接收线程一直等待信号量唤醒;2)发送线程发送信号量;3)按键中断发送信号量;
2024-05-29 14:44:49
461
原创 FreeRTOS【7】队列使用
问题就来了,为了提高子线程的响应实时性,需要频繁判断,导致CPU占用率极高,显然这样的设计是不合理的,所以队列的存在就变得合理了。操作系统提供了多线程并行的操作,为了方便代码的维护,各个线程都分配了专用的内存并处理对应的内容。但是线程间也是需要协助操作的,例如一个主线程接收信息,会把接收的信息并发到其他线程,即主线程不阻塞,子线程做实际的处理。FreeRTOS 的队列传递信息采用的是内存拷贝,队列在接收信息的时候会阻塞线程,释放CPU,降低 CPU 的使用率,相当于线程间信息的交互交给内核去统筹。
2024-05-29 13:49:24
1186
原创 FreeRTOS【6】线程优先级
如图在第 0 秒,线程 0 和线程 1 具备相同的优先级,就算线程 0 不阻塞,系统也会定时切换到线程 1,在第 3 秒时提高的线程 0 的优先级,线程 1 无法继续运行,直至第 6 秒的时候降低了线程 0 的优先级后线程 1 才可以继续运行,符合设计预期。2)控制线程在 3000ms 后将线程 0 优先级设置为 2,再过 3000ms 将线程 0 优先级设置为 0,这里涉及到的接口有获取线程优先级的 uxTaskPriorityGet,设置优先级接口 vTaskPrioritySet。
2024-05-15 19:57:49
525
原创 FreeRTOS【5】线程阻塞
其实在上一篇已经使用了线程阻塞,如果高优先级线程一直不阻塞占用 CPU,程序会直接卡死在高优先级线程中,常用的阻塞方式 vTaskDelay,这个在 FreeRTOS 中非常常用,需要配置宏 INCLUDE_vTaskDelay。由于我们设置的时钟节拍是 1ms,而 vTaskDelay 的输入参数就是时钟节拍,FreeRTOS 的参数基本都是以时钟节拍为单位,如果时钟节拍不是 1ms,则需要注意换算。3)控制线程定期解除阻塞,这里引入了一个接口 eTaskGetState,可以获取指定线程的状态。
2024-05-15 15:29:07
1142
原创 FreeRTOS【4】线程挂起和恢复
Blocked:即阻塞态,因为线程存在高低优先级,如果高优先级线程一直运行会导致低优先级线程一直抢占不到 CPU 的使用权,如果使用挂起的方式去挂起高优先级线程,那么高优先级线程的实时性就会大打折扣,所以就引入了阻塞的概念,高优先级线程可以一直阻塞在某个事件,在阻塞期间会让出 CPU 的使用权,但是一旦高优先级线程满足指定事件就会立刻抢占低优先级线程的 CPU 使用权,这样就保证了高优先级线程的实时性。1)线程删除后会释放内存,由于现在的线程都是在系统堆栈动态开辟的,所以线程删除后内存会回归系统内存堆栈。
2024-05-14 20:43:19
1699
原创 FreeRTOS【3】任务线程创建
一般情况下掌握动态创建线程即可,但是有时候我们需要创建多个线程,而且线程的工作内容都基本相同的情况下,为了充分提炼相同代码,多个线程共用一个函数,可以通过传参来区分不同的线程,需要注意的是传参参数(pvParameters)需要常驻内存,否则后续线程访问指针会获取到错误信息。FreeRTOS 创建任务现成的方法有 2 种,动态创建和静态创建,动态创建交由系统统一管理内存,而静态创建则需要使用者指定线程使用的内存区域,创建方法更加原始和繁琐,不推荐使用。这个是线程句柄,后续可以通过句柄实现线程的挂起和删除。
2024-05-13 15:24:06
1724
原创 FreeRTOS【2】配置文件
configTOTAL_HEAP_SIZE 配置分配给系统的堆栈大小,芯片的 RAM 会分出一部分给到系统,如果配置的内存比较小,可能会导致任务创建失败甚至是系统启动失败,分配过大会导致芯片剩余 RAM 不足,单位是 /Bytes。configMAX_PRIORITIES 配置最大优先级,这里设置的是10,能用的优先级为 0~9,最大的设置值为 32,其中空闲任务的优先级为0,如果系统处于空闲状态,PC 指针会一直在空闲任务中打转。上面的配置有部分是必须的,FreeRTOS 中会标定。
2024-05-11 16:45:46
521
原创 FreeRTOS【1】简介和移植
基于微型控制器程序的开发,最开始是裸机开发,即所有的事务都是在 while(1) 循环中实现,实际上 CPU 大部分的时间都在做循环操作,性能没有完全利用起来,代码的可维护性也不足,所以操作系统(OS)应运而生,由于微型控制器实时性要求,有了实时操作系统(RTOS)由于我这边是 MDK 环境所以选择 keil 参考工程并打开,打开工程发现,例程配置如下,tasks.c、list.c、queue.c、port.c、heap_x.c,其中 heap 可以选择多种模式。工程移植参考这个即可。
2024-05-10 20:32:07
532
原创 Linux cmake 初窥【3】
基于上个试验的基础上,增加了动态库 LibShare 和 静态库 LibStatic。基于上一篇的基础上,已经实现了多个源文件路径调用,但是没有库的实现。LibShare CMakeLists.txt,主要是负责管理动态库源文件。LibStatic CMakeLists.txt,主要负责管理静态库源文件。首先还是解析顶层的 CMakeLists.txt,指定了链接库文件。基于 cmake 的动态库和静态库的调用。最后介绍一下 main.cpp 文件。先编译动态库,再编译可执行文件。
2024-05-08 20:34:52
289
原创 Linux cmake 初窥【2】
顶层脚本 compile.sh 负责执行 cmake 操作,顶层的 CMakeLists.txt 很关键,指定了源文件路径,其中每个文件夹中都放置了一个CMakeLists.txt 文件,语法要求,否者会报错。func 中的函数就是 Func_Test();和 Func2_Test();基于 cmake 指定源文件目录可以是多个文件夹,多层目录。基于上一篇的基础上,再次升级。顶层 CMakeLists.txt。
2024-05-07 20:34:36
455
原创 Linux cmake 初窥【1】
linux 下编译程序需要用到对应的 Makefile,用于编译应用程序,但是 Makefile 的语法过于繁杂,甚至有些反人类,所以这里引用了cmake,cmake 其中一个主要功能就是用于生成 Makefile,cmake 的语法更友好。主要包括 main.cpp、func.cpp 和 func.h,当然还是少不了 cmake 的关键脚本 CMakeLists.txt,CMakeLists.txt 主要是用来描述工程结构。执行到这里,我们可以进入 build 文件夹下执行熟悉的 make 操作了。
2024-04-22 20:32:00
212
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人