搜索
bottom↓
回复: 15

UCos-II 2.76 MEGA64 16M时钟 tick = 100HZ GCC 任务间共享数据的问题

[复制链接]

出0入0汤圆

发表于 2007-3-13 08:42:08 | 显示全部楼层 |阅读模式
UCos-II 2.76 MEGA64 16M时钟 GCC 任务间共享数据的问题



volatile unsigned int g_adc_data;//使用关键字声明

//Task1 循环的不停的采集数据

void Task1 (void *data)

{

        unsigned char ADChannel=0;

        data = data;   /* Prevent compiler warning                         */

        ADChannel=0;

        ADMUX = 0x40+(ADChannel);//参考源VCC,右对齐,选择0通道。

        ADCSRA|=(1<<ADSC);//启动转换

        for (;;)

        {

                while(ADCSRA&0x10)

                {

                        NOP();

                }

                g_adc_data= ADC;

                OS_ENTER_CRITICAL();

                g_adc_data = ADC;

                //_delay_us(1);//也不行

                OS_EXIT_CRITICAL();

                OSTimeDlyHMSM(0,0,0,1);////间隔采集数据,问题在这里,如果延时太短小于6ms,感觉g_adc_data就没有被修改,下面任务打印出的都是第一次采集到的数据

                ADCSRA|=(1<<ADSC);//启动下一次转换

        }

}



//Task2 循环的不停的打印采集到的数据

void Task2 (void *data)

{

        for(;;)

        {

                OS_ENTER_CRITICAL();

                Printf("通道数据是 %d\r
",g_adc_data);

                OS_EXIT_CRITICAL();

                OSTimeDlyHMSM(0,0,2,0);//每2秒打印一次数据,如果上面任务中的采集间隔(OSTimeDlyHMSM(0,0,0,6))太短低于6ms就打印出相同的数据,g_adc_data没有被改变过??????,但如果采集间隔大于6ms打印就是对的

        }

}



我这种任务间共享数据的方法是不是有问题????请大家指点一下,谢谢

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

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2007-3-13 08:44:13 | 显示全部楼层
后面我将OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()换成OSSchedLock()和OSSchedUnlock() 问题依旧

出0入0汤圆

发表于 2007-3-13 08:58:15 | 显示全部楼层
我觉得第一个问题里面,你还需要判断AD是否转换完毕,未转换完则继续挂起自己.

任务1可以给任务2发送消息的(好象是这么叫,不太清楚了).也就是任务一采集完数据后,可以挂起本身,把CPU让给任务2,让任务2打印出来.

出0入0汤圆

 楼主| 发表于 2007-3-13 09:00:51 | 显示全部楼层
while(ADCSRA&0x10)

      {

         NOP();

      }

这个就是判断AD是否完成的代码

出0入0汤圆

 楼主| 发表于 2007-3-13 09:04:55 | 显示全部楼层
一直没有找到为什么g_adc_data没有改变的根本原因,使用volatile关键字声明,这种方式不对吗,还是其他的原因??

出0入0汤圆

发表于 2007-3-13 09:07:22 | 显示全部楼层
while(ADCSRA&0x10)  

      {  

         OSTimeDlyHMSM(0,0,0,1);

      }

至少要这样.你之前那么写起不了作用.后面的那句OSTimeDlyHMSM(0,0,0,1); 可以不要了.想用多任务就不应该出现死等的情况.

出0入0汤圆

 楼主| 发表于 2007-3-13 09:19:12 | 显示全部楼层
while(ADCSRA&0x10)   

      {   

         OSTimeDlyHMSM(0,0,0,1);

      }  

//实际进行一次转换上这个要不了1ms啊,是不是有点浪费了



谢谢各位对本贴的关注

出0入0汤圆

 楼主| 发表于 2007-3-13 09:55:48 | 显示全部楼层
一般各位在任务间共享数据采用的是什么方式啊,特别是共享一些数组

出0入0汤圆

 楼主| 发表于 2007-3-14 09:46:51 | 显示全部楼层
while(ADCSRA&0x10)   

      {   

         OSTimeDlyHMSM(0,0,0,1);  

      }  

至少要这样.你之前那么写起不了作用.后面的那句OSTimeDlyHMSM(0,0,0,1); 可以不要了.想用多任务就不应该出现死等的情况.





     我试了一下,问题依旧,而且我还发现一个现象,比如说我两个任务要共享一个全局变量,或者一个数组,A任务修改了全局变量或者数组,B任务要使用该全局变量,一个办法是A任务修改了全局变量或者数组后OSTimeDlyHMSM(0,0,0,6) (而且不能比6小 ),B任务才能够使用到正确的共享数据,OSTimeDlyHMSM太短,如OSTimeDlyHMSM(0,0,0,3),B任务就不能够使用到正确的数据。另外一个办法是,A任务修改了全局变量后OSTimeDlyHMSM(0,0,0,1),然后B在使用该共享数据前OSTimeDlyHMSM(0,0,0,6)或者更久,B也能使用到正确的数据,真是很奇怪,是不是OS_CFG.H里有什么没有配置好????

出0入0汤圆

 楼主| 发表于 2007-3-14 10:14:56 | 显示全部楼层
看来我走到死胡同了,无解???

出0入0汤圆

发表于 2007-3-14 19:57:34 | 显示全部楼层
问一下,你的Task1和Task2的优先级状况,系统的tick是多少ms?

可以看一下      g_adc_data = ADC;



      OS_ENTER_CRITICAL();

      Printf("通道数据是 %d\r
",g_adc_data);

      OS_EXIT_CRITICAL();

这两段的汇编代码,确认是否是从变量地址读取的。



另外,你只是在那个位置把OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()换成OSSchedLock()和OSSchedUnlock() 效果应该是一样的,任务调度是依赖于定时中断的。
-----此内容被gingin于2007-03-14,19:59:29编辑过

出0入0汤圆

 楼主| 发表于 2007-3-15 10:26:43 | 显示全部楼层
我现在发现了问题,就是堆栈溢出,导致Task1 挂了,挂了以后,TASK2去访问g_adc_data的数据就会出现g_adc_data每次读出来的数据都是一样的,但是我加大Task1的堆栈,只能保证Task1 跑得久一点,但最终也会挂掉,我将堆栈加大到512字节了,只能跑得更久一点,操作系统是在本网上下载的es_m128_test_board_by_yfzhang\ATmega128实验板里面的程序修改的,在此感谢yfzhang,不知到是不是这个移植的还不够完美,有一点BUG,请大家看看,能否帮帮我,谢谢

点击此处下载armok01146583.rar

出0入0汤圆

发表于 2007-3-15 10:59:58 | 显示全部楼层
???

ucos ii有本挺厚的书,是英文原版翻译过来的.早就出现在国内的.应该至少仔细看看书啊.

全局变量共享,信号量,互斥型信号量,油箱,消息队列,中断.这些都可以实现.

出0入0汤圆

发表于 2007-3-15 13:46:48 | 显示全部楼层
我现在也在研究堆栈溢出问题,不好办呀

出0入0汤圆

发表于 2007-3-15 22:55:20 | 显示全部楼层
这个就是生产者/消费者的模式,其实要实现楼主的功能,1个任务就可以了(除了idle任务以外),这个任务是消费者,生产者用中断服务程序就可以实现了。

大致的流程如下:

// 消费者任务

void consumer (void *)

{

    建立消息队列(OSQCreate);

    设置ADC中断处理;

    启动第一次ADC;

    while (1) {

        等待消息(OSQPend);

        打印数据;

    }

}

// 生产者中断服务

isr producer ()

{

    读取ADC结果;

    将结果数据作为消息发送到消息队列(OSQPost);

    启动下一次ADC;

}

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-5-20 20:38

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

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