自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 嵌入式学习笔记 - 瑞萨单片机

能够直接与故障源链接,故障源不需要再通过CPU处理再去控制PWM输出。简单来说就是在一些外设输出功能上如PWM输出上,这条通道能够直通输出门电路。瑞萨单片机的POE0,额外添加一条控制通道,

2025-10-21 18:37:43 122

原创 嵌入式学习笔记- 单片机的低功耗以及唤醒

为了省电,单片机可以进入如Sleep、Stop、Standby等低功耗模式。在这些模式下,CPU核心时钟可能会停止,但某些外设(如串口、定时器)的时钟仍然可以运行。某些外设时钟可能停止,也可能运行,这要取决于不同的单片机的硬件设计。

2025-10-13 14:59:27 307

原创 嵌入式学习笔记- 关于电容的纹波电流

纹波电流是导致电解电容发热、影响其寿命的关键交流电流成分。它不是一种特殊的电流,而是电路中必然存在的现象。要重视,不能忽视。必须保证电路中的纹波电流 < 电容的额定纹波电流。电容鼓包爆浆,要怀疑是否是纹波电流过大或电容ESR变大所致。希望这个解释能帮助您彻底理解这个概念!二 电容纹波电流与频率的关系在大多数情况下,频率越高,电容所能承受的额定纹波电流值越大。【个人理解:因为频率越低ESR越大,具体见第三节ESR与频率的关系】下面我为您详细解释为什么会这样,以及在实际应用中如何考虑。

2025-09-20 12:03:50 978

原创 芯片管脚的源电流与漏电流

特性源电流漏电流中文别名拉电流灌电流电流方向从芯片流出流入芯片常见工作状态输出高电平输出低电平数据手册符号典型值-20mA (绝对值20mA)+20mA (绝对值20mA)形象比喻水龙头(出水)地漏(吸水)

2025-09-19 18:08:43 969

原创 嵌入式学习笔记之位域操作-为什么中断操作变量不可用位域

位域是C和C++中的一种特殊结构体成员,它允许你定义一个占用特定位数的成员,而不是整个字节或字。这样做的目的是为了节省内存。c// 只占1个比特// 只占1个比特// 占6个比特操作普通变量 (e.g.,uint8_t位域 (Bit-field)单条指令可能(如对齐的8位写入)几乎不可能(需要修改字节中的特定位)操作本质可能是原子的一定是“读-改-写”,非原子中断安全通过关中断可以变得安全极不安全,即使关中断,如果在多个地方操作同一字节的不同位域,也会互相干扰原子操作有标准支持(C11。

2025-09-19 13:43:24 653

原创 C51单片机的位寻址操作和位域操作不是一回事

C51单片机的位寻址操作和位域操作虽然都涉及对单个二进制位的操作,但它们是不同的概念和技术实现方式: 理解:位寻址区是一段可以支持单bit访问的内存空间,是硬件上支持,并且使用时要使用相应的汇编指令以及正确的地址,或者使用操作特殊寄存器的方式实现。示例一:使用汇编指令实现位寻址操作SETB 20H.0, 这里的 SETB就是位操作指令,使用了这个指令硬件就会操作位寻址区, 同时操作对象20.H也需要是位寻址区,不然就会发生错误。示例二: 通过操作特殊寄存器SFR的方式实现位寻址操作理解

2025-08-16 08:17:57 854

原创 嵌入式学习笔记- 结构体名字被赋值时是整体内容赋值

赋值后两个变量拥有相同内容,但占据独立的内存空间。// 复制 s1 的所有成员值到 s2。是同类型结构体变量),系统会‌。结构体变量名被赋值时,‌。

2025-07-15 17:29:52 297

原创 嵌入式学习笔记 - 指针模拟数组名

当一个指针指向一个数组时,可以用指针模拟数组的行为,指针可以使用下标运算符。等价于 *(ptr+1)

2025-07-15 17:24:04 125

原创 嵌入式学习笔记 - MSC8051单片机程序下载代码设置问题

MSC8051架构的单片机比如SH79f6441可以通过程序下载器,通过代码设置选项设置一些参数,不一定非要通过程序修改寄存器的方式来实现对单片机的初始化设置,比如EEPROM的OP_EEPROMSIZE 大小以及 初始化数据都可以通过程序下载器,下载时通过代码设置来设置,不一定要通过程序本身控制寄存器的方式去修改。

2025-06-21 21:07:54 137

原创 嵌入式学习笔记 - 关于KEIL5,KEIL4版本,ESP8H0183工程无法找到芯片包问题

问题描述:电脑上同时安装了KEIL ARM以及KEIL C51,都是KEIL5版本,有一个新的工程,使用硬件为 EASTSOFT(东软) ESP8H0183芯片,是一款cortex M0内核的芯片,但是每次打开还是提示无法找到芯片包,但是打开别的M0的工程可以找到芯片包,于是怀疑是工程本身问题,仔细查看此工程,发现此工程是KEIL4版本,而之前安装的芯片支持包是keil5的芯片支持包,重新下载keil4版的芯片支持包后问题解决。但是此次遇到的问题,keil5没有给出解决提示,只是提示找不到芯片包。

2025-06-18 10:17:58 273

原创 嵌入式学习笔记 - KEIL 提醒missing compiler version 5

需要下载相应的编译器,或者copy旧版本的编译器,复制到keil安装目录下keil->ARM->ARMCC文件夹。下方的ARMCLANG就是自带的version6版本编译器。KEIL 从5.37版本以上不再附加compiler version 5的编译器取而代之是verion6 编译器,若旧版的程序需要使用version5编译器,在ARM Compiler标签添加ARMCC路径。完成此步骤后还需要配置keil环境。然后找到相应的文件夹添加进去即可。最后记得选择相应的编译器。

2025-06-17 18:41:37 417

原创 嵌入式学习笔记 - SH79F6441串口初始化时为什么TX必须输出高

UART协议规定:‌空闲状态(无数据传输时)的 TX 线必须保持高电平(逻辑 1)若空闲状态为低电平,那么会被接收方误判为起始位,造成通信错误。2.起始位的识别机制。

2025-06-16 10:40:35 221

原创 嵌入式学习笔记 - 0X01^0XFF中符号^是什么意思

在表达式0X01^0XFF中,符号 ‌^‌ 表示 ‌‌ 运算。

2025-06-16 10:15:15 183

原创 嵌入式学习笔记 - SH79F6441 堆栈栈顶可以是片上内部RAM(00H-FFH)的任意地址怎么理解

SH79F6441的片上内部RAM包含256字节(00H-FFH)和外部扩展的2816字节RAM。堆栈操作默认使用内部RAM区域,其地址空间为00H-FFH。若使用扩展RAM(>FFH),需通过特殊指令(如MOVX)访问。堆栈栈顶可以是片上内部RAM(00H-FFH)的任意地址)建议从30H(用户RAM区起始地址)开始分配栈空间。需结合具体应用场景评估栈深度需求,避免运行时溢出。8051兼容架构,栈生长方向为‌。

2025-06-15 20:51:19 305

原创 嵌入式学习笔记 - HAL库对外设的封装

② 第二个变量一般为结构体Init,这个结构体是一个很多参数的集合如下图,在初始化外设函数HAL_xx_INIT()执行之前时,HAL会将外设结构体句斌的Init成员的这些参数赋值,这个句柄结构体的第一个成员Instance(xx_TypeDef类型)一般为该外设的所有寄存器的起始基地址,在初始化外设函数HAL_xx_INIT()执行之前时,HAL将这个变量(指针)赋值为该外设的基地址。第二个成员Init(xx_InitTypeDef类型)一般为该外设的设置的需要设置的参数,

2025-06-14 18:04:24 495

原创 嵌入式学习笔记 - C语言访问地址的方式,以及指针的进一步理解

/将结构体变量的地址赋值给指针,结构体的名字不能作为地址,需使用&符号。如果不使用类型转换,自增的步长会默认为指针变量的类型大小,因为定义指针的时候肯定要定义类型。//将数组a的地址赋值给指针,数组名可以代表地址,或者p=&a[0];嵌入式系统中对一个具体内存地址的访问,通常需要使用指针(指针变量)的方式进行。如果你强制类型转换的对象是一个地址,那么必须使用的方式,以上语句是c语言中定义一个指针(指针变量)的方式。这种直接给指针赋绝对地址值的写法是合法的语法,//将变量a的地址赋值给指针。

2025-06-11 19:58:44 423

原创 嵌入式学习笔记 - C语言中结构体的定义,以及结构体变量的内存空间的分配

‌定义结构体‌:在C语言中,通过struct关键字定义结构体。char name;int age;这个定义只是声明了一个名为Student的结构体类型,并没有分配内存空间。通常所说的结构体是指结构体类型。结构体变量才是真正的结构体。‌分配内存‌:创建结构体变量时,系统会为其分配内存空间。// 分配内存空间给stu1此时,stu1占用的内存空间包括name数组和age变量所需的空间。

2025-06-11 19:17:27 375

转载 从keil官网下载DFP(芯片支持包)的方法

Database 的意思是数据库,资料库,Device Database就是设备资料库。DFP的意思是Devices Family Packs 设备系列包。5.选择我们使用的芯片(我这里使用的是STM32L051系列)3.选择MDK-ARM会进入到MDK下载页面。2.点击右上角的下载按钮,进入下一页面。4.选择左下角的芯片列表按钮(7.在右上角选择下载DFP文件。这里我们不用下载MDK。6.然后选择DFP(

2025-06-10 14:33:26 612

原创 嵌入式学习笔记 - freeRTOS为什么中断中不能使用互斥量

如上图,任务①,②,③优先级依次升高,任务①与任务③共用一个信号量资源,入过某一时刻任务①拥有了这个共享资源,任务③要处于阻塞状态等待任务①,假设此时不需要共享资源的任务②时间到了,则会打断任务①,那么任务①的释放信号量的时间将会更长,那么高优先级的任务③就很长时间得不到执行,这显然不符合优先级机制。任务③会将任务①的优先级提升到任务③一样的值,那么任务①会一直运行不会被中间级别优先级的任务打断,这就大大缩短了任务①释放共享资源的时间,如下图。关键就在发起人,就是提升优先级的那个时刻是谁要求的。

2025-06-08 12:01:30 459

原创 freeRTOS 互斥量优先级继承机制函数实现xQueueGenericReceive()

以下为函数接收互斥量,互斥量不为空(未被别的任务持有),去除互斥量,并且将互斥量的持有者付志伟当前任务,紫色字体函数peeked. *//*lint!else。

2025-06-07 20:55:52 731

原创 嵌入式学习笔记 - freeRTOS vTaskPlaceOnEventList()函数解析

/将当前任务的事件属性插入消息队列等待插入链表。//将当前任务的状态属性部分插入延时链表。函数第一个参数为消息队列等待插入链表,这种设计实现了事件与状态管理的分离。也就是说一个任务有两个属性,就绪列表,延时列表,挂起列表。另一个是事件属性,可能位于。一个是状态属性,可能位于。

2025-06-07 13:00:00 498

原创 嵌入式学习笔记 - freeRTOS xTaskResumeAll( )函数解析

如果configUSE_PREEMPTION 定义为 0,就不进行任务切换同时xAlreadyYielded也不赋值为1,就是记录为没切换过,可能是因为这种情况下taskYIELD_IF_USING_PREEMPTION()未定义(如下图所示),默认为taskYIELD_IF_USING_PREEMPTION()不起作用,所以不对xAlreadyYielded。// 返回是否切换过的标志,如果未切换过,出去后是一定要切换的,因为将当前任务加到等待插入列表,以及延时列表之后,是一定要切换任务的。

2025-06-07 12:13:46 1150

转载 freeRTOS 函数xTaskCheckForTimeOut解析

否则,如果`xElapsedTime < *pxTicksToWait`:(如果`xConstTickCount < pxTimeOut->xTimeOnEntering`,那么`xElapsedTime`必定会大于`*pxTicksToWait`,所以不会选择这条分支)(仅开启vTaskSuspend)如果等待时限为无限时长(`*pxTicksToWait == portMAX_DELAY`),则应该返回`pdFALSE`(`xReturn = pdFALSE`)。

2025-06-07 10:03:14 114

原创 嵌入式学习笔记 - FreeRTOS 信号量以及释放函数

‌二值信号量‌:主要用于任务同步和互斥访问。它只有两个状态:信号量被占用(0)和信号量未被占用(1)。二值信号量没有优先级继承机制,适用于同步任务或中断‌12。‌互斥量‌:也称为互斥信号量,主要用于互斥访问共享资源。互斥量的初始值为1,表示资源可用。互斥量具有优先级继承机制,适用于需要保护共享资源的场景,确保同一时间只有一个任务可以访问该资源‌45。

2025-06-06 23:17:27 532

原创 嵌入式学习笔记-freeRTOS taskENTER_CRITICAL(_FROM_ISR)跟taskEXIT_CRITICAL(_FROM_ISR)函数解析

第①处按照系统设定的configMAX_SYSCALL_INTERRUPT_PRIORITY值对中断进行屏蔽第②处调用一次自增一次第③处检查中断状态寄存器位,如果有任何中断位置1,说明是在中断中,那么报错,因为此函数不允许中断中使用。第①处如果前面有过一次以上调用taskENTER_CRITICAL,那么仍然禁止中断configMAX_SYSCALL_INTERRUPT_PRIORITY值以上的中断都不能开启,直到最后一次退出才真正退出,

2025-06-06 23:16:02 1669

原创 嵌入式学习笔记- freeRTOS 带FromISR后缀的函数

因为中断中等待的,一般都是任务给予的,比如消息队列,信号量,而isr中断运行优先级又高于任何任务,要尽早结束中断让系统任务运行起来才有可能尽可能快的得到想要的消息,不然任务中断都会很被动的运行甚至拖死,任务得不到运行发不出消息,中断得不到消息。其实没有必须,只是因为合适,中断中不可能进行任务切换,放在中间也可以但是也不会立即切换,放在末尾能够确保中断尽快完整的运行结束,确保对信号量消息队列的关键操作全部完成再判断是否进行切换,比较符合逻辑,可能造成上下文混乱,这个只是猜测,这个问题有答案的欢迎留言。

2025-06-06 14:04:58 339

原创 freeRTOS xQueueGenericSend以及xQueueGenericReceive函数疑问

freeRTOS 将当前任务添加到队列的等待接收列表以及阻塞延时列表后当前任务会立刻停止吗,会立即进行任务调度吗,按照逻辑道理上来说应该会立即进行任务切换。但是源代码里面队列写入以及读取代码里面没有立即切换任务的实现,是有条件的。是不满足条件的情况下进行调度,这个地方很多教程都是错的。

2025-06-06 14:00:41 200

原创 freeRTOS在ISR中断中切换任务为什么会造成堆栈错乱

在 ISR 中直接切换任务会破坏中断上下文与任务上下文的隔离性,主要原因包括中断嵌套导致的栈帧覆盖、临界区保护失效及 PendSV 机制被绕过。‌,而非任务的专用栈空间。中断退出时,CPU 尝试从中断栈帧恢复寄存器,但该位置已被新任务的数据覆盖,导致寄存器错乱或硬错误。‌,由 FreeRTOS 内核在中断退出后安全执行切换操作。若在 ISR 内直接调用任务切换函数(如。),系统可能错误地将新任务的上下文保存到‌。中断返回时,CPU 无法正确恢复到预定任务。

2025-06-05 16:33:26 553

原创 freeRTOS中断中为什么不能进行任务切换2

‌:FreeRTOS 禁止在中断中直接进行任务切换,是为了保护被中断任务的上下文完整性、维护正确的堆栈管理、保证系统的实时响应能力以及确保内核操作的原子性。(个人理解是进入ISR中断之前,要利用MSP保护上下文,那么如果ISR里面进行任务切换,任务切换时也要利用MSP对任务上下文进行切换,而freeRTOS的对MSP的保存机制,跟ISR对MSP的保存机制可能不同,很有可能会造成错乱)后缀的 API,这些 API 在需要时内部会安全地触发 PendSV 请求,而不是直接切换任务。

2025-06-05 16:23:37 451

原创 freeRTOS中断中为什么不能进行任务切换1

‌场景‌‌能否切换任务‌‌实现方式‌中断服务程序(ISR)内部❌ 禁止仅标记切换请求(中断退出后✅ 允许通过PendSV等软中断执行实际切换此设计保障了中断响应的实时性,同时确保任务切换在安全上下文进行56。

2025-06-05 16:23:35 504

原创 freeRTOS 消息队列之一个事件添加到消息队列超时怎么处理

在使用FreeRTOS时,如果你需要将一个事件添加到消息队列中,并且希望在特定时间内完成,可以通过几种方式来处理超时情况。

2025-06-05 12:13:48 253

原创 为什么freertos 放在xPendingReadyList里面的是xEventListItem而不是xStateListItem

在FreeRTOS的任务调度机制中,xPendingReadyList用于管理即将从事件中解除阻塞并准备就绪的任务。这种分离设计提高了系统效率,使事件处理和状态管理可以并行操作而互不干扰。

2025-06-05 11:06:15 232

原创 嵌入式学习笔记 - freeRTOS任务设计要点

优先级越高的任务执行时间尽量短一些间隔时间长一些,这样给低优先级的任务多一些运行的机会。或者说处理时间短的任务可以设置的优先级高一些。因为中断函数使用的上下文环境是MSP环境,而非PSP环境,不允许挂起任务,不允许阻塞任务的任何操作。空闲任务的优先级最低,不允许出现阻塞,包括空闲任务的钩子函数,否则cpu指令将停止,造成硬件错误。中断的处理时间要远低于任务的运行时间,不然将会一直执行中断。高优先级任务尽量频率低一些,否则低优先级得不到运行。可以使用FromISR函数进行操作。

2025-06-04 20:58:59 310

原创 嵌入式学习笔记 - freeRTOS关于删除自身任务函数 void vTaskDelete

当删除的任务是自身时,不会当下立即删除当前任务,因为任务切换时还需要当前任务的堆栈进行相关操作,存放pxCurrentTCB的指针的R3就得需要当前任务的堆栈暂存,而是将自身任务插入到等待删除列表,由空闲任务删除。下图为void vTaskDelete函数的内部实现,

2025-06-04 15:50:12 154

原创 嵌入式学习笔记 - freeRTOS的两种临界禁止

数组)是全局共享的关键数据结构,存储了所有可运行任务的信息。多个任务或中断服务程序(ISR)可能并发访问该列表。若不进行保护,可能导致链表节点损坏、优先级错乱等数据竞争问题。与临界区(关中断)不同,vTaskSuspendAll()仅暂停调度器,中断仍可响应,适用于需长时间保护临界区但需响应中断的场景。更改就绪列表时,通常是通过禁止中断的方式,进入临界段,因为systick中断中有可以更改就绪列表的权利,暂停所有任务调度(但允许中断),确保当前任务独占执行权,

2025-06-04 12:45:07 244

原创 嵌入式学习笔记 - freeRTOS创建一个任务的具体过程

若是第一次创建任务,先初始化所有列表,再将任务添加到列表,添加到列表的过程就是将任务控制块的任务节点信息的前后节点指针赋值,插入到就绪列表的相应优先级的链表。包含了任务的全部信息,包括任务栈的起始地址(用户定义的任务栈地址),栈顶地址,任务堆栈,任务优先级,

2025-06-03 17:08:10 120

原创 嵌入式学习笔记 - freeRTOS任务栈在初始化以及任务切换时的压栈出栈过程分析

比如定义一个任务栈为Task2Stack[N],那么任务栈的在ARM内存中的排列如下图示所,数组Task2Stack代表的起始是任务栈的最低地址,当栈为空时,就是栈内不存任何内容时,栈顶地址SP=Task2Stack+N-1,Task2Stack 为定义的任务栈的起始地址,也就是定义的任务栈数组的地址,N为定义的任务栈的总大小(长度)。

2025-06-03 16:30:01 998

原创 嵌入式学习笔记 - FreeRTOS关于vApplicationGetIdleTaskMemory

* 任务堆栈大小 */ /*指针pulIdleTaskStackSize指向的地址存放的是变量configMINIMAL_STACK_SIZE*//* 任务堆栈内存 */ /*指针ppxIdleTaskStackBuffer指向的地址里存放的是数组IdleTaskStack的地址,数组名字直接可以代表地址*//* 任务控制块内存 *//*指针ppxIdleTaskTCBBuffer指向的地址里存放的是结构体IdleTaskTCB的地址,结构体名字必须加&代表地址*/

2025-06-02 12:58:56 377

原创 嵌入式学习笔记 - freeRTOS动态创建任务时传入的任务句柄参数

以下是函数内部使用这个参数的具体部分,如果这个参数被赋值过,也是就是参数(这个参数是一个指针地址)里面有指针,也就是用户定义过这个指针,就进行赋值操作,否则无任何操作,后续程序也不能使用这个任务。xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate, /* 任务入口函数 */(const char* )"AppTaskCreate",/* 任务名字 */(void* )NULL,/* 任务入口函数参数 */任务控制块指针的地址。

2025-06-02 12:40:59 451

原创 嵌入式学习笔记 - freeRTOS 动态创建任务跟静态创建任务的区别,以及内存回收问题

‌‌。

2025-06-02 10:41:28 405

空空如也

空空如也

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

TA关注的人

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