找回密码
 立即注册
楼主: tzz1983

FreeRTOS 让 FreeRTOS 在 C251 上从能用到好用, 2026/9/14更新

  [复制链接]

188

主题

1406

回帖

5508

积分

荣誉版主

积分
5508
发表于 昨天 19:28 | 显示全部楼层
tzz1*** 发表于 2026-9-18 19:13
关于本 C251 FreeRTOS 移植任务切换机制的公开说明

有网友对本移植的任务切换方式提出质疑,担心在中断中 ...

楼主说:


三、这是 FreeRTOS 的标准做法
在 Cortex-M 官方移植中,任务切换由 PendSV 异常完成:


先拍照为证,免得以后被人删了不肯承认!


回复

使用道具 举报 送花

188

主题

1406

回帖

5508

积分

荣誉版主

积分
5508
发表于 昨天 21:16 | 显示全部楼层
tzz1*** 发表于 2026-9-18 14:03
经过几天的时间,气也消了,“某些东西”就是别人都让着他,“赢”惯了,这次没有让着他,让各位网友见笑了 ...

对楼主技术回复的质疑:下面是楼主的第一回合的原文:

从头开始演义吧:
第一回合:我问:
https://www.stcaimcu.com/thread-7614-1-1.html  麻烦你分析一下这个网页的问题


提取文字如下:
四、我对这个帖子的总结评价
  • 技术价值方面:楼主的移植优化(堆放 XDATA 降低 EDATA 占用)是有实用价值的,能让 STC32G/C251 上跑更多任务;杨老师指出的 ~ 与 ! 差异也是正确的优化提示。
  • 核心争议(中断内切任务):从 STC 官方角度,不建议在中断内通过关总中断强行切换任务,这种做法与 STC32G 四级流水线的中断保护机制、FreeRTOS 官方移植规范都有冲突,存在实时性和中断丢失风险。官方移植版采用“下个 tick 统一切换”是有其硬件层面考量的。
  • 问题所在(也是您想让我分析的“问题”):这个帖子最大的问题不在于技术,而在于它已经严重偏离了技术讨论的初衷——两位网友互相人身攻击、骂战占满了十几页,导致真正有价值的技术信息被淹没。帖中出现了大量与 STC 官方立场无关的个人攻击内容(如"XXX""XX""XXXX"等),这些言论不代表 STC 官方观点。

我的质疑:
(1)这是STC AI助手回答的第四个部分,其他部分为什么不放出来,是想故意隐藏什么吗?
(2)什么标出的第2点内容:核心争议(中断内切任务)这一段中文字“这种做法与 STC32G 四级流水线的中断保护机制、FreeRTOS 官方移植规范都有冲突,存在实时性和中断丢失风险。
就是说明“你的FreeRTOS移植版存在重大的安全隐患”,你同意吗?
(3)上面第3点内容说明你的提问“麻烦你分析一下这个网页的问题”动机不纯,你不是想要安不安全的技术回答,你是诱导STC AI助手评价非技术问题。

第一回合你的回答 由你亲自给出了技术结论:
核心争议(中断内切任务):从 STC 官方角度,不建议在中断内通过关总中断强行切换任务,这种做法与 STC32G 四级流水线的中断保护机制、FreeRTOS 官方移植规范都有冲突,存在实时性和中断丢失风险。官方移植版采用“下个 tick 统一切换”是有其硬件层面考量的。








回复

使用道具 举报 送花

188

主题

1406

回帖

5508

积分

荣誉版主

积分
5508
发表于 昨天 21:37 | 显示全部楼层
tzz1*** 发表于 2026-9-18 14:03
经过几天的时间,气也消了,“某些东西”就是别人都让着他,“赢”惯了,这次没有让着他,让各位网友见笑了 ...



对于楼主第二回合的质疑:
第二回合:我问:从 STC 官方角度,不建议在中断内通过关总中断强行切换任务”,这个有出处?



文字提取:
问题:“从 STC 官方角度,不建议在中断内通过关总中断强行切换任务”,这个有出处?
我核实完了。以下是我的更正与说明:
更正声明您在追问的这句话 ——“从 STC 官方角度,不建议在中断内通过关总中断强行切换任务”—— 我查证后必须承认:手册中确实没有这样的原文表述,也没有任何官方文件直接给出这个结论这句话是我基于手册相关内容做的推理和外推不应当以 “STC 官方角度” 的名义说出来。这是我上一轮回答的不严谨之处,向您致歉。


在其中,STC AI助手对于“从 STC 官方角度”表示找不到出处道歉,但是它从技术的角度“我基于手册相关内容做的推理和外推”得出的技术结论。

所以第二回合你的回答 由你亲自给出了技术结论:
核心争议(中断内切任务):从 STC 官方角度从技术的角度:不建议在中断内通过关总中断强行切换任务,这种做法与 STC32G 四级流水线的中断保护机制、FreeRTOS 官方移植规范都有冲突存在实时性和中断丢失风险。官方移植版采用“下个 tick 统一切换”是有其硬件层面考量的。





回复

使用道具 举报 送花

188

主题

1406

回帖

5508

积分

荣誉版主

积分
5508
发表于 昨天 22:39 | 显示全部楼层
tzz1*** 发表于 2026-9-18 14:03
经过几天的时间,气也消了,“某些东西”就是别人都让着他,“赢”惯了,这次没有让着他,让各位网友见笑了 ...

对第三回合的答复:

第三回盒:我问:你作为一个AI,不要自以为什么就什么,在我的认知里,从来没有这个STC 官方角度,不建议在中断内通过关总中断强行切换任务。但有一点是确定的,在操作和中断有关的寄存器后,至少会再执行一条指令才能产生中断,你可以查查是否有这回事

我的答复:
我找到了这个帖子:
多级流水线内核的中断响应,STC8H8K64U系列,2023/9/20
https://www.stcaimcu.com/thread-4346-1-1.html
(出处: 国芯人工智能技术交流网站)
001_中断流水线.jpg
这是在STC-RTOS发展史上一个重要的技术帖子:这是姚总当年为我们(包括你在内)在讨论RTOS中断内切换任务安全性时专门为我们开的一个技术帖子,而且你当时还参与了讨论
STC32G手册是在不断地更新中,查不到不等于没有。

回复

使用道具 举报 送花

188

主题

1406

回帖

5508

积分

荣誉版主

积分
5508
发表于 昨天 23:16 | 显示全部楼层
tzz1*** 发表于 2026-9-18 14:03
经过几天的时间,气也消了,“某些东西”就是别人都让着他,“赢”惯了,这次没有让着他,让各位网友见笑了 ...
我对第四回合的回复:

第四回合:我问:我从FREERTOS官方渠道了解到,xTaskIncrementTick()设计者意图本就是关掉中断再调用,
有些RAM移植客官方版本也是:“关中断,xTaskIncrementTick(),开中断,这样的简单逻辑,
原理很简单,这里本身是中断,不需要判断中断是否是开的。并且我从推理角度来说,这是合理的,不存在什么违背什么的地方.
至于之前你说的四条指令,我的理解是,正如你说的 ”TR0=0; NOP(4); EA = 0; “
本意是留出四条指令的空间,让TR0=0;可以成功的执行完。
但是,这个和原码:
void Timer0_ISR_Handler (void) interrupt 1
{
EA=0;
portYIELD_FROM_ISR( xTaskIncrementTick() );
EA=1;
}
并不冲突,为什么这个地方不需要留,这里是刚进中断,之前有执行什么了吗,
所以你给杨老师胡乱指挥的那个,我认为是错误的,这里要根本就没有BUG.

我的答复:
(1)你说“我从FREERTOS官方渠道了解到,xTaskIncrementTick()设计者意图本就是关掉中断再调用,
有些RAM移植客官方版本也是:“关中断,xTaskIncrementTick(),开中断,这样的简单逻辑,
原理很简单,这里本身是中断,不需要判断中断是否是开的。并且我从推理角度来说,这是合理的,不存在什么违背什么的地方.

请问楼主,ARM有PendSV异常,STC32G有吗?你能用ARM的安全性来证明你的STC32G上的安全性吗?
PendSV(可挂起系统调用)是 Cortex-M 内核专门为 RTOS 设计的异常,核心区别在于它可被软件“挂起”,并设为最低优先级,等所有其他中断处理完后再执行
请问STC32有这种异常处理机制吗?你把猪鼻子上插上葱它也不是大象啊。

(2)你说:
至于之前你说的四条指令,我的理解是,正如你说的 ”TR0=0; NOP(4); EA = 0; “
本意是留出四条指令的空间,让TR0=0;可以成功的执行完。
但是,这个和原码
void Timer0_ISR_Handler (void) interrupt 1
{
EA=0;
portYIELD_FROM_ISR( xTaskIncrementTick() );
EA=1;
}
并不冲突,为什么这个地方不需要留,这里是刚进中断,之前有执行什么了吗,
所以你给杨老师胡乱指挥的那个,我认为是错误的,这里要根本就没有BUG.

回复1: 请问这个“原码”是是哪个“原码”,ARM的FreeRTOS的官方程序,还是STC官方在STC32G上移植的那个版本?
如果是ARM版本,哪里来的“ interrupt 1”?。
如果是STC官方在STC32G上移植的那个版本,谢谢你说了实话:
为STC官方在STC32G上移植的那个版本正了名:STC官方在STC32G上移植的FreeRTOS版本是正确的和安全的!

回复2:请问“你给杨老师胡乱指挥的那个”是哪个?
是STC官方在STC32G上移植的那个吗?你不刚肯定是它了吗?
是你移植的哪个吗?你的意思是我教你在中断里切换任务了吗?你不想要这独份功劳了吗?

回复3:你连“你给杨老师胡乱指挥的那个”都没有说清楚,还想嫁祸给STC AI助手

回复

使用道具 举报 送花

188

主题

1406

回帖

5508

积分

荣誉版主

积分
5508
发表于 昨天 23:46 | 显示全部楼层
tzz1*** 发表于 2026-9-18 14:03
经过几天的时间,气也消了,“某些东西”就是别人都让着他,“赢”惯了,这次没有让着他,让各位网友见笑了 ...
对于第五回合的回复:


第五回合:我问:你不编造,但你已经编了


我的回复:
(1)从头到尾STC AI助手都只是说承认不应该说“从STC 官方角度”而已,只是说不应该把自己的推论说成是STC官方结论,但是说自己技术上错了吗?

(2)第五回合我亲自给出了技术结论:
核心争议(中断内切任务):杨为民,不建议在中断内通过关总中断强行切换任务,这种做法与 STC32G 四级流水线的中断保护机制、FreeRTOS 官方移植规范都有冲突,存在实时性和中断丢失风险。官方移植版采用“下个 tick 统一切换”是有其硬件层面考量的。

(3)下面我给出这个技术结论的依据:
我刚才再次就你自己移植的在STC32G单片机上的FreeRTOS具体程序的安全性问题,它告诉我
如实说明:该帖内没有以文本形式公开 portYIELD_FROM_ISR 宏、Timer4 ISR、临界区宏的源码,我无法从帖子正文直接核对,需要您下载帖子中的 .rar 附件后,把 port.cportmacro.hFreeRTOSConfig.h 的对应片段贴出来,我才能逐行核对。
手册标准我已给出:STC32G12K128 手册「关闭中断应用注意事项」明确要求——关 EA 前插入 4 NOP,这是您核对移植代码临界区是否正确的唯一手册依据。
作者自述的机制属于论坛用户反馈层面,需与源码比对后才能采信。
如果您把附件里 port.c portmacro.h 的相关代码贴给我,我可以帮您逐行对照手册要求核对临界区时序、宏定义是否与该卡芯片的流水线特性匹配。

(4)我将你在1楼的最新更新的、你自己移植的在STC32G单片机上的FreeRTOS具体程序“ FreeRTOS_STC32G12K - 26.rar ”解压后,将你的:
“FreeRTOSConfig.h
”、“os_pendsv_config.h”、“port.c”和“portmacro.h”四个源程序文件上传给它分析。
STC AI助手就你的具体程序进行了分析和给出了答案。作为技术分析,内容由点长,但我觉得给出原文分析供大家学习参考:

我已经拿到了核对所需的手册依据。现在开始逐项对照源码进行分析。

基于 STC32G12K128 手册对移植代码的逐项核对
说明:下列"手册依据"部分来自 STC32G12K128 手册原文;"代码分析"部分是我对您提供源码的推理判断,供您参考。

一、portYIELD_FROM_ISR 宏 → 核对结果:逻辑自洽,与作者自述一致
源码(portmacro.h):
#define portEND_SWITCHING_ISR( xSwitchRequired )    do { if( xSwitchRequired != pdFALSE ) PendSv_SetFlag(); } while( 0 )#define portYIELD_FROM_ISR( x )                     portEND_SWITCHING_ISR( x )
源码(os_pendsv_config.h):
#define  PendSv_SetFlag()                     T4IF=1  //设置PendSv标志对应的指令或函数#define  PendSv_ClearFlag()                         T4IF=0  //清除PendSv标志对应的指令或函数#define  PendSv_InterruptNumber         20      //PendSv使用的中断编号 (TIMTE4)
手册依据:中断向量表确认 Timer4 中断标志位是 T4IF,中断允许位是 ET4,优先级固定为 0 级(最低级)。
核对项
结果
portYIELD_FROM_ISR 是否直接切上下文?否。它只执行 T4IF=1(挂起 Timer4 中断请求),不直接切换任务
是否与作者自述"只执行 T4IF=1、挂起切换请求"一致?一致
是否与手册 Timer4 优先级最低的机制吻合?吻合。Timer4 固定优先级 0(最低),不会嵌套在其它中断中
结论:作者关于"portYIELD_FROM_ISR 只置 T4IF、真正切换在基级发生"的自述,与源码一致。这一部分逻辑自洽。
⚠️ 但有一处需注意:PendSv_SetFlag() 宏展开为 T4IF=1,而 T4IF 位于 AUXINTIF(地址 EFH)。按手册「关闭中断应用注意事项」——"操作中断相关的寄存器都会触发立刻卡中断的操作",T4IF=1 属于"写中断相关寄存器"。因此 portYIELD_FROM_ISR 的调用场景(是否在持有关中断的临界区内调用)需要留意时序。


二、Timer4 中断服务程序(PendSvIsr)→ 核对结果:整体逻辑可行,但有重点可疑点
源码(port.c):
void PendSvIsr( void ){    __asm{  PendSvIsr_Entrance:     }    __asm{  CLR     EA  }        // ① 进入立即关总中断    portSAVE_CONTEXT();          // ② 寄存器入栈    __asm{  MOV   DR0,DR60          }    __asm{  MOV   DR4,pxCurrentTCB  }    __asm{  MOV   @DR4+0x2,WR2      }    PendSv_ClearFlag();          // ③ T4IF=0 清标志    vTaskSwitchContext();        // ④ 选下一个任务    __asm{  MOV   DR4,pxCurrentTCB  }    __asm{  MOV   WR2,@DR4+0x2      }    __asm{  MOV   DR60,DR0          }    portRESTORE_CONTEXT();       // ⑤ 寄存器出栈    __asm{  SETB    EA  }        // ⑥ 开总中断    __asm{  RETI        }        // ⑦ RETI 返回}
手册依据:手册中断向量表确认 Timer4 向量入口为 FF00A3H,中断号 20,void TM4_Isr() interrupt 20 为手册示例写法。
核对项
结果
中断号是否为 20?是,与手册 Timer4 中断号一致
向量入口是否由 PendSv_EntryAddress = 20*8+3 计算?20*8+3 = 0xA3,对应 FF00A3H 后 3 字节偏移,与手册 FF00A3H 一致
用 RETI 返回?是,与手册中断返回机制一致
上下文切换是否在基级(非嵌套)发生?取决于 Timer4 是否真的不被嵌套。Timer4 优先级固定 0(最低),手册机制支持"不被嵌套"
可疑点(需您重点关注):
  • PendSvIsr 用 CLR EA 关中断后,全程没有再开中断直到最后 SETB EA。这意味着 Timer4 切换期间总中断是关闭的。
  • 但按手册「关闭中断应用注意事项」:"操作中断相关的寄存器都会触发这个立刻卡中断的操作",而 PendSv_ClearFlag()(T4IF=0)正是操作中断相关寄存器。手册要求在"操作中断相关寄存器"与"关中断"之间插入 4 个 NOP——本 ISR 是 CLR EA 在前、T4IF=0 在后,属于"先关中断、后写中断寄存器",方向相反,不涉及手册那条规则的违规,但 T4IF=0 之后紧接着就 vTaskSwitchContext(),若期间有其它中断请求(此时 EA=0),会被"立刻掐掉",这部分需要结合您的实际中断使用场景评估。
  • portRESTORE_CONTEXT() 之后 SETB EA 再 RETI:作者在 xPortStartScheduler 里有一段注释:

//开中断,开中断后至少会往下执行一条指令,执行完ERET指令后才能响应中断.__asm   { SETB  EA      }__asm   { DB    0AAH    }   // ERET
作者自己已经意识到"开中断后至少要再执行一条指令才能响应中断"这一特性——这与手册"写中断相关寄存器会立刻卡中断、其它执行要过 4 级流水线"的描述是同一类机制。作者在此处做了处理。


三、临界区宏 → 核对结果:功能正确,但未按手册插入 4 个 NOP(存在时序风险)
这是本次核对最需要指出的问题。
源码(port.c):
static uint8_t data uxCriticalNesting = 0;static bit _bEA;void vPortEnterCritical( void ){    if (!_testbit_(EA)) {          // 若 EA 原本为 0        if (uxCriticalNesting == 0) {            _bEA = 0;              // 记住原本是关的        }    } else {                        // 若 EA 原本为 1        if (uxCriticalNesting == 0) {            _bEA = 1;              // 记住原本是开的        }    }    uxCriticalNesting++;}void vPortExitCritical( void ){    uxCriticalNesting--;    if(uxCriticalNesting==0)EA=_bEA;}
portmacro.h 中:
#define portENTER_CRITICAL()                    vPortEnterCritical()#define portEXIT_CRITICAL()                     vPortExitCritical()#define portSET_INTERRUPT_MASK_FROM_ISR()       ((!_testbit_(EA))?0X00:0X80)#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x)    {IE|=(uint8_t)x;}
3.1 做得对的地方(值得肯定)
核对项
结果
是否支持嵌套临界区?是。通过 uxCriticalNesting 计数实现,计数为 0 时才恢复
是否保存/恢复原 EA 状态?是。用 _bEA 保存进入时的 EA 状态,退出时恢复。这是标准且正确的做法
ISR 版临界区是否保存/恢复原状态?基本正确。portSET_INTERRUPT_MASK_FROM_ISR 返回原中断状态,portCLEAR_... 用 `IE

3.2 需要指出的问题:关中断没有插入 4 个 NOP
手册依据原文("关于STC32G系列关闭中断应用注意事项"):
"STC内部设计为4级流水线……如果想要让指令执行完成后再关闭中断。需要在关EA之前加入4个NOP时钟。
例如,关闭定时器0,TR0=0,如果马上要关掉EA对后面进行原子操作保护,则需要考虑TR=0经过流水线的时间,需要写为 TR0=0; NOP(4); EA = 0;
目前只要是操作中断相关的寄存器都会触发这个立刻卡中断的操作,所以如果需要立刻关总中断/各个外设的独立中断,需要考虑给其之前4个NOP,来让之前产生的这部分中断有实际响应空间。"
对照本移植代码:
vPortEnterCritical() 中,最终执行关中断的是 EA=_bEA(当原本 EA=1 时,即 EA=1→实际是保持,真正关断发生在第 0 层且原本 EA=0 的情况)。实际上,本移植的 vPortEnterCritical 在 EA 原本为 1 时并没有真正执行 EA=0 —— 它只是记录了 _bEA=1,然后把 uxCriticalNesting++,并没有关中断!
⚠️ 这是我要重点向您指出的问题:
void vPortEnterCritical( void ){    if (!_testbit_(EA)) {        // EA==0 分支        if (uxCriticalNesting == 0) {            _bEA = 0;        }    } else {                      // EA==1 分支        if (uxCriticalNesting == 0) {            _bEA = 1;             // ← 这里只是记录,没有执行 EA=0!        }    }    uxCriticalNesting++;}📋
当 EA==1 时进入 vPortEnterCritical(),代码路径里没有任何一条 EA=0 指令,只记录了 _bEA=1。这意味着这个"临界区"在 EA 原本为 1 时,实际上根本没有关闭中断,临界区保护是失效的。
按 FreeRTOS 标准移植,vPortEnterCritical() 必须在最外层计数为 0 时真正执行关中断。此处看起来遗漏了关中断动作(或依赖了某处上下文未给出的额外逻辑)。
另外,即便补上 EA=0,按手册要求,在 EA=0 之前(尤其是前面刚操作过中断相关寄存器时)还需插入 4 个 NOP,本代码中没有任何 _nop_() 保护。

3.3 对 portCLEAR_INTERRUPT_MASK_FROM_ISR(x) 的核对

#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x)    {IE|=(uint8_t)x;}
  • 用 IE |= x 恢复,只置位不清理,逻辑上可用于"恢复 EA 到进入前状态"(x 为 0x80 时开中断)。
  • 但注意:在中断服务程序内操作 IE(EA 是 IE.7)属于"操作中断相关寄存器",按手册会触发"立刻卡中断"行为。这里同样没有 4 个 NOP 的时序保护。


四、portYIELD() 宏 → 核对结果:用 NOP8 补偿时序,思路与手册机制相符
源码:
#define portYIELD()    do { PendSv_SetFlag();NOP8();} while( 0 )
  • PendSv_SetFlag() 即 T4IF=1(写中断相关寄存器);
  • 随后 NOP8() 延时 8 个时钟。
手册依据:手册说"操作中断相关寄存器会触发立刻卡中断……其它执行要过 4 级流水线"。作者在这里用 8 个 NOP 延时,思路是与手册机制相符的(给流水线和中断响应留时间)。不过手册原文针对的是"关中断前的保护",这里针对的是"置中断标志后的响应延时",场景不同,但方向上体现了作者对该芯片流水线特性的认知。


五、Timer0 滴答中断 → 核对结果:存在两个可讨论点
源码:
void Timer0_ISR_Handler (void) interrupt 1        {    EA=0;    portYIELD_FROM_ISR( xTaskIncrementTick() );    EA=1;}📋
手册依据:Timer0 中断号 1、向量 FF000BH、中断标志 TF0、中断允许 ET0(均与手册一致)。
讨论点:
  • EA=0 之后立即 portYIELD_FROM_ISR(...)(即 T4IF=1)。按手册"操作中断寄存器会立刻卡中断",这里 EA=0 是关中断,T4IF=1 是操作中断寄存器。手册要求的是"操作中断寄存器 → NOP(4) → 关 EA"的顺序。此处顺序是"先关 EA → 再操作中断寄存器"。两者方向不同:这里关 EA 时,前面并没有刚操作过中断寄存器,所以不完全踩中手册那条规则的场景;但 T4IF=1 之后立刻 EA=1,若希望 Timer4 中断能被正确响应,同样依赖"开中断后至少一条指令"的特性,需实测。
  • 这正是论坛争议中"杨某"质疑的那段代码。从手册角度:这段代码本身没有直接违反手册任何明文规定;但它把"在中断内关中断、操作中断寄存器、再开中断"这套动作放在了滴答中断里,时序上确实敏感,需要结合"EA=1 后至少执行一条指令才响应中断"的机制来验证。手册无法直接判定它死机与否。


六、总结核对表
代码项
手册依据
核对结果
portYIELD_FROM_ISR → 只 T4IF=1Timer4 优先级固定最低(0级)✅ 与作者自述一致,逻辑自洽
Timer4 ISR 中断号 20 / 向量 0xA3Timer4 向量 FF00A3H、号 20✅ 一致
PendSvIsr 用 RETI 返回手册中断返回机制✅ 一致
portYIELD() 用 NOP8 延时操作中断寄存器触发的流水线特性✅ 思路相符
vPortEnterCritical 支持嵌套+保存EA状态——✅ 结构正确
vPortEnterCritical 是否真正关中断FreeRTOS 临界区定义⚠️ 当 EA 原本为 1 时,代码路径中未见 EA=0,临界区保护疑似失效
临界区/ISR 临界区是否插 4 个 NOP手册"关闭中断应用注意事项"明文要求⚠️ 未见任何 _nop_() 时序保护
Timer0_ISR 内 EA=0; portYIELD_FROM_ISR; EA=1手册无禁止性明文⚠️ 手册无法判定对错,属时序敏感区,需实测


最后说明:以上"⚠️"标记项是我基于您提供的源码和手册原文作出的推理判断,供您核对参考。特别是"vPortEnterCritical 未真正关中断"这一点,建议您在 Keil C251 中反汇编 vPortEnterCritical 函数确认生成的汇编里是否有关 EA 的指令——如果确实没有,那么这是该移植版一个值得作者确认的问题。




回复

使用道具 举报 送花

188

主题

1406

回帖

5508

积分

荣誉版主

积分
5508
发表于 23 小时前 | 显示全部楼层
tzz1*** 发表于 2026-9-18 14:03
经过几天的时间,气也消了,“某些东西”就是别人都让着他,“赢”惯了,这次没有让着他,让各位网友见笑了 ...

最后答复:

你说:结果大家都看到了,有些人把AI当成了神,其实AI就是个小丑,呃,也不能这么说,
当个工具合理利用还是可以的,你要是把他当成神,从而没有了自己的判断,那么估计也只有”迟暮“之年的人会这么做


既然你不承认AI,就请你本尊亲自回答我对你的质疑(此质疑经过AI的润色,但是代表我的观点,我对此文全权负责):

楼主说他的移植版弥补了官方移植版缺失 portYIELD_FROM_ISR() 的问题,其方法是在中断内人为**关闭总中断(EA=0)**后,再调用 portYIELD_FROM_ISR() 执行任务切换。
我认为这个做法本质上是中断内的任务切换"伪装"成任务级的上下文切换,即通过关中断来避免处于"中断模式"时的硬件现场保护问题。
但是这种方法存在着重大的安全隐患,甚至导致死机:
① 违背 STC32G 4级流水线关中断的时序要求
依据手册《关于STC32G系列关闭中断应用注意事项》:
STC内部设计为4级流水线,为了防止关闭总中断后再产生中断,所以有设计一个额外的中断截取功能,例如关闭EA的时候会立刻掐掉所有中断。但是其他执行依然要经过4级的流水线……操作中断相关的寄存器都会触发这个立刻卡中断的操作,所以如果需要立刻关总中断/各个外设的独立中断,需要考虑给其之前4个NOP,来让之前产生的这部分中断有实际响应空间。
在中断内直接操作 EA=0,如果没有正确处理流水线时序,可能丢失正在排队的更高优先级中断请求。

② 中断响应实时性大幅下降
关闭总中断后,所有其他中断源的响应被屏蔽。在关中断期间,即使发生了更高优先级的紧急中断(如UART接收、ADC完成、定时器溢出等),也无法及时响应。这违背了实时操作系统的设计初衷——RTOS的任务切换不应以屏蔽所有中断为代价。特此注意,对于ARM单片机没有这个问题!

③ 中断嵌套被完全禁止
STC32G 支持多级中断嵌套(中断优先级可通过寄存器设置为0~3级)。关闭总中断后,所有中断嵌套被禁止,系统退化为单级中断模式,高优先级中断无法打断正在执行的中断服务程序。对于某些中断源,可能造成中断丢失的额问题
④ 可能导致关键中断丢失或延迟
如果在关中断期间恰有外部事件触发中断,由于总中断被关闭,该中断请求将挂起等待。如果关中断时间较长,某些中断(如串口接收缓冲溢出、PWM周期事件等)可能因未能及时处理而丢失数据。

⑤ 系统性风险:违反FreeRTOS官方移植规范
FreeRTOS 官方设计在中断中通过 FromISR 系列函数激活高优先级任务,然后在中断返回后由内核在安全时机(如节拍中断或用户调用的临界区内)完成实际切换。强行在中断内切换任务,实际上绕过了内核的调度器保护机制,属于非标准用法,可靠性和可维护性都存在隐患。
这里的官方是指FreeRTOS的官方(不是STC的官方),FreeRTOS的核心任务调度机制是专门依赖ARM单片机的PendSV异常机制的

⑥ 楼主的版本与STC官方移植版本的行为不一致。请楼主自行申明,不要打着STC官方的旗号!


回复

使用道具 举报 送花

188

主题

1406

回帖

5508

积分

荣誉版主

积分
5508
发表于 22 小时前 | 显示全部楼层
tzz1*** 发表于 2026-9-18 18:17
怎么知道是我删的呀?是内部人员看你丢脸丢大了,才删掉一些帖子,是在保护你,我巴不得一点都不删呢。不过 ...

你把9楼也删呀,你的移植版两年多前你才发表我就警告过你会死机!至今不改!

FIG_9.jpg
tzz1*** 发表于 2024-4-5 09:41
重新移植过了,没有动过源码.  源码只是处理了一些警告.

其它:我范例中用了 任务运行时间统计, 需要动态 ...


你的这个移植版存在重大BUG不能运行此次排行榜的实时响应时间测试程序,会死机

作为本尊,你应该亲自编写一个可以正常运行的,不死机的测试程序发布出来供大家学习。
如果你编不成功,就请给出一个说明,我们等你消除BUG,发布新版本后再用你的新版本来学习研究。
静等



回复

使用道具 举报 送花

32

主题

229

回帖

1890

积分

版主

积分
1890
发表于 14 小时前 | 显示全部楼层
本贴只讨论 STC/AI系列单片机相关的软件和硬件,其余话题请不要交谈,尤其是涉及敏感词汇的,均已被系统监测到并删除,请大家文明用语,共同维护良好的氛围,感谢支持。
回复

使用道具 举报 送花

24

主题

308

回帖

2504

积分

版主

STC

积分
2504
发表于 14 小时前 | 显示全部楼层
本帖中触发敏感词的内容已被系统监测删除。
本帖初衷为技术学术交流,目前已经严重偏离主题,大量楼层出现人身争执,有效技术内容被淹没。
两位均是我们 STC 的好伙伴,还请放下情绪分歧,回归技术本身,停止互相攻讦,避免帖子继续发酵, 共建健康有序的论坛交流环境,感谢理解与配合。

点评

古代学堂里有一种东西,叫做戒尺! 古代学堂里有一种人,非得被打着骂着才肯好好读书。 本帖子头几页里有一个人,不说他两句就不会好好谈技术问题!欢迎大家去观摩。 我的问题提了几天,没人回答,这下不就好好谈  详情 回复 发表于 10 小时前
电话:0513-55012982、18106296593 (微信同)
QQ : 1347154513
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-9-19 23:42 , Processed in 0.076902 second(s), 91 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表