[an error occurred while processing this directive]
вот он
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено ы 26 января 2006 г. 18:21
В ответ на: так...короче, качайте отсюда порт UCOS-II для ARM для компилятора Rowley (внизу). там в zip есть s файл вот его и изучайте отправлено ы 26 января 2006 г. 18:20


/*
*********************************************************************************************************
* uC/OS-II
* The Real-Time Kernel
*
* (c) Copyright 1992-2004, Micrium, Weston, FL
* All Rights Reserved
*
* Generic ARM Port
*
* File : OS_CPU_A.ASM
* Version : V1.60
* By : Jean J. Labrosse
*
* Changes : Michael Fischer
* This port based on AN-1014.
* I changed only a small part for the CrossWorks port.
* 1) Changed some IAR specific code from AN-1014
* EXTERN -> .extern
* PUBLIC -> .global
* defines like: NO_INT EQU 0xC0 -> .equ NO_INT, 0xC0
* RSEG CODE:CODE:NOROOT(2) -> .section .text, "ax"
* CODE32 -> .code 32
* ??OSxxxxx -> =OSxxxxx
* 2) Renamed OS_CPU_IRQ_ISR to irq_handler, because this name is used by the STR71x_Startup.s
* 3) Renamed OS_CPU_FIQ_ISR to fiq_handler, because this name is used by the STR71x_Startup.s
* 4) Removed the data section
*
* I found out later, that there exist a GNU port from Jean-Denis Hatier, take a look at AN-1764.
*
* For : ARM7 or ARM9
* Mode : ARM or Thumb
* Toolchain : CrossWorks for ARM 1.5 Build 2 and higher
*********************************************************************************************************
*/

.extern OSRunning /* External references */
.extern OSPrioCur
.extern OSPrioHighRdy
.extern OSTCBCur
.extern OSTCBHighRdy
.extern OSIntNesting
.extern OSIntExit
.extern OSTaskSwHook
.extern OS_CPU_IRQ_ISR_Handler
.extern OS_CPU_FIQ_ISR_Handler


.global OS_CPU_SR_Save /* Functions declared in this file */
.global OS_CPU_SR_Restore
.global OSStartHighRdy
.global OSCtxSw
.global OSIntCtxSw
.global irq_handler /* Is defined in startup.s from the CrossWorks project */
.global fiq_handler /* Is defined in startup.s from the CrossWorks project */

.equ NO_INT, 0xC0 /* Mask used to disable interrupts (Both FIR and IRQ) */
.equ SVC32_MODE, 0x13
.equ FIQ32_MODE, 0x11
.equ IRQ32_MODE, 0x12


/*********************************************************************************************************
* CRITICAL SECTION METHOD 3 FUNCTIONS
*
* Description: Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you
* would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then
* disable interrupts. 'cpu_sr' is allocated in all of uC/OS-II's functions that need to
* disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr'
* into the CPU's status register.
*
* Prototypes : OS_CPU_SR OS_CPU_SR_Save(void);
* void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr);
*
*
* Note(s) : 1) These functions are used in general like this:
*
* void Task (void *p_arg)
* {
* #if OS_CRITICAL_METHOD == 3 ; Allocate storage for CPU status register
* OS_CPU_SR cpu_sr;
* #endif
*
* :
* :
* OS_ENTER_CRITICAL(); ; cpu_sr = OS_CPU_SaveSR();
* :
* :
* OS_EXIT_CRITICAL(); ; OS_CPU_RestoreSR(cpu_sr);
* :
* :
* }
*
* 2) OS_CPU_SaveSR() is implemented as recommended by Atmel's application note:
*
* "Disabling Interrupts at Processor Level"
********************************************************************************************************/

.section .text, "ax"
.code 32

OS_CPU_SR_Save:
MRS R0,CPSR /* Set IRQ and FIQ bits in CPSR to disable all interrupts */
ORR R1,R0,#NO_INT
MSR CPSR_c,R1
MRS R1,CPSR /* Confirm that CPSR contains the proper interrupt disable flags */
AND R1,R1,#NO_INT
CMP R1,#NO_INT
BNE OS_CPU_SR_Save /* Not properly disabled (try again) */
BX LR /* Disabled, return the original CPSR contents in R0 */


OS_CPU_SR_Restore:
MSR CPSR_c,R0
BX LR


/*********************************************************************************************************
* START MULTITASKING
* void OSStartHighRdy(void)
*
* Note(s) : 1) OSStartHighRdy() MUST:
* a) Call OSTaskSwHook() then,
* b) Set OSRunning to TRUE,
* c) Switch to the highest priority task.
*********************************************************************************************************/

.section .text, "ax"
.code 32

OSStartHighRdy:

MSR CPSR_cxsf, #0xD3 /* Switch to SVC mode with IRQ and FIQ disabled */

LDR R0, =OSTaskSwHook /* OSTaskSwHook(); */
MOV LR, PC
BX R0

LDR R4, =OSRunning /* OSRunning = TRUE */
MOV R5, #1
STRB R5, [R4]

/* SWITCH TO HIGHEST PRIORITY TASK */
LDR R4, =OSTCBHighRdy /* Get highest priority task TCB address */
LDR R4, [R4] /* get stack pointer */
LDR SP, [R4] /* switch to the new stack */

LDR R4, [SP], #4 /* pop new task's CPSR */
MSR SPSR_cxsf,R4
LDMFD SP!, {R0-R12,LR,PC}^ /* pop new task's context */


/*********************************************************************************************************
* PERFORM A CONTEXT SWITCH (From task level) - OSCtxSw()
*
* Note(s) : 1) OSCtxSw() is called in SYS mode with BOTH FIQ and IRQ interrupts DISABLED
*
* 2) The pseudo-code for OSCtxSw() is:
* a) Save the current task's context onto the current task's stack
* b) OSTCBCur->OSTCBStkPtr = SP;
* c) OSTaskSwHook();
* d) OSPrioCur = OSPrioHighRdy;
* e) OSTCBCur = OSTCBHighRdy;
* f) SP = OSTCBHighRdy->OSTCBStkPtr;
* g) Restore the new task's context from the new task's stack
* h) Return to new task's code
*
* 3) Upon entry:
* OSTCBCur points to the OS_TCB of the task to suspend
* OSTCBHighRdy points to the OS_TCB of the task to resume
*********************************************************************************************************/

.section .text, "ax"
.code 32

OSCtxSw:
/* SAVE CURRENT TASK'S CONTEXT */
STMFD SP!, {LR} /* Push return address */
STMFD SP!, {LR}
STMFD SP!, {R0-R12} /* Push registers */
MRS R4, CPSR /* Push current CPSR */
TST LR, #1 /* See if called from Thumb mode */
ORRNE R4, R4, #0x20 /* If yes, Set the T-bit */
STMFD SP!, {R4}

LDR R4, =OSTCBCur /* OSTCBCur->OSTCBStkPtr = SP; */
LDR R5, [R4]
STR SP, [R5]

LDR R0, =OSTaskSwHook /* OSTaskSwHook(); */
MOV LR, PC
BX R0

LDR R4, =OSPrioCur /* OSPrioCur = OSPrioHighRdy */
LDR R5, =OSPrioHighRdy
LDRB R6, [R5]
STRB R6, [R4]

LDR R4, =OSTCBCur /* OSTCBCur = OSTCBHighRdy; */
LDR R6, =OSTCBHighRdy
LDR R6, [R6]
STR R6, [R4]

LDR SP, [R6] /* SP = OSTCBHighRdy->OSTCBStkPtr; */

/* RESTORE NEW TASK'S CONTEXT */
LDMFD SP!, {R4} /* Pop new task's CPSR */
MSR SPSR_cxsf, R4

LDMFD SP!, {R0-R12,LR,PC}^ /* Pop new task's context */


/*********************************************************************************************************
* PERFORM A CONTEXT SWITCH (From interrupt level) - OSIntCtxSw()
*
* Note(s) : 1) OSIntCtxSw() is called in SYS mode with BOTH FIQ and IRQ interrupts DISABLED
*
* 2) The pseudo-code for OSCtxSw() is:
* a) OSTaskSwHook();
* b) OSPrioCur = OSPrioHighRdy;
* c) OSTCBCur = OSTCBHighRdy;
* d) SP = OSTCBHighRdy->OSTCBStkPtr;
* e) Restore the new task's context from the new task's stack
* f) Return to new task's code
*
* 3) Upon entry:
* OSTCBCur points to the OS_TCB of the task to suspend
* OSTCBHighRdy points to the OS_TCB of the task to resume
*********************************************************************************************************/

.section .text, "ax"
.code 32

OSIntCtxSw:
LDR R0, =OSTaskSwHook /* OSTaskSwHook(); */
MOV LR, PC
BX R0

LDR R4,=OSPrioCur /* OSPrioCur = OSPrioHighRdy */
LDR R5,=OSPrioHighRdy
LDRB R6,[R5]
STRB R6,[R4]

LDR R4,=OSTCBCur /* OSTCBCur = OSTCBHighRdy; */
LDR R6,=OSTCBHighRdy
LDR R6,[R6]
STR R6,[R4]

LDR SP,[R6] /* SP = OSTCBHighRdy->OSTCBStkPtr; */

/* RESTORE NEW TASK'S CONTEXT */
LDMFD SP!, {R4} /* Pop new task's CPSR */
MSR SPSR_cxsf, R4

LDMFD SP!, {R0-R12,LR,PC}^ /* Pop new task's context */


/*********************************************************************************************************
* IRQ Interrupt Service Routine
*********************************************************************************************************/

.section .text, "ax"
.code 32

irq_handler: /* Changed name from OS_CPU_IRQ_ISR */

STMFD SP!, {R1-R3} /* PUSH WORKING REGISTERS ONTO IRQ STACK */

MOV R1, SP /* Save IRQ stack pointer */

ADD SP, SP,#12 /* Adjust IRQ stack pointer */

SUB R2, LR,#4 /* Adjust PC for return address to task */

MRS R3, SPSR /* Copy SPSR (i.e. interrupted task's CPSR) to R3 */

MSR CPSR_c, #(NO_INT | SVC32_MODE) /* Change to SVC mode */

/* SAVE TASK'S CONTEXT ONTO TASK'S STACK */
STMFD SP!, {R2} /* Push task's Return PC */
STMFD SP!, {LR} /* Push task's LR */
STMFD SP!, {R4-R12} /* Push task's R12-R4 */

LDMFD R1!, {R4-R6} /* Move task's R1-R3 from IRQ stack to SVC stack */
STMFD SP!, {R4-R6}
STMFD SP!, {R0} /* Push task's R0 onto task's stack */
STMFD SP!, {R3} /* Push task's CPSR (i.e. IRQ's SPSR) */

/* HANDLE NESTING COUNTER */
LDR R0, =OSIntNesting /* OSIntNesting++; */
LDRB R1, [R0]
ADD R1, R1,#1
STRB R1, [R0]

CMP R1, #1 /* if (OSIntNesting == 1) { */
BNE OS_CPU_IRQ_ISR_1

LDR R4, =OSTCBCur /* OSTCBCur->OSTCBStkPtr = SP */
LDR R5, [R4]
STR SP, [R5] /* } */

OS_CPU_IRQ_ISR_1:
MSR CPSR_c, #(NO_INT | IRQ32_MODE) /* Change to IRQ mode (to use the IRQ stack to handle interrupt) */

LDR R0, =OS_CPU_IRQ_ISR_Handler /* OS_CPU_IRQ_ISR_Handler(); */
MOV LR, PC
BX R0

MSR CPSR_c, #(NO_INT | SVC32_MODE) /* Change to SVC mode */

LDR R0, =OSIntExit /* OSIntExit(); */
MOV LR, PC
BX R0

/* RESTORE NEW TASK'S CONTEXT */
LDMFD SP!, {R4} /* Pop new task's CPSR */
MSR SPSR_cxsf, R4

LDMFD SP!, {R0-R12,LR,PC}^ /* Pop new task's context */


/*********************************************************************************************************
* FIQ Interrupt Service Routine
*********************************************************************************************************/

.section .text, "ax"
.code 32

fiq_handler: /* Changed name from OS_CPU_FIQ_ISR */

STMFD SP!, {R1-R3} /* PUSH WORKING REGISTERS ONTO FIQ STACK */

MOV R1, SP /* Save FIQ stack pointer */

ADD SP, SP,#12 /* Adjust FIQ stack pointer */

SUB R2, LR,#4 /* Adjust PC for return address to task */

MRS R3, SPSR /* Copy SPSR (i.e. interrupted task's CPSR) to R3 */

MSR CPSR_c, #(NO_INT | SVC32_MODE) /* Change to SVC mode */

/* SAVE TASK'S CONTEXT ONTO TASK'S STACK */
STMFD SP!, {R2} /* Push task's Return PC */
STMFD SP!, {LR} /* Push task's LR */
STMFD SP!, {R4-R12} /* Push task's R12-R4 */

LDMFD R1!, {R4-R6} /* Move task's R1-R3 from FIQ stack to SVC stack */
STMFD SP!, {R4-R6}
STMFD SP!, {R0} /* Push task's R0 onto task's stack */
STMFD SP!, {R3} /* Push task's CPSR (i.e. FIQ's SPSR) */

/* HANDLE NESTING COUNTER */
LDR R0, =OSIntNesting /* OSIntNesting++; */
LDRB R1, [R0]
ADD R1, R1,#1
STRB R1, [R0]

CMP R1, #1 /* if (OSIntNesting == 1) { */
BNE OS_CPU_FIQ_ISR_1

LDR R4, =OSTCBCur /* OSTCBCur->OSTCBStkPtr = SP */
LDR R5, [R4]
STR SP, [R5] /* } */

OS_CPU_FIQ_ISR_1:
MSR CPSR_c, #(NO_INT | FIQ32_MODE) /* Change to FIQ mode (to use the FIQ stack to handle interrupt) */

LDR R0, =OS_CPU_FIQ_ISR_Handler /* OS_CPU_FIQ_ISR_Handler(); */
MOV LR, PC
BX R0

MSR CPSR_c, #(NO_INT | SVC32_MODE) /* Change to SVC mode */

LDR R0, =OSIntExit /* OSIntExit(); */
MOV LR, PC
BX R0

/* RESTORE NEW TASK'S CONTEXT */
LDMFD SP!, {R4} /* Pop new task's CPSR */
MSR SPSR_cxsf, R4

LDMFD SP!, {R0-R12,LR,PC}^ /* Pop new task's context */

.ltorg

/*** EOF ***/


Составить ответ  |||  Конференция  |||  Архив

Ответы


Отправка ответа

Имя (обязательно): 
Пароль: 
E-mail: 
NoIX ключ Запомнить

Тема (обязательно):
Сообщение:

Ссылка на URL: 
Название ссылки: 

URL изображения: 


Rambler's Top100 Рейтинг@Mail.ru
Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание

E-mail: info@telesys.ru