|
我参照别人写的OS_CPU_A.s 的文件(其实差不多一模一样),建了两个任务。但是在调试的时候 在(第一次)进入第一个任务tasktest (void *pdata)-->OSTimeDly(3)-->切换到任务2(第一次) tasktest2(void *pdata)--->OSTimeDly(2)---->(第一次)进入OSTaskIdle——>(第一次)OSTickISR(没有嵌套中断)--->(第二次)进入OSTaskIdle--->(第二次)OSTickISR--->(第二次)切换到任务2 tasktest2(void *pdata) <前面按照程序设计逻辑正确,后面> --->在OSTimeTick,一直没有出来(没有进入OSTaskIdle),有的时候直至回到OSInit() 重新开始。。。求教各位,请问这是怎么回事呢,,难道avrstudio没有设置对吗(没有优化,也是这样)? 标志寄存器 SREG:I 打开的时候,timer0 在CTC模式下 OCR0与TCN0匹配的时候,也没有发生中断。。。(可气的是,程序在以后尽然自己关闭了 SREG:I )
主文件 summer_289.c
#include <avr/io.h>
#include<avr/interrupt.h>
#include "./source/ucos_ii.h"
#include "userdef.h"
#include <stdio.h>
#define stk_size 500
OS_STK teststk[stk_size];
OS_STK teststk2[stk_size];
//OS_EVENT *ResourceSem;
void tasktest(void* pdata);
void tasktest2(void* pdata);
int main (void)
{
OSInit();
OSTaskCreate(tasktest,0,&teststk[stk_size-1],2);
OSTaskCreate(tasktest2,0,&teststk2[stk_size-1],3);
OSStart();
}
void tasktest (void *pdata)
{
//USART0_UDRE_init(0,0,0,0);
CTC_TIMER0_init();
sei();
while(1)
{
DDRB=0xFF;
PORTB=~PORTB;
// printf("hello word !");
OSTimeDly(3);
}
}
void tasktest2(void *pdata)
{
while(1)
{
DDRA=0XFF;
PORTA=~PORTA;
OSTimeDly(2);
}
}
-----------------------------------------------------------------------------------------------------------------------------------------
OS_CPU_C.c
#include "./source/ucos_ii.h"
OS_STK *OSTaskStkInit (void (*task)(void *p_arg),void *p_arg,OS_STK *ptos,INT16U opt)
{
OS_STK *stk=ptos;
*stk--=(unsigned char)(((unsigned int)task)&0xff;
*stk--=(unsigned char)(((unsigned int)task)>>8);
*stk--=0x31;
*stk--=0x30;//Z
*stk--=0x29;
*stk--=0x28;//Y
*stk--=0x27;
*stk--=0x26;//X
*stk--=((unsigned int)p_arg)&0xff;
*stk--=((unsigned int)p_arg)>>8; *stk--=0x23;
*stk--=0x22;
*stk--=0x21;
*stk--=0x20;
*stk--=0x19;
*stk--=0x18;
*stk--=0x17;
*stk--=0x16;
*stk--=0x15;
*stk--=0x14;
*stk--=0x13;
*stk--=0x12;
*stk--=0x11;
*stk--=0x10;
*stk--=0x09;
*stk--=0x08;
*stk--=0x07;
*stk--=0x06;
*stk--=0x05;
*stk--=0x04;
*stk--=0x03;
*stk--=0x02;
*stk--=0x00;
*stk--=0x00;//
*stk--=0x80;//SREG
return ((OS_STK *)stk);
}
OS_CPU_A.S
#include <avr/io.h
.extern OSRunning
.extern OSTCBHighRdy
.extern OSTCBCur
.extern OSPrioHighRdy
.extern OSPrioCur
.extern OSIntNesting
.extern OSTimeTick
.extern OSIntExit
.macro POPRGS
POP R16
OUT _SFR_IO_ADDR(SREG),R16
POP R0
POP R1
POP R2
POP R3
POP R4
POP R5
POP R6
POP R7
POP R8
POP R9
POP R10
POP R11
POP R12
POP R13
POP R14
POP R15
POP R16
POP R17
POP R18
POP R19
POP R20
POP R21
POP R22
POP R23
POP R24
POP R25
POP R26
POP R27
POP R28
POP R29
POP R30
POP R31//也不知道有没有一句话就可以全压栈和出栈的
.endm
////////////////////////////////////////////////////////
.macro PUSHRGS
PUSH R31
PUSH R30
PUSH R29
PUSH R28
PUSH R27
PUSH R26
PUSH R25
PUSH R24
PUSH R23
PUSH R22
PUSH R21
PUSH R20
PUSH R19
PUSH R18
PUSH R17
PUSH R16
PUSH R15
PUSH R14
PUSH R13
PUSH R12
PUSH R11
PUSH R10
PUSH R9
PUSH R8
PUSH R7
PUSH R6
PUSH R5
PUSH R4
PUSH R3
PUSH R2
PUSH R1
PUSH R0
IN R16,_SFR_IO_ADDR(SREG)
PUSH R16
.endm
/*-------------------------------------------------------------------*/
.global OSStartHighRdy
.type OSTaskHighRdy,#function
.section .text,"ax"
OSStartHighRdy:
/**********************************************
IN R28,_SFR_IO_ADDR(SPL)
IN R29,_SFR_IO_ADDR(SPH)
ADIW R28,4
OUT _SFR_IO_ADDR(SPL),R28
OUT _SFR_IO_ADDR(SPH),R29
LDS R30,OSTCBCur
LDS R31,OSTCBCur+1
***********************************************/
#if OS_TASK_SW_HOOK_EN > 0u
CALL OSTaskSwHook
#endif
//直接到最高优先级的任务中去
LDS R30,OSTCBHighRdy
LDS R31,OSTCBHighRdy+1
LD R16,Z+
LD R17,Z
OUT _SFR_IO_ADDR(SPL),R16
OUT _SFR_IO_ADDR(SPH),R17
LDS R16,OSRunning
INC R16
STS OSRunning,R16
POPRGS
RET
///////////////////////////////////////////////////////
.global OSCtxSw
.type OSCtxSw,#function
.section .text,"ax"
OSCtxSw:
PUSHRGS //保存寄存器
//保存任务栈栈顶指针
IN R16,_SFR_IO_ADDR(SPL)
IN R17,_SFR_IO_ADDR(SPH)
LDS R30,OSTCBCur
LDS R31,OSTCBCur+1
ST Z+,R16
ST Z,R17
//
#if OS_TASK_SW_HOOK_EN > 0u
.extern OSTaskSwHook
CALL OSTaskSwHook
#endif
LDS R30,OSTCBHighRdy
LDS R31,OSTCBHighRdy+1
STS OSTCBCur,R30
STS OSTCBCur+1,R31
LD R16,Z+
LD R17,Z //获取下面要进行的任务的栈顶(地址值),即Z指向的内容
OUT _SFR_IO_ADDR(SPL),R16
OUT _SFR_IO_ADDR(SPH),R17 //已经将任务栈的栈顶指针切换到准备下面要进行的任务的栈顶
//记录当前的优先级
LDS R16,OSPrioHighRdy
STS OSPrioCur,R16 //于将优先的比较有指针比较转换为整数比较
POPRGS
RET
///////////////////////////////////////////////////*中断级别的切换
.global OSIntCtxSw
.type OSIntCtxSw,#function
.section .text,"ax"
OSIntCtxSw:
#if OS_TASK_SW_HOOK_EN > 0u
CALL OSTaskSwHook
#endif
IN R24,_SFR_IO_ADDR(SPL)
IN R25,_SFR_IO_ADDR(SPH)
adiw r24,4
#if OS_CRITICAL_METHOD==2
adiw r24,1
#endif
#if OS_CRITICAL_METHOD==3
adiw r24,1
#endif
OUT _SFR_IO_ADDR(SPL),R24
OUT _SFR_IO_ADDR(SPH),R25
LDS R30,OSTCBCur
LDS R31,OSTCBCur+1
ST Z+,R24
ST Z,R25
//切换大高优先级任务
LDS R30,OSTCBHighRdy
LDS R31,OSTCBHighRdy+1
LD R16,Z+
LD R17,Z
OUT _SFR_IO_ADDR(SPL),R16
OUT _SFR_IO_ADDR(SPH),R17
STS OSTCBCur,R30
STS OSTCBCur+1,R31 //保存当前任务的tcb指针
LDS R16,OSPrioHighRdy
STS OSPrioCur,R16 //记录当前的优先级
POPRGS
RET
/************************************************************************************
(1)保存全部CPU寄存器的值;
(2)调用OSIntEnter(),或直接把全局变量
OSIntNesting(中断嵌套层次)加1;
(3)执行用户代码做中断服务;
(4)调用OSIntExit();
(5)恢复所有CPU寄存器;
(6)执行中断返回指令。
***************************************************************************************/
.global OSTimeISR
.global TIMER0_COMP_vect
TIMER0_COMP_vect:
OSTimeISR:
PUSHRGS
LDS R16,OSIntNesting
INC R16
STS OSIntNesting,R16
CALL OSTimeTick
CALL OSIntExit
POPRGS
RETI
.end
工程文件一直传不上来 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
如果天空是黑暗的,那就摸黑生存;
如果发出声音是危险的,那就保持沉默;
如果自觉无力发光,那就蜷伏于牆角。
但是,不要习惯了黑暗就为黑暗辩护;
也不要为自己的苟且而得意;
不要嘲讽那些比自己更勇敢的人。
我们可以卑微如尘土,但不可扭曲如蛆虫。
|