杨为民
发表于 2024-5-11 16:29:08
tzz1983 发表于 2024-5-11 15:37
可以这样认为,其实大家都知道怎么回事。
如果说,在高优中断里不调用OS服务,基本上都是零改就能实现的 ...
(1)回答正确,你最近给出的作品 uC/OS-II@STC8H确实是一个“能在高优先级零延迟中断”中调用系统服务的RTOS。祝贺你的这个作品成为本论坛“零中断延迟”RTOS的第二匹黑马。
(2)这是你的测试程序中的测试中断ISR:
void Timer3_ISR_Handler (void) interrupt 19{
T4T3M &= ~0x08; //定时器3停止计数
IE2 &= ~0X20; //关闭定时器3中断
P00 = ~P00;
P01 = 1; //开始唤醒任务
OSTaskResume_FROM_ISR(APP_CFG_START_TASK_PRIO);
}
其中这个在中断里的语句“OSTaskResume_FROM_ISR(APP_CFG_START_TASK_PRIO);”就是调用系统服务功能实现唤醒最高优先级的任务的,这就是赤裸裸的“中断里”调用呀。
(3)为了实现功能,你特地在uC/OS-II的系统内核文件“os_task.c”里新增加了这个在中断内使用的系统服务
INT8UOSTaskResume_FROM_ISR (INT8U prio)FunctionProperties
{
OS_TCB *ptcb;
#if OS_CRITICAL_METHOD == 3u /* Storage for CPU status register */
OS_CPU_SRcpu_sr = 0u;
#endif
#if OS_ARG_CHK_EN > 0u
if (prio >= OS_LOWEST_PRIO) { /* Make sure task priority is valid */
return (OS_ERR_PRIO_INVALID);
}
#endif
OS_ENTER_CRITICAL();
ptcb = OSTCBPrioTbl;
if (ptcb == (OS_TCB *)0) { /* Task to suspend must exist */
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_RESUME_PRIO);
}
if (ptcb == OS_TCB_RESERVED) { /* See if assigned to Mutex */
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_NOT_EXIST);
}
if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) != OS_STAT_RDY) { /* Task must be suspended */
ptcb->OSTCBStat &= (INT8U)~(INT8U)OS_STAT_SUSPEND; /* Remove suspension */
if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) == OS_STAT_RDY) { /* See if task is now ready */
if (ptcb->OSTCBDly == 0u) {
OSRdyGrp |= ptcb->OSTCBBitY; /* Yes, Make task ready to run */
OSRdyTbl |= ptcb->OSTCBBitX;
OS_TRACE_TASK_READY(ptcb);
OS_EXIT_CRITICAL();
if (OSRunning == OS_TRUE) {
OS_TRACE_TASK_RESUME(ptcb);
OS_Sched_FROM_ISR(); /* Find new highest priority task */
}
} else {
OS_EXIT_CRITICAL();
}
} else { /* Must be pending on event */
OS_EXIT_CRITICAL();
}
return (OS_ERR_NONE);
}
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_NOT_SUSPENDED);
}
其中调用的是中断内的任务切换函数“OS_Sched_FROM_ISR(); ”,这就是赤裸裸的从内核开始了“在中断内进行系统功能的调用”的设计。
(4)并且,你增加的不是一个,而是新增加了一组供中断内调用的常用的系统功能服务:
* 针对所有需要中断调用并且会引起任务切换的OS服务,移植版本提供了额外的中断调用版本,以下是新增中断服务的函数.
INT8UOSTaskSuspend_FROM_ISR (INT8U prio)FunctionProperties;
INT8UOSTaskResume_FROM_ISR (INT8U prio)FunctionProperties;
INT8UOSTaskChangePrio_FROM_ISR (INT8Uoldprio,INT8Unewprio)FunctionProperties;
INT8UOSTimeDlyResume_FROM_ISR (INT8U prio)FunctionProperties;
INT8UOSSemPendAbort_FROM_ISR (OS_EVENT *pevent, INT8U opt, INT8U *perr)FunctionProperties;
INT8UOSSemPost_FROM_ISR (OS_EVENT *pevent)FunctionProperties;
OS_FLAGSOSFlagPost_FROM_ISR (OS_FLAG_GRP*pgrp, OS_FLAGS flags, INT8U opt, INT8U *perr)FunctionProperties;
INT8UOSMboxPostOpt_FROM_ISR (OS_EVENT*pevent, void *pmsg, INT8U opt)FunctionProperties;
INT8UOSMboxPost_FROM_ISR (OS_EVENT*pevent, void *pmsg)FunctionProperties;
INT8UOSMboxPendAbort_FROM_ISR (OS_EVENT*pevent, INT8U opt, INT8U *perr)FunctionProperties;
INT8UOSQPendAbort_FROM_ISR (OS_EVENT*pevent, INT8U opt, INT8U *perr)FunctionProperties;
INT8UOSQPost_FROM_ISR (OS_EVENT*pevent, void *pmsg)FunctionProperties;
INT8UOSQPostFront_FROM_ISR (OS_EVENT*pevent, void *pmsg)FunctionProperties;
INT8UOSQPostOpt_FROM_ISR (OS_EVENT*pevent, void *pmsg, INT8U opt)FunctionProperties;
见你的主贴的19楼介绍:《自己用的 uC/OS-II@STC8H, 51核移植版本》
(https://www.stcaimcu.com/forum.php?mod=viewthread&tid=8195&extra=page%3D1&page=1)
(5)经过这些操作,你已经成功地将uC/OS-II移植到STC8H单片机上(本不具备RTX4/5需要的片上中断条件),必将会成为一个比CosyOS-II还强的“零中断延迟”的STC单片机RTOS。
强就强在uC/OS-II是一个主流的单片机RTOS,可以移植很多开源库在上面,比如本尊在本论坛已经移植的“uGFX”图形接口和“znFAT”文件系统,这些是CosyOS-II一时半会难以做到的。
tzz1983
发表于 2024-5-11 16:37:11
杨为民 发表于 2024-5-11 16:29
(1)回答正确,你最近给出的作品 uC/OS-II@STC8H确实是一个“能在高优先级零延迟中断”中调用系统服务的 ...
杨老师,我补充一下,不是 “新增加了一组供中断内调用的常用的系统功能服务”,
是 所有需要中断调用并且会引起任务切换的OS服务.
这个移植版本不存在功能裁剪,所有uC/OS-II的功能都可用,并且针对51核IDATA的栈还增加了一个检查功能。
fanxsp
发表于 2024-5-11 16:49:51
本帖最后由 fanxsp 于 2024-5-11 16:55 编辑
tzz1983 发表于 2024-5-11 16:37
杨老师,我补充一下,不是 “新增加了一组供中断内调用的常用的系统功能服务”,
是 所有需要中断调用 ...
你的堆栈检查,是用什么方法?我采用最简单的,就是把堆栈数据通过回调函数处理,回调函数可以直接把堆栈数据发往串口,我们自己直接分析堆栈数据,连续为0的区域,就是空余的堆栈空间。
如果是仿真运行,就停止运行,然后直接查看堆栈数据。
tzz1983
发表于 2024-5-11 16:54:39
fanxsp 发表于 2024-5-11 16:49
你的堆栈检查,是用什么方法?我采用最简单的,就是把堆栈数据通过回调函数处理,回调函数可以直接把堆栈 ...
我把代码贴出来吧,省得你下载了{:smile:}
/*-----------------------------------------------------------*
* idata公共运行栈检查, 检查方法是查找栈中连续0最大的块
* 此函数在统计任务中自动调用,也可主动调用. 没有返回值,通过全局变量回传数据.
* 使用此功能时,必须在STARTUP.A51中清零所有的IDATA.
* 有多种可能导致检查的结果不准确
* 当剩余的栈容量小余栈正常数据中连续的0时,将得到错误的结果.
* 极端的可能是正常的栈数据中含有大量的连续0
* 所以,只有在栈剩余量较大时才有参考意义
* 虽然结果可能不准确,但是,当栈剩余量较大时仍有参考意义.
*-----------------------------------------------------------*/
void IDStkChk(void)FunctionProperties
{
INT8U addr=ID_CH_Start+1,maxFree=0,cnt=0;
for(;addr;addr++){
if( ((u8 idata *)0) == 0){
cnt++;
}else{
maxFree = (cnt>maxFree)? cnt:maxFree;
cnt=0;
}
}
maxFree = (cnt>maxFree)? cnt:maxFree;
if(maxFree<ID_STK_Free){
ID_STK_Free = maxFree;
ID_STK_Used = ID_STK_Size-ID_STK_Free;
}
}
tzz1983
发表于 2024-5-11 16:55:21
本帖最后由 tzz1983 于 2024-5-11 17:01 编辑
fanxsp 发表于 2024-5-11 16:49
你的堆栈检查,是用什么方法?我采用最简单的,就是把堆栈数据通过回调函数处理,回调函数可以直接把堆栈 ...
我的方法和你的方法基本一致, 我只是检查一个大概,作为参考。并不是很准确, 但也无伤大雅。
这个功能只会在调试代码时用到,基本上是为了方便程序员查看,而不是要一个准确的结果
fanxsp
发表于 2024-5-11 17:02:13
tzz1983 发表于 2024-5-11 16:54
我把代码贴出来吧,省得你下载了
/*-----------------------------------------------------------*
ucos 本身好象也是这个办法,我的情况是有多个堆栈区,想来想去,没有什么好办法,就采用最简单的,把堆栈数据上传,人工判断。
CosyOS
发表于 2024-5-12 13:33:24
本帖最后由 CosyOS 于 2024-5-12 14:17 编辑
首先,我从未说过只有 CosyOS 才能实现 “零中断延迟” 。
而且,我相信,只要进行适当调整,很多 RTOS 都可以实现 “零中断延迟”。
只是 实现 “零中断延迟” 的技术手段不同,效果也不尽相同。
对于 坛友 tzz1983 的作品 我不慎了解,不敢妄加评论,
但只想 问问他本尊,他的这个测试程序中,定时器3中断,
void Timer3_ISR_Handler (void) interrupt 19{
T4T3M &= ~0x08; //定时器3停止计数
IE2 &= ~0X20; //关闭定时器3中断
P00 = ~P00;
P01 = 1; //开始唤醒任务
OSTaskResume_FROM_ISR(APP_CFG_START_TASK_PRIO);
}
是否真的实现了 “零中断延迟” ?
如果确实实现了 “零中断延迟”,那么,
INT8UOSTaskResume_FROM_ISR (INT8U prio)FunctionProperties
中的 “OS_ENTER_CRITICAL();”,
是否会影响其它高优先级中断的实时响应 ?
进而导致其它高优先级中断无法实现 “零中断延迟” ?
如果该定时器3中断未能实现 “零中断延迟”,
那么 其它高优先级中断 是否可以实现 “零中断延迟” ?是否支持随意调用服务?
请 坛友 tzz1983 把你的先进技术也简单介绍一下,
也让 大家 都能从中受益 !
CosyOS
发表于 2024-5-12 14:20:55
本帖最后由 CosyOS 于 2024-5-12 14:25 编辑
CosyOS 发表于 2024-5-12 13:33
首先,我从未说过只有 CosyOS 才能实现 “零中断延迟” 。
而且,我相信,只要进行适当调整,很多 RTOS 都 ...
没人和你较真,但需要通过你,没你不行啊!
我也不想和任何人较真。
tzz1983
发表于 2024-5-12 14:24:08
CosyOS 发表于 2024-5-12 14:20
没人和你较真,但需要通过你,没你不行啊!
那你自己知道就行了,我相信不只你知道. 你自己的问题都不正面解决,
我这里没有问题, 我也没有乱说话
tzz1983
发表于 2024-5-12 14:36:35
本帖最后由 tzz1983 于 2024-5-12 14:39 编辑
CosyOS 发表于 2024-5-12 14:20
没人和你较真,但需要通过你,没你不行啊!
我也不想和任何人较真。
好吧, 正面回答你,要实现0延时, 需要改一下进入临界区的宏,
把关闭总中断改为只关闭一部分中断, 未被临界区关闭的中断才可以实现零中断延迟,
作为代价, 不可以调用OS服务, 并且进入临界区的宏也会变得复杂一点.
虽然最终可以实现这个功能, 但我个人认为使用uC/OS-II 时是没有必要这样做的
页:
3
4
5
6
7
8
9
10
11
12
[13]
14
15