uCOS-III移植问题 程序的可移植性卡死在空闲任务里 求助

uCOS-II论坛_专业的stm32/ucgui/avr ucos移植等技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
Powered by
供应链服务
商务及广告合作
Jeffery Guo
关注我们的微信
供应链服务 PCB/IC/PCBA
下载发烧友APP
版权所有 (C) 深圳华强聚丰电子科技有限公司查看: 1224|回复: 11
uCOSII中任务顺序执行一遍之后进入空闲任务不出来了
主题帖子精华
新手上路, 积分 15, 距离下一级还需 35 积分
在线时间4 小时
程序如下,浮点测试任务优先级为5,LED闪烁任务优先级为6,DMA发送任务优先级为7,下载程序到板子上后,顺序执行了上面三个任务之后,没有回到LED闪烁任务(优先级为6),而是直接进入了空闲任务不出来了。这是什么原因啊?查看了论坛里所有关于uCOS的帖子也没找到解决办法···求高手帮忙
#define START_TASK_PRIO& & & & & & & & & & & & 10&&
#define START_STK_SIZE& & & & & & & & & & & & 64
OS_TCB start_task_TCB;
OS_STK START_TASK_STK[START_STK_SIZE];
void start_task(void *pdata);
#define DMA_Send_TASK_PRIO& & & & & & & & & & & & 7
#define DMA_Send_STK_SIZE& & & & & & & & & & & & 128
OS_STK DMA_Send_TASK_STK[DMA_Send_STK_SIZE];
void DMA_Send_task(void *pdata);
#define led_trade_TASK_PRIO& & & & & & & & & & & & 6
#define led_trade_STK_SIZE& & & & & & & & 128
OS_STK led_trade_TASK_STK[led_trade_STK_SIZE];
void led_trade_task(void *pdata);
#define FLOAT_TASK_PRIO& & & & & & & & & & & & 5
#define FLOAT_STK_SIZE& & & & & & & & & & & & 128
__align(8) OS_STK FLOAT_TASK_STK[FLOAT_STK_SIZE];
void float_task(void *pdata);
u8 SendBuff[SEND_BUF_SIZE];
const u8 TEXT_TO_SEND[]={&iCore3 STM32F4 &};
extern u8 RECEIVEBuff[RECEIVE_BUF_SIZE];& & & &
int main(void)
& & & & u16
& & & & u8 t=0;
& & & & u8 j,mask=0;
& & & & NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
& & & & delay_init(168);&&
& & & & uart_init(115200);& & & &
& & & & led.initialize();
& & & & key.initialize();
& & & & //DMA配置
& & & & MYDMA_Config((u32)&USART4-&DR,(u32)SendBuff,SEND_BUF_SIZE,(u32)&USART4-&DR,(u32)RECEIVEBuff,RECEIVE_BUF_SIZE);
& & & & j=sizeof(TEXT_TO_SEND);& & & && &
& & & & for(i=0;i&SEND_BUF_SIZE;i++)
& & & & & & & & if(t&=j)
& & & & & & & & & & & & {
& & & & & & & & & & & & if(mask)
& & & & & & & & & & & & & & & & {
& & & & & & & & & & & & & & & & SendBuff=0x0a;
& & & & & & & & & & & & & & & & t=0;
& & & & & & & & & & & & & & & & }else
& & & & & & & & & & & & & & & & {
& & & & & & & & & & & & & & & & SendBuff=0x0d;
& & & & & & & & & & & & & & & & mask++;
& & & & & & & & & & & & & & & & }& & & &
& & & & & & & & & & & & }else
& & & & & & & & & & & & & & & & {
& & & & & & & & & & & & mask=0;
& & & & & & & & & & & & SendBuff=TEXT_TO_SEND[t];
& & & & & & & & & & & & t++;
& & & & & & & & & & & & & & & & }& && & & && &
& & }& & & & & & & &&&
& & & & i=0;
& & & & OSInit();
& & & & OSTaskCreate(start_task,(void*)0,(OS_STK*)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO);
& & & & OSStart();&&
//开始任务
void start_task(void *pdata)
& & & & OS_CPU_SR cpu_sr=0;
& & & & pdata=
& & & & OSStatInit();&&
& & & & OS_ENTER_CRITICAL();
& & & & OSTaskCreate(DMA_Send_task,(void*)0,(OS_STK*)&DMA_Send_TASK_STK[DMA_Send_STK_SIZE-1],DMA_Send_TASK_PRIO);
& & & & OSTaskCreate(led_trade_task,(void*)0,(OS_STK*)&led_trade_TASK_STK[led_trade_STK_SIZE-1],led_trade_TASK_PRIO);
& & & & OSTaskCreate(float_task,(void*)0,(OS_STK*)&FLOAT_TASK_STK[FLOAT_STK_SIZE-1],FLOAT_TASK_PRIO);
& & & & OSTaskSuspend(START_TASK_PRIO);//挂起开始任务
& & & & OS_EXIT_CRITICAL();&&
//DMA发送数据
void DMA_Send_task(void *pdata)
& & & & while(1)
& & & & & & & & if(KEY_INPUT)
& & & & & & & & {
& & & & & & & & & & & & MYDMA_Enable(DMA1_Stream4,SEND_BUF_SIZE);
& & & & & & & & }
& & & & & & & & OSTaskSuspend(DMA_Send_TASK_PRIO);//1òÆeèÎÎñ
//LED闪烁提示系统正在运行
void led_trade_task(void *pdata)
& & & & while(1)
& & & & & & & & LED_GREEN_ON;
& & & & & & & & delay_us(50000);
& & & & & & & & LED_BLUE_OFF;
& & & & & & & & delay_us(50000);
& & & & & & & & LED_GREEN_OFF;
& & & & & & & & delay_us(50000);
& & & & & & & & LED_BLUE_ON;
& & & & & & & & delay_us(50000);
& & & & & & & & OSTimeDlyHMSM(0,0,0,100);
//浮点测试任务
void float_task(void *pdata)
& & & & OS_CPU_SR cpu_sr=0;
& & & & static float float_num=0.01;
& & & & while(1)
& & & & & & & & float_num+=0.01f;
& & & & & & & & OS_ENTER_CRITICAL();
& & & & & & & & printf(&float_numμÄÖμÎa: %f\r\n&,float_num);
& & & & & & & & if(float_num&=1)
& & & & & & & & & & & & {
& & & & & & & & & & & & & & & & OSTaskSuspend(FLOAT_TASK_PRIO);
& & & & & & & & & & & & }
& & & & & & & & OS_EXIT_CRITICAL();
(68.15 KB, 下载次数: 0)
15:39 上传
(92.44 KB, 下载次数: 0)
15:39 上传
(24.33 KB, 下载次数: 0)
15:39 上传
主题帖子精华
金钱115049
在线时间865 小时
你这个临界区设置有问题吧?在临界区里面挂起任务,不知道可不可行哦,别这么干试试。
主题帖子精华
新手上路, 积分 15, 距离下一级还需 35 积分
在线时间4 小时
你这个临界区设置有问题吧?在临界区里面挂起任务,不知道可不可行哦,别这么干试试。
恩恩,我试试看先
主题帖子精华
新手上路, 积分 15, 距离下一级还需 35 积分
在线时间4 小时
你这个临界区设置有问题吧?在临界区里面挂起任务,不知道可不可行哦,别这么干试试。
已经尝试着在临界区外面把任务挂起了,但还是不行,好心塞,修改后的程序代码如下
//开始任务
void start_task(void *pdata)
& & & & OS_CPU_SR cpu_sr=0;
& & & & pdata=
& & & & OSStatInit();&&
& & & & OS_ENTER_CRITICAL(); 、
& & & & OSTaskCreate(DMA_Send_task,(void*)0,(OS_STK*)&DMA_Send_TASK_STK[DMA_Send_STK_SIZE-1],DMA_Send_TASK_PRIO);
& & & & OSTaskCreate(led_trade_task,(void*)0,(OS_STK*)&led_trade_TASK_STK[led_trade_STK_SIZE-1],led_trade_TASK_PRIO);
& & & & OSTaskCreate(float_task,(void*)0,(OS_STK*)&FLOAT_TASK_STK[FLOAT_STK_SIZE-1],FLOAT_TASK_PRIO);
& & & & OS_EXIT_CRITICAL();&&
& & & & OSTaskSuspend(START_TASK_PRIO);
//浮点测试任务
void float_task(void *pdata)
& & & & OS_CPU_SR cpu_sr=0;
& & & & static float float_num=0.01;
& & & & while(1)
& & & & & & & & float_num+=0.01f;
& & & & & & & & OS_ENTER_CRITICAL();
& & & & & & & & printf(&float_numμÄÖμÎa: %f\r\n&,float_num);
& & & & & & & & OS_EXIT_CRITICAL();
& & & & & & & & if(float_num&=1)
& & & & & & & & & & & & {
& & & & & & & & & & & & & & & & OSTaskSuspend(FLOAT_TASK_PRIO);//1òÆeèÎÎñ
& & & & & & & & & & & & }
主题帖子精华
新手上路, 积分 15, 距离下一级还需 35 积分
在线时间4 小时
你这个临界区设置有问题吧?在临界区里面挂起任务,不知道可不可行哦,别这么干试试。
原子哥,知道问题大概出现的地方了,应该是我用DMA串口发送数据的过程中做了什么导致了UCOSII进入了空闲任务出不来。在这个过程中,我采用的是中断的方式,是不是我的中断服务程序中做了什么不该做的事情啊?DMA中断服务程序以及串口中断服务程序如下
//DMA发送中断处理函数
void DMA1_Stream4_IRQHandler(void)
#if SYSTEM_SUPPORT_OS & & & &
OSIntEnter();
& & & & if(DMA_GetITStatus(DMA1_Stream4,DMA_IT_TCIF4)!=RESET)
& & & & & & & & //清除标志位
& & & & & & & & DMA_ClearFlag(DMA1_Stream4,DMA_FLAG_TCIF4);
& & & & & & & & //关闭DMA
& & & & & & & & DMA_Cmd(DMA1_Stream4,DISABLE);
& & & & & & & & //打开发送完成中断
& & & & & & & & USART_ITConfig(USART4,USART_IT_TC,ENABLE);
#if SYSTEM_SUPPORT_OS & & & &
& & & & OSIntExit(); & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &&&
#endif & & & &
//串口中断服务函数
void UART4_IRQHandler(void)
& & & & u16 LEN;
#if SYSTEM_SUPPORT_OS
& & & & OSIntEnter();
& && &&&//发送完成中断处理,只是简单地清除标志位,并未做其他事情
& & & & if(USART_GetITStatus(USART4, USART_IT_TC) != RESET)
& & & & & & & & USART_ClearFlag(USART4,USART_FLAG_TC);//清零TC标志位
& & & & //接收完成中断处理
& & & & if(USART_GetITStatus(USART4, USART_IT_IDLE) != RESET)&&
& & & & & & & & //清标志
& & & & & & & & USART4-&SR;
& & & & & & & & USART4-&DR;
& & & & & & & & //关闭DMA
& & & & & & & & DMA_Cmd(DMA1_Stream2,DISABLE);
& & & & & & & & //清除标志位
& & & & & & & & DMA_ClearFlag(DMA1_Stream2,DMA_FLAG_TCIF2);
& & & & & & & & //获取接收帧帧长
& & & & & & & & LEN=RECEIVE_BUF_SIZE-DMA_GetCurrDataCounter(DMA1_Stream2);
& & & & & & & & //重新设置DMA传输数据长度& & & & & & & & & & & & & & & & & & & && && &
& & & & & & & & DMA_SetCurrDataCounter(DMA1_Stream2,RECEIVE_BUF_SIZE);
& & & & & & & & //打开DMA
& & & & & & & & DMA_Cmd(DMA1_Stream2,ENABLE);& & & &
#if SYSTEM_SUPPORT_OS
& & & & OSIntExit(); & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &&&
主题帖子精华
金牌会员, 积分 1149, 距离下一级还需 1851 积分
在线时间143 小时
如果没有业务,只是几个task之间的延时切换有问题吗?
主题帖子精华
新手上路, 积分 15, 距离下一级还需 35 积分
在线时间4 小时
如果没有业务,只是几个task之间的延时切换有问题吗?
恩,可以的。昨天晚上通过注释掉具体任务内容,只留下简单的三个任务直接的切换,是可以完成调度切换的,加入简单的LED闪烁提示也是可以实现调度切换,不会导致进入空闲任务出不了。唯一的问题就出在我在任务中启动DMA串口发送,就会进入空闲任务死循环里边,所以基本可以确定问题就出在这一块了。不知道我分析的方向是不是对的,但是从昨晚一直做的几个实验(包括重新移植UCOSII以及使用探索者开发板的UCOSII例程进行修改,两种方式)来看,现象是这样子的
主题帖子精华
金牌会员, 积分 1149, 距离下一级还需 1851 积分
在线时间143 小时
恩,可以的。昨天晚上通过注释掉具体任务内容,只留下简单的三个任务直接的切换,是可以完成调度切换的, ...
原理上,DMA不会对操作系统有影响,你可以尝试看下systick的配置是不是被改变了~ucos的核心调度都是基于systick的时钟
主题帖子精华
新手上路, 积分 15, 距离下一级还需 35 积分
在线时间4 小时
原理上,DMA不会对操作系统有影响,你可以尝试看下systick的配置是不是被改变了~ucos的核心调度都是基于s ...
对不起,可以提示一下是systick的哪方面的配置被改变了吗?因为用的是探索者开发板的例程修改来的,只修改了外部晶振频率,由原来探索者开发板的8MHz改成了24MHz的外部晶振。修改的地方如下:
(1)、system_stm32f4xx.c文件中#define PLL_M&&8修改为#define PLL_M& && &24
(2)、stm32f4xx.h文件中的#define HSE_VALUE ((uint32_t)8000000)修改为#define HSE_V& &ALUE& & ((uint32_t))
其他地方均没有动,包括& && &&&主函数中的时钟初始化delay_init(168);没有修改
主题帖子精华
金牌会员, 积分 1149, 距离下一级还需 1851 积分
在线时间143 小时
对不起,可以提示一下是systick的哪方面的配置被改变了吗?因为用的是探索者开发板的例程修改来的,只修 ...
看下systick的寄存器,也就是说在你使能了DMA后,有没有导致systick的寄存器配置变了,导致操作系统不会切换任务了
主题帖子精华
新手上路, 积分 15, 距离下一级还需 35 积分
在线时间4 小时
看下systick的寄存器,也就是说在你使能了DMA后,有没有导致systick的寄存器配置变了,导致操作系统不会 ...
恩恩,那我先看看~
主题帖子精华
中级会员, 积分 390, 距离下一级还需 110 积分
在线时间102 小时
给个tips,任务切换的原理是高优先级的任务抢断低优先级的处理器,当高优先级占用处理器的时候因为死循环或者什么原因导致处于一个等待状态,从而没有释放处理器,这就会导致低优先级的任务无法运行
Powered byuCOS任务是如何从空闲任务里切换出去
原文:.cn/thread/
每个任务都有自己的优先级,自己的堆栈,自己的寄存器,CPU(中央处理单元)依靠任务的优先级在多个任务之间转换,调度任务。每个任务执行时,独占CPU.
UCOS的空闲任务OS_TaskIdle
当然也不例外。UC/OS-Ⅱ在任务创建之初就建立一个空闲任务,这个任务在没有其它任务进入就绪态时投入运行。这个空闲任务[OSTaskIdle()]永远设为最低优先级,它什么也不做,只是在不停地给一个32位的名叫OSIdleCtr的计数器加1,统计任务使用这个计数器以确定现行应用软件实际消耗的CPU时间。空闲任务不可能被应用软件删除。
我们先来看一下我们自己创建任务的一般结构。如下所示:
void Task_USER_A(void *pdata)&
&&& //用户代码
..............
&&& //用户代码
&&&OSTimeDly();&&&&&
&&&OSTimeDlyHMSM();&
在每个已经建立的任务(idel除外)中都会看到(1)或(2)这样的延时函数,(1)/(2)实现任务延时,将当前的任务挂起一段时间,延时函数中会去查询任务就续表中优先级最高的任务,通过调用任务调度OSSched()完成任务切换。挂起当前任务,才能让比当前任务优先级低的任务得到CPU而执行。
很多初学者这个可以理解,但是空闲任务却没有调用(1)/(2)延时函数。我们看一下空闲任务的代码,如下:
void& OS_TaskIdle (void *pdata)
OS_CPU_SR&
&&&&&&&&&&&&&&&
OS_ENTER_CRITICAL();&&&&&&
&&&&&&&&&OSIdleCtr++;
&&&&&&&&&OS_EXIT_CRITICAL();&&&&&
OSTaskIdleHook();&&&&&&&&&&&&&&&&&&&&&&
但看这个任务和前面的任务切换机制,我们难免会在这里糊涂。其实我们只要认真看一下OSTimeTick()就可以明白了。源码我们就不再列出来了,只是说一下执行过程。
时钟节拍服务是通过在中断服务子程序中调用OSTimeTick()实现的,OSTimeTick()中将每个用户任务控制块OS_TCB中的时间延时项OSTCBDly减1(就是在任务中OSTimeDly();所设定的延时时间减一)。当某任务的任务控制块中的时间延时项OSTCBDly减到了零,这个任务就进入了就绪态。中断服务结束还会调用OSIntExit(),在OSIntExit()中会查询任务就绪表,如果有优先级高的任务就绪则执行任务切换。
看到这里我们就会明白,其实真正执行任务切换功能的函数是OSTimeTick()。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。uCOS-III移植到stm32_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
uCOS-III移植到stm32
&&uCOS-III在MDK环境下的移植
阅读已结束,下载文档到电脑
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩15页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
uCOS-III中文翻译.pdf 328页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
下载提示
1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
2.该文档所得收入(下载+内容+预览三)归上传者、原创者。
3.登录后可充值,立即自动返金币,充值渠道很便利
需要金币:200 &&
你可能关注的文档:
··········
1-1前后台系统
1-2实时内核
1-3实时系统(RTOS)
1-4uC/OS-III
1-5uC/OS,uC/OS-II,uC/OS-III的性能对比
1-6这本书的编排方式
1-7探针uC/Probe
1-9章节目录
2、目录和文件
2-1应用代码
2-3板级支持包(BSP)
2-4uC/OS-III 中独立于CPU的源文件
2-5uC/OS-III 中CPU相关的源代码
2-6uC/CPU,CPU相关代码
2-7uC/LIB可移植的函数库
3、开始学习uC/OS-III
3-1单任务应用
3-2 内核对象与多任务应用
4 、临界段
4-1-1测量关中断时间
4-2锁住调度器
4-2-1测量锁调度器时间
4-3uC/OS-III与长临界段
5、任务管理
5-1设置任务优先级
5-2堆栈空间大小的确定
5-3检测任务堆栈的溢出
使用MMU或MPU
堆栈溢出检测寄存器
基于软件的堆栈溢出检测
计算空闲堆栈空间
5-4任务管理服务
5-5 内部任务管理
5-5-1任务状态
5-5-2任务控制块TCB
5-6 内部任务
5-6-1空闲任务OS_IdleTask()
5-6-2时基任务OS-TickTask()
5-6-3统计任务OS_StatTask()
5-6-4定时器任务OS_TmrTask()
5-6-5中断处理任务OS_IntQTask()
6、就绪列表
6-2就绪列表
6-3添加任务到就绪队列
7-1抢占式调度
7-3循环轮转调度
7-4调度的内部实现
7-4-1OSSched()
7-4-2OSIntExit()
7-4-3OS_SchedRoundRobin()
8、上下文切换
8-1OSCtxSw()
8-2OSIntCtxSw()
9、中断管理
9-1CPU的中断处理
9-2典型的中断服务程序
9-3短中断服务程序(ISR)
9-5每个中断向量指向不同的地址
9-6直接提交和延迟提交
9-6-1直接提交
9-6-2延迟提交方式
9-7直接提交VS延迟提交
9-8系统时基
10、挂起队列
11、时间管理
11-1OSTimeDly()
11-2OSTimeDlyHMSM()
11-3OSTimeDlyResume()
11-4OSTimeSet()和OSTimeGet()
11-5OSTimeTick()
12、软件定时器管理
12-1一次性定时模式
12-3有初始定时周期模式
12-4内部定时器管理
12-4-1内部定时器管理-定时器状态
12-4-2定时器内部管理——OS_TMR
12-4-3内部定时器管理——定时器任务
12-4-4内部定时器管理——定时器列表
13、资源管理
13-1关中断
13-2锁调度器
13-3信号量
13-3-1二值信号量
正在加载中,请稍后...}

我要回帖

更多关于 qt程序移植到开发板 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信