找回密码
 立即注册
查看: 339|回复: 4

STC单片机 uC/OS-II核心技术(6):在关闭总中断进行临界区保护过程中切换任务的例子

[复制链接]

该用户从未签到

63

主题

703

回帖

1万

积分

荣誉版主

积分
10904
发表于 2023-9-22 13:09:00 | 显示全部楼层 |阅读模式
本帖最后由 杨为民 于 2024-3-31 10:54 编辑

1)在90年代我负责的一个PC机终端网络金融收支项目中,同事问我当用户密码输入错误三次后,用什么技术才能使得键盘、网络、条码枪等的所有外设都锁死不响应,并且即使有木马程序也不会被启动?我回答:“关闭总中断,程序做死循环”。
2)在00年代我的一个学生在一台国外进口的数字铣床上实习,上面有个巴掌大的红色按钮,上面只有英文“紧急”一个词。学生问技术员有什么作用,技术员说不知道,从来没有用过。
有一天,大概是工件装错了,运行时工件稳稳地向机械臂支架撞了过去,学生一机灵,拍下紧急按钮,铣床总电源断了,所有运动停止,避免了严重故障。
3)在10年代,我与机床厂朋友聊到此事,他说数字铣床等数控机床在紧急情况下用关总电源来处理其实不是很好的选择:其一是电一停,刀头卡在工件里,事后人工取出很难,会影响定位精度,甚至要重新校准。其二是下次加电时,各种部件没有从起降区开始工作,启动过程可能造成部件碰撞。
4)当时正值朋友技改项目,我出主意帮他们将紧急情况下关总电源的方法修改为:第一步,停止底盘运行,执行刀头缩回、机械臂复位操作,第二部等待操作人员手动将底盘运动到合适的位置,取下工件,复位系统,然后再断电。具体技术细节要求保密,不便细说了。
5)我认为准备运用在机电控制系统的单片机RTOS在必须有功能实现上面的“紧急情况处理”,因此设计了测试2作为产品级的单片机RTOS必须通过的测试方法。
测试2模拟了上面的紧急情况处理过程:
1)区间1,监测紧急按钮和其他传感器,检测紧急情况出现。
2)区间2,发现紧急情况,发出各种报警信号。关闭总中断,进入临界区保护,让所有的外部响应停止。然后分别对各个中断进行处理,打开或者关闭。但是RTOS系统中断必须停止,避免意外切换到其他任务。
3)区间3,进入刀头、机械臂等复位任务(正常情况它也是一个任务),保护重要设备归位。
4)区间4,处理各种善后,包括设置哪些任务就绪,哪些任务挂起。
5)区间5,进入手工操作任务(正常情况它也是一个任务),无限期等待操作者来手工操作各种机械运动来消除紧急情况,情况正常后,必须等待手工退出任务。
6)区间6,退出临界区保护,
7)区间7,善后处理,系统正式停机和断电。
6)值得说明的是:在以上的临界区保护中,当区间2分别设置好各个中断了以后,用户程序仍然可以直接用EA=1再次打开总中断,因为有许多运动控制必须在有中断的情况下才能执行。将凡是引用了中断任务调度函数的中断关闭后,就再也不会出现临界区保护之外的任务切换。
所以在“关闭总中断的临界区保护中”,用户仍然可以直接用“EA=1”和“EA=0”来控制总中断,不必要僵硬地就认为在临界区不可以打开总中断,只是程序设计的时候要特别地注意。
7)一个单片机RTOS产品在研制时会出现很多选择,这些选择不同使得RTOS有不同的类型,不同类型的RTOS适合不同的场合和具有不同的功能,这些选择没有对错之分。
一个具体的单片机RTOS可以选择不处理上面的紧急情况,当然这种产品也就无需通过测试2
一个具体的单片机RTOS虽然选择处理上面的紧急情况,但是处理的方法不是关闭总中断,当然这种产品也就无需通过测试2
一些特殊应用的单片机RTOS就根本不允许关闭总中断,那么测试3的方法也是一种选择。
总而言之,单片机RTOS的移植者或者研制者必须决定自己的产品需要哪些功能,需要通过哪些测试。

回复 送花

使用道具 举报

该用户从未签到

11

主题

331

回帖

886

积分

荣誉版主

积分
886
发表于 2023-9-22 21:14:15 来自手机 | 显示全部楼层
这个案例讲清楚了临界区切换任务的需求。

当然也有其他方法,做到一样的结果。不同的程序员想法不一样,最终解决问题就行。
回复 支持 反对 送花

使用道具 举报

该用户从未签到

0

主题

1

回帖

14

积分

新手上路

积分
14
发表于 2023-9-28 15:26:42 | 显示全部楼层
1楼讲述的是一个紧急事件处理的流程, 进入处理阶段后, 先关总中断和任务切换, 避免紧急事件处理过程中被打断.
其中讲述到前期各种妥善处理后,可打开手动任务, 继续相关的错误恢复.
整个流程有个疑点是, 第5步切换至手动任务, 第6步退出临界区, 这个细节的合理性值得思考.
通常情况下会发生以下情况:
1.在第5步切换任务会使临界区剩下一段没有被执行到.
2.在临界区切换任务意味着手动任务被包含在临界区内, 这个做法有违常理, 毕竞这是一个常规任务, 设计之初是否考虑到任务可全程在临界区内运行也是未知之数.
个人认为更合理的做法是, 提前锁住任务切换, 并提升手动任务的优先级, 使得下一次切换必定是切换到手动任务, 依次退出临界区和允许任务切换开锁. 之后便进入手动任务.
回复 支持 反对 送花

使用道具 举报

该用户从未签到

20

主题

575

回帖

1191

积分

荣誉版主

积分
1191
发表于 2023-9-29 22:37:01 | 显示全部楼层
本帖最后由 tzz1983 于 2023-9-29 22:41 编辑

本贴论点: 一个悖论是怎样形成的.
1.随着系统的日趋复杂,源代码中命名的规范性和书写规范的作用越来越突显出来,各个模块的功能统一划分, 明确分工等. 这样编写的代码逻辑清晰, 易复用, 可读性强.
有着诸多优点. 以下简称->合理性
2.但是总有一部分程序员, 不喜欢按规范和正常的逻辑来编写代码. 最终也是可以编写出可以正常运行的代码. 代价是付出更多的精力,可读性,可维护性差等.
但是最终不可否认, 程序仍旧是可以正常运行的. 这种可以正常运行的代码-> 下面简称为可行性.
3.这种具备2"可行性"的代码在实际运用中, 可以是没有任何BUG, 并且运行良好. 于是我们可以得出这样一种结论: 不按规范编写代码, 这是一种需求, 毕竞有些人就是不
喜欢按规范写代码, 并且他写的代码也是可以正常运行的.
4. 即然我们肯定了3是一种必要的需求, 那么我们在上层软件设计时(例如RTOS, 编绎器等, 编绎环境等), 就必须时刻考虑到这种正当需求. 为他们做好服务.
5. 即然我们做到了4. 那么也就是同时肯定了2, 即不按规范编写代码是正常的, 再进一步肯定, 就变成了正确的, 必然的.
6. 最后得出结论: 我们在编写代码时, 不必注重各种规范, 大程序思维, 随心所欲即可!

看看吧, 一个观点, 经过一番"貌似"正常的逻辑推导后, 竞然得出了完全相反的结论. 厉害了!

下面转入正题:
论坛中两位版主: 杨老师 熊仔, 正是希望通过这种歪曲的逻辑推导方式来证明: "在临界区内切换任务是一种正常的需求, 从而我们要满足这种需求"
这里一个很更要的破绽是究竞 "临界区内切换任务是不是必要的". 实际1楼举的例子可以很轻松的证明并非一定要在临界区内切换任务.
并且论题延升讨论的话, 切换至"原来的手动任务" 这都是一个不合理的选择. 理由是在急停"紧急事件"处理后期, 更合理的是"生成一个全新的手动任务, 而不是用之前的". 之前的手动任务是常规任务, 侧重点
可能偏向可操作性, 易用性, 实用功能等. 而后者更注重安全性, 运行环境等. 可以说完全可以做成两个不同的任务.
在此之前熊仔也提到过一些其它的需在要临界区内切换任务的场景, 但是没有一个是经得起推敲的. 感觉就是在给自己找台阶.

细心的朋友可以看到熊仔移植的 uCOSII-STC32G-V1.02.zip 中的一段代码:

        EA = 0;
        OSCtxSw();
        OSTimeDly(OS_TICKS_PER_SEC / 2);        // 500毫秒

这段代码演示关EA并切换任务, 之前我和熊仔聊过一些, 他跟我说临界区内不可阻塞, 但此处OSTimeDly(OS_TICKS_PER_SEC / 2)是在EA=0时被调用的, 目的是为了切换到任务B
有没有一种自相矛盾的感觉? 到底临界区内可不可以阻塞? 为何要用这种方式切换到任务B?

我完全相信熊仔的技术能力,  在此处他也不是故意犯一个"自相矛盾"的错误, 他只是想证行"临界区内切换任务" 是"可行的" . 并且在后面的任务B和C也确实证明了"临界区内切换任务"成功了
但是这样一个简单的道理为什么这么难以说明白了呢? 甚至是为了证明"临界区内切换任务" 是"可行的", 自己先犯了一个自己认为是"错误"的错.

后来我明白了这其中的道理: 不是熊仔技术能力差, 而是他想把一件不合理的事情证明为合理的, 这本身就很难

点评

(1)tzz1983网友,你发错地方了吧?你从一楼的哪里看出来我给出了这个结论:“在临界区内切换任务是一种正常的需求, 从而我们要满足这种需求"。 (2)熊仔网友在二楼的原话是“这个案例讲清楚了临界区切换任务的需  详情 回复 发表于 2023-9-30 01:33
回复 支持 反对 送花

使用道具 举报

该用户从未签到

63

主题

703

回帖

1万

积分

荣誉版主

积分
10904
 楼主| 发表于 2023-9-30 01:33:52 | 显示全部楼层
本帖最后由 杨为民 于 2023-9-30 03:06 编辑
tzz1983 发表于 2023-9-29 22:37
本贴论点: 一个悖论是怎样形成的.
1.随着系统的日趋复杂,源代码中命名的规范性和书写规范的作用越来越突显 ...

(1)tzz1983网友,你发错地方了吧?你从一楼的哪里看出来我给出了这个结论:在临界区内切换任务是一种正常的需求, 从而我们要满足这种需求"。

(2)熊仔网友在二楼的原话是“这个案例讲清楚了临界区切换任务的需求。当然也有其他方法,做到一样的结果。不同的程序员想法不一样,最终解决问题就行。tzz1983网友,你从哪里看出来他给出了这个结论:在临界区内切换任务是一种正常的需求, 从而我们要满足这种需求"。
(3)tzz1983网友,我愿意再次用更醒目的字体强调一下我在一楼的结论:
7)一个单片机RTOS产品在研制时会出现很多选择,这些选择不同使得RTOS有不同的类型,不同类型的RTOS适合不同的场合和具有不同的功能,这些选择没有对错之分
一个具体的单片机RTOS可以选择不处理上面的紧急情况,当然这种产品也就无需通过测试2。
一个具体的单片机RTOS虽然选择处理上面的紧急情况,但是处理的方法不是关闭总中断,当然这种产品也就无需通过测试2。
一些特殊应用的单片机RTOS就根本不允许关闭总中断,那么测试3的方法也是一种选择
总而言之,单片机RTOS的移植者或者研制者必须决定自己的产品需要哪些功能,需要通过哪些测试。

(4)建议tzz1983网友找准是哪个帖子然后再去质疑。如果要质疑本贴结论,请就上面的醒目的结论扣题质疑,不要推理。
(5)其实对于本贴一楼的情况,根本不需要在临界区切换什么任务,直接把范例中的任务A和任务B写成两个非无限循环形式的函数,直接在任务C里调用这两个函数不就完了吗,还需要切换什么任务?只是我们的主题是讨论单片机RTOS编程,不只是解决一个问题用什么方法。
(6)tzz1983网友,我后面会发一系列关于如何移植一个产品级别的RTOS的帖子,在那里欢迎你跟帖讨论。
回复 支持 反对 送花

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-17 22:28 , Processed in 0.061632 second(s), 45 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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