打印
[AVR单片机]

AVR新手移植small rtos第二版,欢迎测试,期待高手指点。

[复制链接]
3842|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ATmega8515|  楼主 | 2007-5-6 10:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
据AVR实际情况,改动原版Small RTOS51的地方: 
1.   任务切换保存全部32个寄存器,SREG,Os_Enter_Sum和返回地址(共36字节),不区分任务快速切换和一般任务切换,OSCtxSw()和OSIntCtxSw()为同一函数。 
#define OSIntCtxSw()   OSCtxSw()  //在OS_CPU.h。 
2.   空闲任务OSIdle()也有自己一份堆栈。 
3.   不是将所有剩余SRAM空间分配给系统堆栈,系统堆栈空间大小由自己设定 
#define    OS_STACK_SIZE    512      //在OS_CPU.h,系统堆栈空间大小(包括空闲任务OSIdle的堆栈) 
4.   OS_CPU_A.s新加了一个头文件,Os_cpu_a.h。本想把这个头文件放到OS_CPU.H里的,但不知道GCC标记C程序生成的宏是什么(在KEIL C里面,标记C程序的宏是 #define __C51__)。 

****************************************************************************************** 
AVR新手移植Small RTOS 1.12到ATmega16,欢迎测试,期待高手指点。 

发现上一版汇编代码中有严重,明显的错误,导致非系统管理中断不能使用,更新第二版 
1.新加EN_OSStkChk,在OS_CPU.h里,#define EN_OSStkChk         1 
根据两个全局变量OSStk_Null,OSStk_Min_Null查看切换任务时系统堆栈剩余大小。可以参考此值调整OS_STACK_SIZE大小。 
2.去掉Os_cpu_a.h,放到OS_CPU.h 
3.更改OSIntCtxSw(),使之适应非系统管理中断。 

中断使用方法说明: 
1系统管理中断,中断结束时进行任务切换。 
SIGNAL(……) 

#if EN_OS_INT_ENTER >0 
        OS_INT_ENTER(); 
#endif 
…… 

…… 
OSIntExit(); 


2. 系统管理中断,中断结束时不进行任务切换。 
普通中断写法,中断中不能再开中断。 

3.非系统管理中断 
#define EN_SP2              1    //打开非系统管理中断 
普通中断写法,中断中不能再开中断,还需要改写三个宏 
OS_ENTER_CRITICAL() 打开总中断,关闭系统管理中断(包括系统时钟中断) 
OS_EXIT_CRITICAL() 打开总中断,打开系统管理中断(包括系统时钟中断) 
OS_SET_INT打开总中断,打开系统管理中断(包括系统时钟中断),不需要对Os_Enter_Sum减一操作,R0暂存SREG。 


附:任务切换函数OSCtxSw()汇编代码: 
#define OS_CPU_A 
#include "Os_cpu.h" 

.text 
.section .text 

OSCtxSw: 
       PUSHALL    
       
      lds   r24,Os_Enter_Sum 
      push    r24 

      in   r24, SREG   ; 
      push   r24 

;   SaveSP=SP; 
      in   r6, SPL 
      in   r7, SPH 

#if  EN_SP2>0   
.extern Sp2 
      in r0,SREG 
      cli 
      ldi r25,hi8(Sp2+Sp2Space-1) 
      ldi r24,lo8(Sp2+Sp2Space-1) 
      out SPH,r25 
      out SREG,r0 
      out SPL,r24 
#endif 
    
   ;cp1=SaveSP; 
         movw   r8, r6 
             
;   temp_p= (uint16)OSTaskStackBottom[OSNextTaskID+1]; 
      lds   r24, OSNextTaskID 
        mov   r18, r24 
         eor   r19, r19 
          movw   r24, r18 
         add   r24, r18 
         adc   r25, r19 
         movw   r30, r24 
         subi   r30, lo8(-(OSTaskStackBottom+2))    
         sbci   r31, hi8(-(OSTaskStackBottom+2)) 
          ld   r12, Z 
         ldd   r13, Z+1    
             
   ;cp2=(uint16)(OSTaskStackBottom[OSTaskID+1]); 
       lds   r24, OSTaskID 
         mov   r18, r24 
          eor   r19, r19 
          movw   r24, r18 
         add   r24, r18 
         adc   r25, r19 
         movw   r30, r24 
          subi   r30, lo8(-(OSTaskStackBottom+2)) 
          sbci   r31, hi8(-(OSTaskStackBottom+2)) 
         ld   r10, Z 
          ldd   r11, Z+1    
    
   ;if(OSTaskID<OSNextTaskID) 
      lds   r24, OSTaskID 
      lds   r25, OSNextTaskID 
         cp   r24, r25 
         brcs   .+2       
         rjmp   OSCtxSw_5     
       
      ;{while(cp2!=temp_p) 
OSCtxSw_1: 
         cp   r10, r12 
          cpc   r11, r13 
        breq   OSCtxSw_2     
    
      ;{*(uint8 *)cp1=*(uint8 *)cp2; 
          movw   r30, r8 
         movw   r26, r10 
         ld   r24, X 
        st   Z, r24 
       
      ;   cp1--;cp2--;} 
          sec 
        sbc   r8, r1 
         sbc   r9, r1 
         sec 
         sbc   r10, r1 
        sbc   r11, r1 
         rjmp   OSCtxSw_1              
   ;    
OSCtxSw_2: 
    
   ;   temp16=cp1-cp2; 
         movw   r4, r8 
         sub   r4, r10 
         sbc   r5, r11 
       
;      for(i8=OSTaskID+1;i8<OSNextTaskID+1;i8++) 
      lds   r24,OSTaskID 
         mov   r2, r24 
         inc   r2 

OSCtxSw_3:         
        mov   r18, r2 
        eor   r19, r19 
       lds   r24, OSNextTaskID 
         eor   r25, r25 
          adiw   r24, 0x01   ; 1 
         cp   r18, r24 
         cpc   r19, r25 
         brge   OSCtxSw_4     
       
      ;   {   OSTaskStackBottom[i8]+=temp16;   } 
        mov   r18, r2 
         eor   r19, r19 
       movw   r24, r18 
         add   r24, r18 
         adc   r25, r19 
        movw   r26, r24 
         subi   r26, lo8(-(OSTaskStackBottom))    
         sbci   r27, hi8(-(OSTaskStackBottom))    
          
      movw r30,r26 
          ld   r24, Z 
         ldd   r25, Z+1 
         add   r24, r4 
          adc   r25, r5 
          adiw   r26, 0x01   ; 1 
         st   X, r25 
         st   -X, r24 
          inc   r2 
          rjmp    OSCtxSw_3     
    
   ;   OSTaskID=OSNextTaskID; 
OSCtxSw_4: 
   lds   r24, OSNextTaskID 
    sts   OSTaskID, r24 

      ;SP=cp1; 
      in R0,SREG 
      cli 
       out   SPH, r9 
      out SREG,R0 
       out   SPL, r8 


#if EN_OSStkChk 
      .extern OSStk_Null 
      .extern OSStk_Min_Null 
      sts OSStk_Null+1,r5 
      sts OSStk_Null,r4 
      lds r25,OSStk_Min_Null+1 
      lds r24,OSStk_Min_Null 
      cp r24,r4 
      cpc r25,r5 
      brcc    .+2 
      Rjmp OSCtxSw_4_1 
      sts OSStk_Min_Null+1,R5 
      sts OSStk_Min_Null,R4 
#endif 

OSCtxSw_4_1:    
;      goto loadctx; 
          rjmp   OSCtxSw_11      


;   else if(OSNextTaskID<OSTaskID) 
OSCtxSw_5: 
      lds   r25, OSNextTaskID 
       lds   r24, OSTaskID 
         cp   r25, r24 
         brcs   .+2          
         rjmp   OSCtxSw_10        
       
       
      ;{   while(cp1!=temp_p) 
OSCtxSw_6: 
       cp   r8, r12 
        cpc   r9, r13 
        breq   OSCtxSw_7      
          
         ;{      *(uint8 *)(++cp2)=*(uint8 *)(++cp1);} 
        sec 
        adc   r10, r1 
        adc   r11, r1 
          movw   r30, r10 
         sec 
         adc   r8, r1 
         adc   r9, r1 
         movw   r26, r8 
         ld   r24, X 
         st   Z, r24 
         rjmp   OSCtxSw_6     

   ; 
OSCtxSw_7: 

   ;   temp16=cp1-cp2; 
         movw   r4, r8 
        sub   r4, r10 
        sbc   r5, r11 

      ;for(i8=OSNextTaskID+1;i8<OSTaskID+1;i8++) 
      lds   r24, OSNextTaskID 
         mov   r2, r24 
         inc   r2 
OSCtxSw_8:      
       mov   r18, r2 
         eor   r19, r19 
      lds   r24,OSTaskID 
        eor   r25, r25 
         adiw   r24, 0x01    
         cp    r18,r24 
         cpc    r19,r25 
        brge   OSCtxSw_9    
    
;      {      OSTaskStackBottom[i8]-=temp16;} 
        mov   r18, r2 
         eor   r19, r19 
         movw   r24, r18 
         add   r24, r18 
         adc   r25, r19 
         movw   r26, r24 
         subi   r26, lo8(-(OSTaskStackBottom))    
          sbci   r27, hi8(-(OSTaskStackBottom))    
          
      movw r30,r26 
        ld   r24, Z 
         ldd   r25, Z+1 
         sub   r24, r4 
          sbc   r25, r5 
        adiw   r26, 0x01   ; 1 
         st   X, r25 
         st   -X, r24 
         inc   r2 
           rjmp   OSCtxSw_8      

   ;   OSTaskID=OSNextTaskID; 
OSCtxSw_9: 
       lds   r24, OSNextTaskID 
      sts   OSTaskID, r24 

   ;SP=cp1 
      in R0,SREG 
      cli 
       out   SPH, r9 
      out SREG,R0 
       out   SPL, r8 


#if EN_OSStkChk 
      .extern OSStk_Null 
      .extern OSStk_Min_Null 
      sts OSStk_Null+1,r5 
      sts OSStk_Null,r4 
      lds r25,OSStk_Min_Null+1 
      lds r24,OSStk_Min_Null 
      cp r24,r4 
      cpc r25,r5 
      brcc    .+2 
      Rjmp OSCtxSw_9_1 
      sts OSStk_Min_Null+1,R5 
      sts OSStk_Min_Null,R4 
#endif 



OSCtxSw_9_1: 
   ;   goto loadctx; 
         rjmp   OSCtxSw_11         
OSCtxSw_10: 
 ;      else SP=SaveSP; 
         in r0,SREG 
         cli 
      out   SPH, r7 
      sts 0x5f,r0 
      sts   0x005D, r6 
   ;   goto loadctx; 

OSCtxSw_11:    
;loadctx: 

      pop r0      //SREG暂存 
      pop r24      //Os_Enter_Sum 
      sts Os_Enter_Sum,r24    
      and r24,r24 
      brne   OSCtxSw_12       
      OS_SET_INT 

OSCtxSw_12:    
      out SREG,r0    
      POPALL    
      ret 

相关帖子

沙发
ATmega8515|  楼主 | 2007-5-6 10:23 | 只看该作者

移植代码

使用特权

评论回复
板凳
zbh| | 2012-1-9 15:51 | 只看该作者
请问,你是在keil中编程的吗?它的机器代码是如何转换成AVR单片机的?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

31

主题

59

帖子

0

粉丝