据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
|