你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

CMSIS-RTOS中碰到的一个小问题

[复制链接]
netlhx 提问时间:2015-5-26 11:29 /
阅读主题, 点击返回1楼
收藏 1 评论20 发布时间:2015-5-26 11:29
20个回答
moyanming2013 回答时间:2015-5-26 20:53:26
安 发表于 2015-5-26 17:01
main是可以作为任务调度,如果把main作为任务调度,那么,系统如何启动?需要修改启动文件,启动的时候调用 ...

main函数是不能结束的!否则系统就停止了。
main函数进入osKernelStart()就不会返回了,之所以留while(1){}是因为不至于真出现问题后,调试时出现无法定位而留的。
netlhx 回答时间:2015-5-26 21:04:16
安 发表于 2015-5-26 17:01
main是可以作为任务调度,如果把main作为任务调度,那么,系统如何启动?需要修改启动文件,启动的时候调用 ...

找了一通资料,发现如下几点供讨论:
1. MAIN作为任务调度,会产生一些副作用,所以ST在改写的时候将这一特性去掉了,也就是说,在ST的RTOS里,MAIN是不能作为任务供调度的。
2. 研究了一下KEIL的RTX,由于这个组件是闭源的,所以内部特征没法跟踪,只不过RTX提供了一个OSKERNELINITIALIZE()函数,而ST提供的该函数是空的,会不会这个函数里面有玄机,存疑中?
3. ST为了统一一些定义,尽管它屏蔽了MAIN作为任务的可能,但默认将OSFEATURE_MAINTHREAD的值设置为1,也就是说,这个特性只是一个摆设,根本不起作用!

供讨论
moyanming2013 回答时间:2015-5-26 22:13:19
netlhx 发表于 2015-5-26 21:04
找了一通资料,发现如下几点供讨论:
1. MAIN作为任务调度,会产生一些副作用,所以ST在改写的时候将这一 ...

根据《The Definitive Guide to Arm Cortex-M3 and Cortex-M4 Processors》,19.3节,P613的内容看来,main作为任务函数被调度,是由于在进入main之前(即在复位向量中已经对RTX做了初始化,把main作为一个任务函数,并启动调度器),RTX只是一个独立的中间件,用户在main任务中可以初始化硬件、初始化并创建其它任务,如果已经使用了osFeature_MainThread==1宏,则就不用再显示调用osKernelStart()了,否则还需要调用并启动调度器。
说明:
1.RTX是开源的,只是你选用的是.lib,你可以选择使用RTX源文件并重新编译即可。
2.RTX又是特殊的,在Keil中的选项(Target)中可以显示指出。当然可以通过修改一些文件使keil支持其它RTOS。
3.为了保持兼容性,把main作为任务函数的优点并不明显。尽管在CMSIS-RTOS API框架下。
下面的也有关于main作为任务函数的CMSIS的说明:
http://www.keil.com/pack/doc/cms ... ___kernel_ctrl.html
netlhx 回答时间:2015-5-26 22:30:54
moyanming2013 发表于 2015-5-26 22:13
根据《The Definitive Guide to Arm Cortex-M3 and Cortex-M4 Processors》,19.3节,P613的内容看来,ma ...

不错,高见!灰常感谢!
回答时间:2015-5-27 14:17:45
moyanming2013 发表于 2015-5-26 20:53
main函数是不能结束的!否则系统就停止了。
main函数进入osKernelStart()就不会返回了,之所以留while(1) ...

楼主跑的是系统,如果有系统,main是可以结束的。在main里面创建了其他任务,虽然main结束了。但是其他的任务还是在运行。
moyanming2013 回答时间:2015-5-27 18:14:52
安 发表于 2015-5-27 14:17
楼主跑的是系统,如果有系统,main是可以结束的。在main里面创建了其他任务,虽然main结束了。但是其他的 ...

LZ是使用了RTOS,但如果osFeature_MainThread没有设置为1,则main是不能也不会停止运行的。
如果osFeature_MainThread设置为了1,则main函数作为一个任务函数的角色出现,这个任务函数是可以停止运行的。
该问题的关键,要看调度器位于什么位置,调度器在main中被调用执行,则main无法停止也不会停止,否则main可以停止。
回答时间:2015-5-28 08:56:26
moyanming2013 发表于 2015-5-27 18:14
LZ是使用了RTOS,但如果osFeature_MainThread没有设置为1,则main是不能也不会停止运行的。
如果osFeatur ...

我没用过这个系统,我用其他的UCOS、COOCS、MQX、rt-thread等系统,main都是作为一个创建任务的功能,可以结束的。
moyanming2013 回答时间:2015-5-28 12:05:38
安 发表于 2015-5-28 08:56
我没用过这个系统,我用其他的UCOS、COOCS、MQX、rt-thread等系统,main都是作为一个创建任务的功能,可 ...

1.根据邵贝贝的《嵌入式实时操作系统uc/os-2》(第二版),3.13节(P113): UC/OS-II的启动,其中指出了:
“多任务的启动是通过调用OSStart()实现的。”
书中给出了在main中调用OSStart()的示例,而OSStart()又调用了OSStartHighReady(),书中给出了解释:
“OSStartHighReady()将永远不返回到OSStart()。”
我没有在该书和UC/OS的官方网站上找到不在main中调用OSStart()的程序或说明。
也就是说在UC/OS中,main将不会也不能返回!
2.根据rt-Thread官方最新代码,从gitHub中获知:
http://github.com/RT-Thread/real ... lications/startup.c
  1. /*
  2. * File      : startup.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2009, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date           Author       Notes
  12. * 2009-01-05     Bernard      first implementation
  13. * 2010-03-04     Magicoe      for LPC17xx
  14. */

  15. #include <rthw.h>
  16. #include <rtthread.h>

  17. #include "board.h"
  18. #include "drv_sram.h"

  19. extern int rt_application_init(void);

  20. /**
  21. * This function will startup RT-Thread RTOS.
  22. */
  23. void rtthread_startup(void)
  24. {
  25.     /* initialize board */
  26.     rt_hw_board_init();

  27.     /* show version */
  28.     rt_show_version();

  29. #ifdef RT_USING_HEAP
  30. #if LPC_EXT_SDRAM
  31.     rt_system_heap_init((void *)LPC_EXT_SDRAM_BEGIN, (void *)LPC_EXT_SDRAM_END);
  32.     sram_init();
  33. #else
  34.     rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
  35. #endif
  36. #endif

  37.     /* initialize scheduler system */
  38.     rt_system_scheduler_init();
  39.     /* initialize system timer*/
  40.     rt_system_timer_init();
  41.     /* initialize application */
  42.     rt_application_init();

  43.     /* initialize timer thread */
  44.     rt_system_timer_thread_init();

  45.     /* initialize idle thread */
  46.     rt_thread_idle_init();

  47.     /* start scheduler */
  48.     rt_system_scheduler_start();

  49.     /* never reach here */
  50.     return ;
  51. }

  52. int main(void)
  53. {
  54.     /* disable interrupt first */
  55.     rt_hw_interrupt_disable();

  56.     /* startup RT-Thread RTOS */
  57.     rtthread_startup();

  58.     return 0;
  59. }
复制代码

同样的,rt-thread在main中调用了rtthread_startup(),并可以看出rtthread_startup()调用了启动调度函数rt_system_scheduler_start();并随后给出注释/* never reach here */,也就是说启动器一旦调度成功,是不会也不能返回的(除非所有的任务都结束了)。
也就是说rt-thread的main函数也是不会也不能返回的。
3.其它2个我没有细看,但有理由相信(或请“安”给出一个不相信的理由),COOCS和MQX的实现机理和上述UC/OS和TR-THREAD一样:即,main是不会也不能返回的。
通过查看可知,貌似只有RTX和FreeRTOS有把main作为任务函数的配置项。
回答时间:2015-5-28 15:11:36
moyanming2013 发表于 2015-5-28 12:05
1.根据邵贝贝的《嵌入式实时操作系统uc/os-2》(第二版),3.13节(P113): UC/OS-II的启动,其中指出了: ...

我说的可以结束,是main中不去写while(1)。在返回之前他先启动了系统的运行,所以这里实际是跳不出main的。即便是写了while(1),从代码流程上看是会进入while处理,但是他是不会走下去的。
OSStart(),这个是程序运行的关键。
moyanming2013 回答时间:2015-5-28 15:49:09
安 发表于 2015-5-28 15:11
我说的可以结束,是main中不去写while(1)。在返回之前他先启动了系统的运行,所以这里实际是跳不出main的 ...

1.你所理解的“结束”不能拿来误导众人,自己娱乐就好了。
2.你所谓的“即便是写了while(1),从代码流程上看是会进入while处理”(但愿你没有写错且不是你自己娱乐用的句子),是错误的!
你还是未能理解到底哪个是正确的!你到底错在了什么地方!
你的理解停留在了如果有while(1)那么main就结束不了,这个是狭隘且错误的!因为在main中程序是进入不了while(1)的,这跟有没有while(1)都没什么卵用!有while(1)进入不了,没有while(1),main也不会退出!
那main为什么会退出不去呢?是因为OSStart()(或其他RTOS中表示启动调度的API)是永远不会返回的(除非所有任务都返回了,这种情况程序员是不会故意而为的)!

那main中到底应不应该出现一个while(1)(或者其它任何表示死循环的语句)呢?当然有必要(但不是必须),因为这是预防程序出现错误,万一(注意是万一)从OSStart()返回了,不至于调试代码时不知道程序去哪了?OSStart()万一退出,main函数也就退出了,此时程序返回到重启向量中(一般重启向量的最后一条语句是跳往main函数),PC中已经不存在有意义的指向了,此时系统终止运行。如果main的最后有一个无线循环,那么起码程序员调试时会知道,哦,原来从OSStart()返回了,此时应该注意所有的任务函数是不是有问题。

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版