- 博客(23)
- 收藏
- 关注
原创 C语言的位域操作
C语言中的位域(Bit Fields)允许在结构体中定义成员变量占用的位数,从而实现对内存中位的精确控制。这在嵌入式开发、协议解析或硬件寄存器操作中尤为有用。
2025-03-15 09:51:51
556
原创 匿名共用体报错anonymous unions are only supported in --gnu mode, or when enabled with #pragma anon_unions
在另一个结构中声明结构变量,而无需为其命名的嵌套结构称为匿名结构。并且可以像访问包含结构中的成员一样访问匿名结构的成员。匿名结构体/联合体指的是没有命名的结构,因为没有对应的名字,所以也不会直接创建这个对象或者变量,一般都是在嵌套结构中使用。1. 匿名结构体/共用体的定义匿名结构体:在父结构体中直接嵌套一个未命名的结构体,其成员视为父结构体的成员。匿名共用体:在父结构体/共用体中嵌套一个未命名的共用体,其成员共享内存空间,可直接访问。// 匿名结构体 + 匿名共用体示例int id;
2025-03-15 09:36:09
233
原创 运行lvgl代码时,什么函数的调用是一定必须的,或者什么宏定义一定要修改的。从这个角度探索lvgl运行的底层逻辑
4、lv_disp_drv_init(&disp_drv)显示驱动注册函数:需要实现dis_flush_cb回调,将LVGL渲染的像素数据发送到屏幕。2、lv_tick_inc(x):提供时间基准,需要在定时器中断中每隔x毫秒(通常1≤x≤10)调用一次,此函数维护LVGL内部动画、事件处理时的时序逻辑。3、lv_timer_handler():主循环中周期性调用(推荐5~10ms),负责处理渲染、事件分发和定时任务。1、lv_init():LVGL的初始化入口,负责每部数据结构、内存分配和默认的初始化。
2025-02-23 13:46:50
159
原创 为什么FreeRTOS不用显式设置Systick定时器
如果configTICK_RATE_HZ设为1000,每个时间片是1ms,高频率的调度会增加上下文切换次数,可能影响实时性但提高响应速度。:vTaskDelay的参数基于tick数,更高的tick率意味着更精细的延迟控制。:FreeRTOS的软件定时器同样依赖tick中断,高tick率会让定时器回调更准时,但也会增加处理定时器的开销。:在低功耗应用中,频繁的tick中断会阻止CPU进入深度睡眠,影响功耗。:更高的tick率意味着更多的中断,这会增加系统的总体负载,可能导致中断响应时间变长,影响实时性。
2025-02-14 21:16:55
447
原创 使用FreeRTOS时,串口中断设置成NVIC_PriorityGroup_1后,创建的任务就无法被调度执行,这是什么原因呢
问题回顾:我移植好FreeRTOS后,就设置串口中断分组为NVIC_PriorityGroup_1,设置完后发现系统无法调度我之前创建的任务了,就很纳闷。解决方式:中断分组设置成NVIC_PriorityGroup_4就可以了。背后的原因:在FreeRTOSConfig.h中,有一个这样的宏定义👇configLIBRARY_LOWEST_INTERRUPT_PRIORITY` 定义了 FreeRTOS 内部最低的中断优先级。它通常用于确定哪些中断可以访问 FreeRTOS 的 API。
2025-02-12 10:36:30
859
原创 估算freertos任务的栈的大小
/ 50 字节 }如果每个栈帧占用 32 字节,而递归深度达到 10,那么任务的栈空间需求就会增加到 320 字节(不考虑其他因素)。当任务在执行时,函数调用深度(即函数调用的层次)越深,栈上需要存储的内容就越多,因此栈空间需求也就越大。因此,taskFunction 本身的栈空间大约需要:4 + 80 + 4(返回地址) + 4(参数)=因此,func1 的栈空间大约需要:4 + 4(返回地址) + 4(参数)=因此,func2 的栈空间大约需要:4 + 4(返回地址) + 4(参数)=
2025-02-06 11:14:41
1069
原创 python上项目如何生成exe文件
文件夹下),这个其实在生成exe文件时,pycharm的终端上也可以看到这些信息。会列出可能未被正确打包的模块,然后根据提示使用。等参数来解决这些问题(再次生成exe文件时最好把dic文件夹和bulid文件夹删除)-F 将所有相关的文件打包成一个单独的exe文件。python解释器版本:3.8。1、安装pyinstaller。
2025-01-13 21:14:53
185
原创 Text段Data段Bass段和RAM、ROM的关系
ZI-data:表示未被初始化的全局变量和静态变量,这些变量会被自动初始化为0(ZI是 Zero Initialize英文单词的缩写),这部分数据会被放在Bass段中。而我们不是通常还会说在C/C++程序中,编译的程序占用内存分为5个区,分别为栈区、堆区、全局/静态存储区、常量存储区、代码区。RAM:栈区、堆区、全局/静态存储区(这个会在程序烧录的时候存储在ROM中,程序运行时会被读写到RAM中)Data段,存放的是RW-data和RO-data。
2025-01-05 18:52:11
342
原创 内核寄存器PC、SP、LR之间的关系,大白话解释
R15,存储下一个将要执行的指令的地址。每执行完一条指令后,PC寄存器的值会递增,指向下一条指令的地址。这种递增通常与指令的长度有关(例如,在32位系统中,通常是4字节)。R13,SP始终会指向栈的下一个空闲空间的地址,用于存储函数的返回地址当一个函数被调用时,当前的程序计数器(PC)值(即调用后的下一条指令地址)通常被压入堆栈,以便在函数执行完毕后能够返回到正确的位置继续执行。这个操作是通过将PC值推送到SP指向的内存地址来完成的,然后SP的值通常会递减,指向堆栈中的下一个空闲位置。
2024-11-01 15:43:09
1316
原创 TCP握手挥手 精简版和完全版
第四次挥手:客户端收到了FIN报文后,回应一个ACK报文,就进入TIME_WAIT状态,经过2MSL时间自动进入CLOSED状态,客户端关闭连接。第二次挥手:服务端将TCP首部ACK标志位置一,发送ACK报文给客户端,服务端进入CLOSED_WAIT状态。第三次挥手: 服务端把剩下的数据发送给客户端后,也将FIN标志位置一,发送FIN报文给客户端。第一次挥手:客户端打算关闭连接,将TCP首部FIN标志位置一,发送FIN报文给服务端,自身进入FIN_WAIT_1状态。第二次挥手:服务端回应客户端。
2024-10-31 14:09:33
331
原创 Python类中函数__call__()到底是啥意思
在这个示例中,我们定义了一个名为`MyClass`的类,并实现了`__call__()`方法。当我们创建一个`MyClass`的实例并使用它作为函数进行调用时,Python会自动调用`__call__()`方法。在这个例子中,`__call__()`方法接受一个参数`pic`,并打印出`pic`和`value`的值。__call__()方法(也就是我们常说的函数)允许类的实例像函数一样被调用。当您实现了`__call__()`方法并在类的实例上调用它时,Python会自动调用该方法。
2024-02-26 14:54:50
239
1
原创 什么是NumPy数组
什么是NumPy数组NumPy数组是Numerical Python库中的核心数据结构,它是一个多维数组对象,可以存储相同类型的元素。NumPy数组支持高效的数学运算和线性代数操作,因此在科学计算领域中被广泛使用。NumPy数组具有以下特点:1. 数据类型:NumPy数组要求其中的元素必须是同一个类型的,虽然丧失了一些灵活性,却带来的性能的极大提升。2. 内存效率:NumPy的内存效率高,可以比其他库更容易处理大量的数据。3. 方便性:NumPy工作起来非常方便,特别是对于矩阵乘法和重塑。
2024-02-26 10:10:41
1318
1
原创 STM32 keil5 报错:flash download failed-cortex M3解决方法(如果看了很多篇文章都搞不定,就请看这篇)
如果你看了很多篇文章都解决不了这个报错,那我想你的烧录器一定是。反正我也是看了很多篇文章依然解决不了,之后这样搞一下就可以了。然后解决办法是:把以下地方调成under Reset。
2023-10-12 10:41:01
959
原创 两个单片机串口通信HAL库代码&&为何HAL_UART_Receive_IT函数只能触发一次接收中断及对应解决办法
1、主机MCU:STM32F103RCT6;从机MCU:STM32F103ZET62、两个MCU分贝打开串口1和串口2。串口1打印调试信息,串口2用来跨平台通信。
2023-08-24 13:39:25
2387
10
原创 stm32ADC精确电压计算公式详解
1、从理论上看,ST提供的基准电压Vrefint1,和实际MCU得到的基准电压Vrefint2,应该是相等的。2、而Vrefint1 是在3.0V的参考电压下得出的,所以Vrefint1 = 3.0V * (VREFINT_CAL/FULL_SCALE)而Vrefint2 是在不确定的参考电压下得到,这个参考电压也是我们需要的。 所以Vrefint2 = VDDA *(VREFINT_DATA/FULL_SCALE)
2023-08-18 09:12:49
5060
2
原创 300字解释 指针常量和常量指针
所以const int *p 表示可以改变p的方向,但是不可以通过p改变所指向的值,通过其他方式还是可以改变值的。*p代表的是指针指向的值,而p指的是指针本身存的地址值。所以对const p,意思就是把指针本身存的地址值变为常量,换句话来说就是指针的指向固定了(因为指针的指向是有指针本身存的地址值决定的)。int* const p,我们可以尝试加个括号int* (const p),这样我们就发现const针对的是p。*const p 表示可以该改变p指向的值,但是不可以改变p指向的方向。
2023-03-08 09:23:02
79
原创 Unable to locate package libv41-dev
Unable to locate package libv41-dev
2023-03-04 22:11:24
279
3
原创 Linux进程间通信:消息队列
管道通信方式的中间介质是文件,通常称这种文件为管道文件。两个进程利用管道文件进行通信时,一个进程为写进程,另一个进程为读进程。写进程通过写端(发送端)往管道文件中写入信息;读进程通过读端(接收端)从管道文件中读取信息。两个进程协调不断地进行写、读,便会构成双方通过管道传递信息的流水线。
2023-02-27 10:53:22
237
转载 短小精悍解释pthread_cond_wait()
pthread_cond_wait() 用于挂起当前线程并线程会堵塞在当前阶段不会往下走,同时释放互斥锁。在别的线程使用 pthread_cond_signal() 或pthread_cond_broadcast来唤醒后,pthread_cond_wait()就会获取这个互斥锁,如果获取成功,就往下执行。
2023-02-26 21:16:08
168
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人