10811|55

157

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

问题请教 [复制链接]

uCOS II中,用uCOS 写 LM3S6911的程序,3个串口都是以查询方式接受或者发送串口数据!当我在main 函数中 创建任务时把 单独的3个串口任务 放在最前面时,三个串口可以同时工作!如果我在前面有一个创举任务,则最后一个串口不能工作。不管怎么做,只要落在最后,就不能工作!想请教原因在哪?附件是源程序!用source insight 和Keil 4 工具!

m3_Led_18918.rar

8.32 MB, 下载次数: 2

文件

最新回复

1.会不会是自己在写代码是,用于保存64字节或者跟多字节的数组在使用是超出了界限,或者说在赋值给这个数组时出现了问题。 2.24C256如果在支持连续写64字节或以上时,不知道有没有什么特别的要求。  详情 回复 发表于 2013-2-27 16:33
点赞 关注

回复
举报

436

帖子

5

TA的资源

五彩晶圆(初级)

沙发
 
来看一下。看描述,各个任务本身应该·是没有问题的。如果没有用到任务同步的话,不是因为任务同步机制导致的问题的话,这个可能就是:
1. 优先级的不当
2.高优先级任务的sleep时间过短,导致低优先级的任务无法得到调度。

代码逻辑导致的问题可能性比较小。

具体的看一下代码,再回复你哈,别急。

点评

好的,谢谢你哈!  详情 回复 发表于 2013-1-15 21:53
 
 

回复

157

帖子

0

TA的资源

纯净的硅(初级)

板凳
 

回复 沙发 lr2131 的帖子

好的,谢谢你哈!

点评

你先试试,把一些不是很紧要的任务优先级降低一些。另外,在任务中多使用OSTimerDelay等(类似于sleep函数)这样的任务级调度函数,让出CPU给其他低优先级的任务,可以的话尽量给出的sleep参数大一点,当然有些和用户  详情 回复 发表于 2013-1-15 22:05
 
 
 

回复

436

帖子

5

TA的资源

五彩晶圆(初级)

4
 
原帖由 lixmlxm 于 2013-1-15 21:53 发表
好的,谢谢你哈!
你先试试,把一些不是很紧要的任务优先级降低一些。另外,在任务中多使用OSTimerDelay等(类似于sleep函数)这样的任务级调度函数,让出CPU给其他低优先级的任务,可以的话尽量给出的sleep参数大一点,当然有些和用户交互的任务(例如按键、键盘等任务)如果sleep时间太长就会影响到实时响应了,所以说是尽量,这个参数的问题需要自己来调试。

另外建议可以用中断的地方就用中断,例如uart的接受用中断(发送不需要),将会减少系统开销。另外,uart建议加上环形缓冲队列,增强通信稳定性。
 
 
 

回复

157

帖子

0

TA的资源

纯净的硅(初级)

5
 
中段接受的问题,我正在调试。还没有调通,你有现成的调通的例子吗?能否发给我参考一下呢!

点评

这个,我也没有。我只能给出ARM7裸机的uart中断方式的实例。虽然手上也有一个CM3的板子,但是快3年没玩了。你的LM3S是CM3核的,而且用到了os,我提供的几乎没有参考价值。 你的代码中,看到了一些东西似乎是开发环  详情 回复 发表于 2013-1-16 10:42
 
 
 

回复

157

帖子

0

TA的资源

纯净的硅(初级)

6
 
另外,很奇怪的是,我基本上照你说的做了!也就是把创建任务移到主函数,把优先级改掉,把其他任务屏蔽了,这样反而更不行了,只有一个工作了!我用的是人家的DEMO板调试!

点评

这个感觉很奇怪,你说只有一个任务在工作,是哪个任务呢? 另外,你的代码中用到了很多全局变量,在不同的任务之间读写,不使用同步机制是会出现问题的。定义这些变量时,注意还是带上volatile关键字比较好。  详情 回复 发表于 2013-1-16 10:48
 
 
 

回复

436

帖子

5

TA的资源

五彩晶圆(初级)

7
 
原帖由 lixmlxm 于 2013-1-16 09:22 发表
中段接受的问题,我正在调试。还没有调通,你有现成的调通的例子吗?能否发给我参考一下呢!
这个,我也没有。我只能给出ARM7裸机的uart中断方式的实例。虽然手上也有一个CM3的板子,但是快3年没玩了。你的LM3S是CM3核的,而且用到了os,我提供的几乎没有参考价值。
你的代码中,看到了一些东西似乎是开发环境提供的库函数,所以不需要舍近求远,多找找整个开发板附带的资料,毕竟这个才是第一手资料,而且如果要玩好这个东西,第一手资料始终避不过去,你找找看,就当是熟悉资料,对后续的开发也是很有好处的。

另外,这个如果把轮询方式改为中断方式,一般是需要让中断接受操作系统的管理,除非以下两种情况:
1.用户极其熟悉这个OS,可以按自己的想法来搞,只要不出问题。     短期是很有效果的,但考虑到一个长远的维护,建议还是不要这么干,坏处多,好处少。
2.这个中断不会引起任务就绪表的变化。  
这个和用户的功能需求有关。
看你的UART0和UART1,功能是收到数据就回发,因为这个功能很简单,代码不大,所以回发完全可以整合到中断中,这样就不引起就绪任务表的变化,所以也就可以不用接受操作系统的管理,甚至可以不用做成任务。但是建议不要这么干,考虑到后期的扩展和代码一致性的维护,而且也不是很熟悉这个OS的话,还是用常规方式的保险。
如果你熟悉中断的前半段和后半段机制的话,使用任务同步的机制可以很好的解决这个问题,并且支持后续功能扩展(难免保证你以后需要的功能会引起就绪任务表的变化)。
就当是学习这些机制也是很有用的,很多OS都是这样的,包括Linux。和这些大型的OS会有些区别,不过思想是一样的。

中断的前半段:在UART的中断中,调用post来发送mutex信号量,然后读出接受到的数据。
中断的后半段:在对饮串口的任务函数中,调用pend请求对应的mutex信号量,然后pend成功就回发数据。
以上只是一种参考,具体项目工程需要怎么做要看实际效果,不一定都得这么做。

uart2的功能似乎是过一会就发一个自增的字符出去,这个的功能和uart0/1不一样,没有用到接受的话,就当是一个一般的任务。sleep的时间要调合适点,太长太短都不好。

多参考一下demo,代码的书写要按demo中提供的方式来。我记得是要在某个文件中修改一下对应的宏还是变量,让OS来管理你的中断。
 
 
 

回复

436

帖子

5

TA的资源

五彩晶圆(初级)

8
 
原帖由 lixmlxm 于 2013-1-16 09:41 发表
另外,很奇怪的是,我基本上照你说的做了!也就是把创建任务移到主函数,把优先级改掉,把其他任务屏蔽了,这样反而更不行了,只有一个工作了!我用的是人家的DEMO板调试!
这个感觉很奇怪,你说只有一个任务在工作,是哪个任务呢?

另外,你的代码中用到了很多全局变量,在不同的任务之间读写,不使用同步机制是会出现问题的。定义这些变量时,注意还是带上volatile关键字比较好。
 
 
 

回复

157

帖子

0

TA的资源

纯净的硅(初级)

9
 
我只是保留最后3个串口任务,其他删除!结果就是我上次说了那种情况,我用示波器和串口工具测试过!同步机制我还不熟练,因为刚刚接触,我原计划不用消息和邮箱的!所以你说的同步机制我搞起来可能还有点麻烦呢!另外,TI源码中的中断都是调用中断注册函数,所以我只是调用,不过不能工作而已,实在不行可以不用uCOS的,只是不甘心!但是研发速度在等着呢!

点评

这个串口的问题,如果要用到接收功能,强烈建议你要用中断方式,用轮询实在是太浪费CPU了.这个如果改成中断,你知道中断的处理实体那也可以算是个特别的任务,特别在哪,如果当前没有关中断的话,这个中断一定会进来  详情 回复 发表于 2013-1-16 18:59
同步机制有很种方法,你这里对于一些全局变量的读写前后加一下互斥锁或者说是互斥性信号量就好了,不是很难,前面不是已经提到了嘛,mutex找找,也就是pend和post这两个API,也就是加锁和解锁,只是换了个说法而已,  详情 回复 发表于 2013-1-16 18:46
 
 
 

回复

436

帖子

5

TA的资源

五彩晶圆(初级)

10
 
原帖由 lixmlxm 于 2013-1-16 18:10 发表
我只是保留最后3个串口任务,其他删除!结果就是我上次说了那种情况,我用示波器和串口工具测试过!同步机制我还不熟练,因为刚刚接触,我原计划不用消息和邮箱的!所以你说的同步机制我搞起来可能还有点麻烦呢!另外 ...
同步机制有很种方法,你这里对于一些全局变量的读写前后加一下互斥锁或者说是互斥性信号量就好了,不是很难,前面不是已经提到了嘛,mutex找找,也就是pend和post这两个API,也就是加锁和解锁,只是换了个说法而已,不一定要用到消息邮箱有消息队列。

uart0和uart1几乎一样,当然优先级不一样,里面的系统延时时间很短,你给出的参数是1,不知道这个是多长时间,但一定有些短了,你用OSTimeDlyHMSM(0,0,0,20),20ms
来先验证你的代码逻辑吧。

uart2也很短,也这么改,再试试,如果可以的话,你再试着改小这个参数(一般是改小高优先级的延时参数),一直到发现低优先级任务难被调用到,这个时候这个参数就调到底线了,这也就是采用逐渐逼近的方法,当然最好要用比这个底线大一点的值好一些,不能刚刚好,那样有出现任务处理不过来的危险。一般是改小高优先级的任务的延时会出现这个现象。

这个需要你自己来调,参数和实际系统有比较密切的关系,所以帮不上忙。

点评

关于6911 有个问题请教一下哈!我现在打开两个串口中断,但是,功能是接受什么就发什么!但是我现在遇到的问题是:不管哪个串口,谁先接到发送数据以后就可以一直接,另一个就不行了!是哪里设置成了这样,导致出不  详情 回复 发表于 2013-1-24 17:51
 
 
 

回复

436

帖子

5

TA的资源

五彩晶圆(初级)

11
 
原帖由 lixmlxm 于 2013-1-16 18:10 发表
我只是保留最后3个串口任务,其他删除!结果就是我上次说了那种情况,我用示波器和串口工具测试过!同步机制我还不熟练,因为刚刚接触,我原计划不用消息和邮箱的!所以你说的同步机制我搞起来可能还有点麻烦呢!另外 ...
这个串口的问题,如果要用到接收功能,强烈建议你要用中断方式,用轮询实在是太浪费CPU了.这个如果改成中断,你知道中断的处理实体那也可以算是个特别的任务,特别在哪,如果当前没有关中断的话,这个中断一定会进来得到处理,这等于是动态提升了这些低优先级任务的级别(在需要调用的时候被提升,不调用的时候还是低优先级),这其实就是最好的,你想清楚了吗。如果改成中断,这优先级的问题基本上是没有什么问题的,是不是!只要外面高优先级的任务别一直把持着CPU不放就行(当然也不能关中断关太时间长,OS的任务调度是依赖系统定时器中断的),UCOS2是基于高优先级方式可抢断的,如果你高优先级的任务一直不sleep,或者sleep的短了(不sleep是sleep极短的一个极限),低优先级的任务要怎么被调用呢!低优先级任务不能被调用,那当然会出现有些任务不能正常运行或者运行的机会比需要的、预想的少啊!
 
 
 

回复

157

帖子

0

TA的资源

纯净的硅(初级)

12
 
谢谢哈!时间上改过,好像没有效果!这两天忙于公司生产,也没有调试!明天空后继续哈!
 
 
 

回复

157

帖子

0

TA的资源

纯净的硅(初级)

13
 
另外,关于uCOS II,我有一个问题请教:当我的任务条件满足时需要执行不叫久一点的时间,当条件不满足时,基本上不占用时间,这样如何设置空闲时间呢?怕的是本来这个任务我在执行着,其他任务又加进来玩一下,然后再退回去,细想起来,还不如不用uCOS这个操作系统呢!

点评

你说的条件是什么条件?你这种需求我想一般可以采用信号量机制,不要觉得这个在UCOS2上好像就很新奇,其实很多OS上都有类似的功能,Linux和windows上,几乎所有的OS上都有。 例如在linux上有叫信号的说法。其实  详情 回复 发表于 2013-1-18 10:37
 
 
 

回复

436

帖子

5

TA的资源

五彩晶圆(初级)

14
 
原帖由 lixmlxm 于 2013-1-18 09:11 发表
另外,关于uCOS II,我有一个问题请教:当我的任务条件满足时需要执行不叫久一点的时间,当条件不满足时,基本上不占用时间,这样如何设置空闲时间呢?怕的是本来这个任务我在执行着,其他任务又加进来玩一下,然后再 ...


你说的条件是什么条件?你这种需求我想一般可以采用信号量机制,不要觉得这个在UCOS2上好像就很新奇,其实很多OS上都有类似的功能,Linux和windows上,几乎所有的OS上都有。
例如在linux上有叫信号的说法。其实底层原理都是一样的,导致条件满足的根源不同,但都有一个共同点那就是中断,硬件中断具有异步特性(异步特性指的是:无法确定什么时候到来),这种异步的特性必然是中断带来的(软中断也没有异步特性)。所以支持中断的CPU都可以支持这种信号量的机制,在条件不满足的时候,它就在睡眠,条件满足就会被唤醒。你要想设置时间,你觉得要怎么设置呢???这是个异步的特性,你是不可能设置好时间的,有时长有时短,不是你想的用sleep()多少来做,OS自己会处理好的,不需要你管这个参数,条件来了就叫你起来,没来你继续睡。当然也有睡超时的,那也还是会把你叫起来,仍然是中断做的,只不过换成了系统定时器的中断。

没有操作系统,完全用中断就能做到你的需求,而且CPU也比较节省(不用轮询)。所以你有一种感觉,不用OS更好,这个确实,UCOS2用的不熟,又一直卡在uart上,因为一些原因一直搞不好,纯用中断不用OS也是可以的,只是以后扩展任务的话,前后台系统比较麻烦,OS提供的多线程就比较符合人类的思维,比较直观,仅此而已。

总之不管用不用OS,这里确定还是用中断的好,就因为这个异步的特性。

如果用OS,其实也不过还是用的中断的支持机制,仍然还是中断,只不过又是这里用到了中断的后半段机制。

提升性能的底层支持其实还是中断,和有没有0S根本没有一点关系!!!换句话说,这个提升性能是需要硬件支持的,作为OS的软件是不可能直接支持的。

点评

谢谢你哈,你说的我明白了,现在奇怪了哈!我全部去掉接受,只是发射!反而是只有优先级为0的可以运行,其他的不能运行,我怀疑一定是操作系统有地方设置了导致任务只能在0任务运行。但是我又找不到,你有时间在我那  详情 回复 发表于 2013-1-18 16:02
 
 
 

回复

157

帖子

0

TA的资源

纯净的硅(初级)

15
 

回复 14楼 lr2131 的帖子

谢谢你哈,你说的我明白了,现在奇怪了哈!我全部去掉接受,只是发射!反而是只有优先级为0的可以运行,其他的不能运行,我怀疑一定是操作系统有地方设置了导致任务只能在0任务运行。但是我又找不到,你有时间在我那个程序上看看呢!

改后的主函数也如下:

    OSTaskCreate ( taskStart,                                          
                           (void *)0,
                                   &GstkStart[TASK_START_STK_SIZE-1],
                                   TASK_START_PRIO );         
                #endif                                                                                                                        /*  Initialize the start task   */
                #if 0
             OSTaskCreate (taskLed, (void *)0,                  
                              &GstkLed[TASK_LED_STK_SIZE-1],
                                  TASK_LED_PRIO);                                       /*  LED数据更新任务           */
          #endif
           OSTaskCreate (Uart1TxRxTest, (void *)0,                  
                      &GstUart1[TASK_UART1_STK_SIZE-1],
                                  TASK_UART1_PRIO);
          
        OSTaskCreate (Uart0TxRxTest, (void *)0,                  
                      &GstUart0[TASK_UART0_STK_SIZE-1],
                                  TASK_UART0_PRIO);
          

       

        OSTaskCreate (Uart2TxRxTest, (void *)0,                  
                      &GstUart2[TASK_UART2_STK_SIZE-1],
                                  TASK_UART2_PRIO);

谢谢!

点评

你是说你的uart0和uart1里面都把接受去掉,然后和uart2一样都是只发送数据,结果优先级为0的在运行是吧。你之前的优先级定义: #define TASK_UART0_PRIO 4 #define TASK_UART1_PRIO  详情 回复 发表于 2013-1-19 08:22
 
 
 

回复

436

帖子

5

TA的资源

五彩晶圆(初级)

16
 
原帖由 lixmlxm 于 2013-1-18 16:02 发表
谢谢你哈,你说的我明白了,现在奇怪了哈!我全部去掉接受,只是发射!反而是只有优先级为0的可以运行,其他的不能运行,我怀疑一定是操作系统有地方设置了导致任务只能在0任务运行。但是我又找不到,你有时间在我那 ...
你是说你的uart0和uart1里面都把接受去掉,然后和uart2一样都是只发送数据,结果优先级为0的在运行是吧。你之前的优先级定义:
#define  TASK_UART0_PRIO                    4
#define  TASK_UART1_PRIO                     5
#define   TASK_UART2_PRIO                    6

那么现在应该是
#define  TASK_UART0_PRIO                    0
#define  TASK_UART1_PRIO                     1
#define   TASK_UART2_PRIO                   2

UCOS2的优先级规则是,那个数越小(UCOS2不支持负数),优先级越高,当然优先级为0的任务优先级最高啊。既然几个任务的结构很相似,那当然是优先级为0任务被调度的机会总是最大啊。操作系统是不会设置什么任务才能运行其他的就不让运行,操作系统是要按照你给定的参数和其他影响任务调度的API来调度任务的,不然这样的操作系统就又问题了。
 
 
 

回复

157

帖子

0

TA的资源

纯净的硅(初级)

17
 
是这样的!问题是这样为什么只执行第一个任务,其他的都不执行了,我奇怪在这里!

点评

要不你把代码发我看一下吧,我也不知道你这到底是卡在哪了。  详情 回复 发表于 2013-1-21 12:34
 
 
 

回复

436

帖子

5

TA的资源

五彩晶圆(初级)

18
 
原帖由 lixmlxm 于 2013-1-21 09:49 发表
是这样的!问题是这样为什么只执行第一个任务,其他的都不执行了,我奇怪在这里!
要不你把代码发我看一下吧,我也不知道你这到底是卡在哪了。

点评

谢谢你哟!今天晚上回来再调了一下,调通了3个串口!已经确定是uCOS的问题,但是我觉得是设置问题,就是允许执行的最多的人任务数问题!除了os.config.h这个文件里设置外,还有哪里可以设置呢? 我可以执行的代码  详情 回复 发表于 2013-1-21 21:40
 
 
 

回复

157

帖子

0

TA的资源

纯净的硅(初级)

19
 

回复 18楼 lr2131 的帖子

谢谢你哟!今天晚上回来再调了一下,调通了3个串口!已经确定是uCOS的问题,但是我觉得是设置问题,就是允许执行的最多的人任务数问题!除了os.config.h这个文件里设置外,还有哪里可以设置呢?
我可以执行的代码如下,没有在主函数里执行,在主开始任务里执行的;

static void taskStart (void  *parg)
{
//        char *DisplayPoint_R;
//        char *DisplayPoint_G;
//        char const *RDataPoint;
//        char const *GDataPoint;
//        int i,j,k;
        int row;//,column;
//    char *DisplayAddr, *ImageAddr;
    (void)parg;

    targetInit();                                                       /*  Initialize the target's MCU */
                                                                        /*  初始化目标单片机            */

    #if OS_TASK_STAT_EN > 0
    OSStatInit();                                                       /*  Enable statistics           */
                                                                        /*  使能统计功能                */
    #endif

          /*
     *  Create the other tasks here. 在这里创建其他任务
     */
     
      
                 #if 0
          OSTaskCreate (taskLed, (void *)0,                  
                              &GstkLed[TASK_LED_STK_SIZE-1],
                                  TASK_LED_PRIO);                                       /*  LED数据更新任务           */
                #endif   
       
        OSTaskCreate (Uart0TxRxTest, (void *)0,                  
                      &GstUart0[TASK_UART0_STK_SIZE-1],
                                  TASK_UART0_PRIO);
          
      
        OSTaskCreate (Uart2TxRxTest, (void *)0,                  
                      &GstUart2[TASK_UART2_STK_SIZE-1],
                                  TASK_UART2_PRIO);
      
         OSTaskCreate (Uart1TxRxTest, (void *)0,                  
                      &GstUart1[TASK_UART1_STK_SIZE-1],
                                  TASK_UART1_PRIO);

       
                                  
        #if  0
        OSTaskCreate (taskLedupdate, (void *)0,                  
                              &GstkLedupdate[TASK_LEDUPDATE_STK_SIZE-1],
                                  TASK_LEDUPDATE_PRIO);                                       /*  LED数据更新任务           */
       
        OSTaskCreate (taskKeyboard, (void *)0,                  
                              &GstkKeyboard[TASK_KEYBOARD_STK_SIZE-1],
                                  TASK_KEYBOARD_PRIO);                                       /*  LED数据更新任务           */
      #endif
    ledboardDis();               
    while (1)
    {
                    for(row = 0; row < LED_LEDBOARD_SCAN; row ++)
                    {
                            SerialDataForLED_RG(LEDDisplay_RAM[0],row*LED_LEDBOARD_WIDTH, LED_LEDBOARD_WIDTH, 8,LED_LEDBOARD_WIDTH*LED_LEDBOARD_SCAN);
                        //                        SerialDataForLED_RG2(LEDDisplay_RAM[0],row*LED_LEDBOARD_WIDTH, LED_LEDBOARD_WIDTH, 8,LED_LEDBOARD_WIDTH*LED_LEDBOARD_SCAN);
                            ledboardDis();                                                                                                        //禁止LED面板
                            ledboardRow(row);                                                                                                //对应的行扫描
                            ledboardLock();                                                                                                        //锁存串行数据
                            ledboardEn();                                                                                                        //使能LED面板串行数据
                            OSTimeDly(50);                                                                                  /*  延时1ms秒                   */                       
                    }
        }
       
//        while (1) {                             
//       OSTaskSuspend(OS_PRIO_SELF);                                    /*  The start task can be pended*/
//                                                                       /*  here. 启动任务可在这里挂起  */
//  }
}

点评

原来是OS配置的问题:faint::Sweat:,难怪死调都调不出来,我以为你知道这些设置的问题呢。 UCOS2是可裁剪的,如果是官方原版的,没有被第三方改动的话,只需要在OS_CFG.H这个文件中配置,这其实也就是做裁剪。  详情 回复 发表于 2013-1-22 08:30
 
 
 

回复

436

帖子

5

TA的资源

五彩晶圆(初级)

20
 
原帖由 lixmlxm 于 2013-1-21 21:40 发表
谢谢你哟!今天晚上回来再调了一下,调通了3个串口!已经确定是uCOS的问题,但是我觉得是设置问题,就是允许执行的最多的人任务数问题!除了os.config.h这个文件里设置外,还有哪里可以设置呢?
我可以执行的代码如 ...
原来是OS配置的问题,难怪死调都调不出来,我以为你知道这些设置的问题呢。

UCOS2是可裁剪的,如果是官方原版的,没有被第三方改动的话,只需要在OS_CFG.H这个文件中配置,这其实也就是做裁剪。

然后可能就是你的开发环境自身要求的配置吧,和OS本身无关。看是否还有第三方添加的设置或功能或函数。

遇到这个配置的问题,以后要多注意一下配置了,把里面用到的都仔细看一下,特别是支持的任务最大数、相关优先级等设置。
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表