搜索
bottom↓
回复: 12

关于RTX的若干疑问。

[复制链接]

出0入0汤圆

发表于 2015-8-19 15:06:23 | 显示全部楼层 |阅读模式


1,rt_ret_val                                 这个函数直接修改目标任务的堆栈的R0,但是任务又不会出栈,所以不是很清楚这个函数的作用。

2,rt_dispatch                                  这个函数将新任务加入就绪链表,可是,仅通过 rt_switch_req 简单赋值指针就能执行调度?这个时候不是应该立即进行调度么,如果在systick时根据就绪链表进行调度那岂不是实时性就很差了?

3,待定

谢谢大家捧场,希望能够得到大家的指点。

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2015-8-20 11:11:03 | 显示全部楼层
myxiaonia 发表于 2015-8-20 10:40
rtx内核函数主要有2种,
用户态使用的(os_前缀)都是用svc软中断发起的,看看svc汇编码就知道svc先检查是 ...

rtx内核函数主要有2种,
用户态使用的(os_前缀)都是用svc软中断发起的,看看svc汇编码就知道svc先检查是否为用户svc函数,是的话直接运行用户svc函数(用户svc函数需要先定义函数体,再svc.s中声明函数名)后直接退出,否则就会先运行内核函数之后才进行必要的内核调度啊这些操作。
我见吴大师多次提到过使用内核调用效率并不高,好像这种说法在Windows或者linux上大家都这么说,开销比较大。。。不知道win32api现在是不是还是用内核调用的方法,
还有一种就是中断例程中使用的(isr_前缀),会将此次内核调用注册到一个叫做osfifo的队列里,然后悬起pendsv中断,在那里真正进行内核函数的操作。



我有点理解你的意思了,调度操作在SVC封皮内执行,等内核函数执行完成以后,退出内核函数,SVC的封皮汇编会根据os_tsk重新调度。

之前我一直以为,rt_cmsis.c是一个内核封皮函数,内核的运行并不依赖于该文件,现在看来并不是这样啊,rt_cmsis.c已经成了RTX的一部分。

由此引出了另外两个问题,

3,你提到的开销较大,我不是很明白,内核调度开销太大,还是邮箱,信号量,等这些开销大,开销大指的是时间还是空间?

4,我在使用源码移植(根本不需要移植,搭建更准确一些)RTX时,发现在进入main函数之前内核已经初始化并且启动,请问,内核启动是在什么时候进行的呢?

再次感谢您的回答。

出0入0汤圆

发表于 2015-8-19 15:37:51 | 显示全部楼层
哈哈哈 这个要问我了

我的帖子里有专门提到过1问题,rtx巧妙的用这个值来获得内核函数的运行情况,比如成功啊,超时啊,错误啊等等,帮助用户获得更多信息,不过在cmsis-rtx中已经去掉了,挺可惜的。。。

第二个问题,rtx中任务调度都是在中断中完成,2中这些函数仅仅是将要任务切换的准备工作做好,svc,systick和pensv才进行真正的任务切换,任务切换需要操作寄存器,这3个函数是使用嵌入式汇编的唯一地方

出0入0汤圆

发表于 2015-8-19 16:59:06 | 显示全部楼层
2楼的,还是仔细看过源码的。

出0入0汤圆

发表于 2015-8-19 20:02:33 | 显示全部楼层
厉害啊。可能后面还会有用到。先看看。求问楼主,这个由user manual什么的么?我找了好久都没有发现。

出0入0汤圆

发表于 2015-8-19 20:27:50 | 显示全部楼层
可以直接上他的网站或是论坛上去找

出0入0汤圆

 楼主| 发表于 2015-8-20 10:26:31 | 显示全部楼层
myxiaonia 发表于 2015-8-19 15:37
哈哈哈 这个要问我了

我的帖子里有专门提到过1问题,rtx巧妙的用这个值来获得内核函数的运行情况,比如成 ...

非常感谢

1,既然有传递必然有使用,这个我再看看代码。

2,是的,但是SVC需要汇编封皮,PSV需要主动挂起,SysTick需要等待时间,我在这个函数内部找不到SVC封皮,也没有PSV主动挂起,只能等SysTcik。是这样么?如果是这样,那这个岂不是很耽误实时性?

出0入0汤圆

发表于 2015-8-20 10:30:44 | 显示全部楼层
wuzhujian 发表于 2015-8-19 16:59
2楼的,还是仔细看过源码的。


在吴前辈面前班门弄斧了。。。大师莫怪罪啊嘿嘿

当时没少得到你的帮助啊。。。

出0入0汤圆

发表于 2015-8-20 10:40:53 | 显示全部楼层
macaroni 发表于 2015-8-20 10:26
非常感谢

1,既然有传递必然有使用,这个我再看看代码。

rtx内核函数主要有2种,
用户态使用的(os_前缀)都是用svc软中断发起的,看看svc汇编码就知道svc先检查是否为用户svc函数,是的话直接运行用户svc函数(用户svc函数需要先定义函数体,再svc.s中声明函数名)后直接退出,否则就会先运行内核函数之后才进行必要的内核调度啊这些操作。
我见吴大师多次提到过使用内核调用效率并不高,好像这种说法在Windows或者linux上大家都这么说,开销比较大。。。不知道win32api现在是不是还是用内核调用的方法,
还有一种就是中断例程中使用的(isr_前缀),会将此次内核调用注册到一个叫做osfifo的队列里,然后悬起pendsv中断,在那里真正进行内核函数的操作。

出0入0汤圆

发表于 2015-8-20 11:49:48 | 显示全部楼层
macaroni 发表于 2015-8-20 11:11
rtx内核函数主要有2种,
用户态使用的(os_前缀)都是用svc软中断发起的,看看svc汇编码就知道svc先检查是 ...

3.开销大是和普通的函数调用比较的,因为使用svc软中断,中断进出需要现场保护,进了中断还要判断调用条件,从栈或者sp取地址,用户栈倒腾输入和返回参数

4.你使用的是cmsis-rtx,这个os会在进main之前就初始化了os,所以main其实就是个任务了,,,我对cmsis-rtx并不熟悉,只有这么多了

出0入0汤圆

 楼主| 发表于 2015-8-24 13:46:34 | 显示全部楼层
本帖最后由 macaroni 于 2015-8-24 13:49 编辑

已解决



  1. _declare_box8 (mp_stk, OS_STKSIZE*4, OS_TASK_CNT-OS_PRIV_CNT+1);          // 通用STACK

  2. #define _declare_box8(pool,size,cnt)  U64 pool[(((size)+7)/8)*(cnt) + 2]

  3. uint64_t       os_stack_mem[2+OS_PRIV_CNT+(OS_STACK_SZ/8)];                        // 私有STACK

  4. #define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE+OS_TIMERSTKSZ))

复制代码


如上,RTX定义了两组STACK,一组是“通用”STACK,一组是私有“STACK”。这个私有STACK是不是有BUG???

如果按照我的理解 应该这样定义:

  1. uint64_t       os_stack_mem[2+(OS_STACK_SZ/8)];       

  2. #define OS_STACK_SZ (4*(OS_PRIVSTKSIZE * OS_PRIV_CNT +OS_MAINSTKSIZE+OS_TIMERSTKSZ))
复制代码

其中OS_MAINSTKSIZE应该是给main线程,OS_TIMERSTKSZ应该是给定时器线程,这两个应该使用的是“私有”STACK。

还是说RTX有什么黑科技?



OS_PRIVSTKSIZE 并不是定义的每个“私有”STACK的堆栈数目,而是所有“私有”STACK的堆栈数目。


  1. //   <o>Total stack size [bytes] for threads with user-provided stack size <0-1048576:8><#/4>
  2. //   <i> Defines the combined stack size for threads with user-provided stack size.
  3. //   <i> Default: 0
  4. #ifndef OS_PRIVSTKSIZE
  5. #define OS_PRIVSTKSIZE 0       // this stack size value is in words
  6. #endif
复制代码

出0入0汤圆

发表于 2015-8-24 16:40:05 | 显示全部楼层
在RTX中,分系统SVC和用户SVC,是完全没有必要的,只会增加执行开销。 -- 为了区分系统SVC和用户SVC,本身就增加了执行开销。

在RTX中,必须有一个空闲线程。这个空闲线程,优先级是最低的,也是永远不会阻塞的。-- 当所有的用户线程都阻塞了之后,总要有个线程来执行吧。大部分情况下,在这个空闲线程中,执行WFI指令,以降低功耗。

在RTX设计时,没考虑动态内存分配的问题,所有的内存都是事先分配好的(静态分配,有多块不同大小的数组,通过配置文件来处理)。 -- 这是为了通用性。因为RTX事先并不知道MCU有多少内存空间,再者,静态内存分配,出错的概率会降低。

出0入25汤圆

发表于 2017-5-25 15:17:14 | 显示全部楼层
macaroni 发表于 2015-8-20 11:11
rtx内核函数主要有2种,
用户态使用的(os_前缀)都是用svc软中断发起的,看看svc汇编码就知道svc先检查是 ...


有深度的好帖子,,感谢楼主!!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 04:46

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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