⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_cpu_a.tri

📁 UCOS II源码 内含SOURCE 解压后使用
💻 TRI
字号:
;********************************************************************************************************
; 
; File         : os_cpu_a.tri     for UCOS-II  RTOS by Jean Labrosse.
; By           : Andre' Gompel    Andre.Gompel@Infineon.com agompel@bigfoot.com 
;
;		(c) Copyright 2000, Infineon Technology
;		BETA (UNRELEASED CODE): DO NOT COPY WITOUT AUTHORIZATION
;															Tricore TC10
; 
;  THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY EXPRESS OR           
;  IMPLIED WARRANTY. BOTH INFINEON TECHNOLOGIES CORPORATION AND       
;  MICRIUM INC. DISCLAIMS ALL REPRESENTATIONS AND WARRANTIES WITH     
;  REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF       
;  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT  
;  SHALL INFINEON TECHNOLOGIES CORPORATION OR MICRIUM INC. BE LIABLE  
;  FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES  
;  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
;  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACT OR         
;  OMISSION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR          
;  PERFORMANCE OF THIS SOFTWARE.                                      
;
;********************************************************************************************************


	#include "os_cfg.h"			
	#include <RegDef.h>
	#include "TC10GP.h"

	
;;	.nodebug
;;	.file	"os_cpu_a.tri"
	.text
	.align 4


;
; Set up of the PSW See Architecture manual, section "core registers"
;
;psw_prs	 PRS : Protection Register Set Selection
;psw_io		 IO : I/O Access Permission Mode: 2=Supervisor mode.
;psw_is		 IS : interrupt stak. 1=USe interrupt stack
;psw_gw  	 GW : Global Register Write 1=permitted
;psw_cde	 CDE : Call Depth Enable
;psw_cdc	 CDC note 7F equ disabled

PSW_V0	.equ	psw_prs | psw_io | psw_is | psw_gw | psw_cde | psw_cdc

;
; Useful References: 
;
; 1) TriCore Special functions Registers and Bits, Chapter 2. 
; 2) TriCore architecture manual, chapter 7: Protection system
;
; 3) Also User's Manual, Section: General Purpose Timer Unit
;		      Section: Interrupt System
;
; 4) TriCore AppNote: AP3224: Using the Timer Interrupt System
;

;
; IMPORTANT: To modify tick period, adjust OS_TICKS_PER_SEC in file "os_cfg.h"
;
;
      .globl	OSInitGptu
OSInitGptu:				; void OSInitGptu(void)
					
					
	LD_IOREG16 GPTU0_GTCLC, 0xff00	; rmc=0xff

	LD_IOREG16 GPTU0_T012RUN, 0x440	; Stop all timers, 2 B safe.

	LD_IOREG16 GPTU0_T01IRS, 0x100C	;Input and reload, use T01 and T0B concatenated.

	LD_IOREG16 GPTU0_T01OTS, 0x0100 ;SSR00=01 : T0B overflow-> SRC0

	LD_IOREG32 GPTU0_T0RCBA, ~(1000000/OS_TICKS_PER_SEC) ; reload value cntr BA of timer 0

	LD_IOREG32 GPTU0_T0CBA,  ~(1000000/OS_TICKS_PER_SEC) ; Start Value
	
	LD_IOREG32 GPTU0_GTSRSEL, 0xC0000000 ;OverFlow Timer 0 B to Service Request 0

	LD_IOREG16 GPTU0_GTSRC0, 0x1002      ;SRE + TOS=CPU + Priority =2

	LD_IOREG16 GPTU0_T012RUN, 3	; Run Timer 0, A and B counters.

	ret16

	.globl	OSStopGptu
OSStopGptu:
	LD_IOREG16 GPTU0_T012RUN, 0x440	
	ret16

	.globl	OSStartGptu
OSStartGptu:
	LD_IOREG16 GPTU0_T012RUN, 3
	ret16


       .globl	OSTickISR
OSTickISR:				; void OSTickISR (void)
	call	OSTimeTick		; Call uC/OS-II's tick updating function
	ret				; OSIntExit may set the ReqTskSwitch

;********************************************************************************************************
; START HIGHEST PRIORITY TASK READY-TO-RUN
; Description : This function is called by OSStart() to start the highest priority task that was created
; by your application before calling OSStart().
;                 OSStartHighRdy() MUST:
;                      a) Call OSTaskSwHook() then,
;                      b) Set OSRunning to TRUE,
;                      c) Switch to the highest priority task.
;********************************************************************************************************

;; Need to define OS_TASK_CREATE_EXT_EN   in os_cfg.h to have proper access

	.globl   OSStartHighRdy
OSStartHighRdy:				; void OSStartHighRdy (void)
	mov16	d0,1			; GHS would have used D0 : not portable (lwr ctxt)
	LD_AREG	a12, OSRunning		; Does not hurt if already running
	st16.b	[a12],d0		; Indicate that we are multitasking
  	j	OSLaunchHigh

;;	OsIntCtxSw is called by OSIntExit to perform a context switch from am ISR
;; 	at this time all the nested interrupts have been completed.
;;	We are in a critical section


;
;	For TriCore, because of the availabily of the interrupt stack 
;	OSIntCtxSw and OSCtxSw are the same code.
;	I used two labels, to keep full compatibility with the UCOS-II code
;	and also to emphasize this fact.
;	Andre Gompel.
;


; 	void OSIntCtxSw (void)   Is now inlined, see os_cpu.h
;	Not yet: due to bug. 

	.globl	OSIntCtxSw
OSIntCtxSw:				; void OSIntCtxSw (void)
	mov16	d15, 1
	st.w	%zdaoff(flg_sw),d15
	ret16
	

	

	.globl	OSCtxSw
OSCtxSw:				; void OSCtxSw (void)
	svlcx				
	LD_AREG	a12,OSTCBCur		; Get ptr to Curent TCB
	ld.w	d0, [a12]		; OSTCBCur is a ptr
	mov.a	a12, d0		

      	mfcr    d0,(PCXI & 0xffff)
	st.w	[a12], d0		; Save PCXI to TCB->pcxi

	mfcr	d0, (FCX & 0xffff)
	st.w	[a12]4, d0		; Save FCX  to TCB->lcx

	mfcr	d0, (LCX & 0xffff)
	st.w	[a12]8, d0		; Save LCX  to TCB->lcx

;;  Enable next line as needed (avoid increasing context switch latency)
;;	call 	OSTaskSwHook 		; Invoke user defined context switch hook

;;  Now restore task context, from task to be activated TCB
;;  We need the contexts (Upper & lower), and also the context ptrs
;;
	.globl	OSLaunchHigh
OSLaunchHigh:
	LD_AREG	a13, OSTCBHighRdy 	; Get a ptr to highest pty task
	ld.w	d0, [a13]
	mov.a	a13, d0

	LD_AREG	a12, OSTCBCur
	st16.w	[a12], d0		; OSTCBCur  = OSTCBHighRdy

	LD_AREG	a14, OSPrioHighRdy
	ld16.bu d0,[a14]

	LD_AREG	a14,  OSPrioCur
	st16.b	[a14], d0		; OSPrioCur = OSPrioHighRdy	

	ld.w	d0, [a13]		; Get PCXI from task TCB
      	mtcr    (PCXI & 0xffff),d0
	isync

	ld.w	d0, [a13]4
	mtcr	(FCX & 0xffff), d0
	isync

	ld.w	d0, [a13]8
	mtcr	(LCX & 0xffff), d0
	isync

	rslcx				
      	mfcr    d0,(PCXI & 0xffff)
	insert	d0,d0,1,22,1		; Say UL=UC
	mtcr	%lo(PCXI),d0
	isync

	mov.u	d0,PSW_V0		; Use PSW.v0
	mtcr	(PSW & 0xffff),d0
	isync
	rfe				; go 4 it

;;.globl	os_vectors	; just for the debugger
;;os_vectors:					2 B DELETED 
	.globl	OSInitTricoreInt	
				; We will enable interrupts at a later time
				; Logically we should also set btv here.

OSInitTricoreInt:		; void OSInitTricoreInt(void)
		; Initialize BIV

	movh	d15,%hi(int_vectors)
	addi	d15,d15,%lo(int_vectors)
	mtcr	(BIV & 0xffff),d15	; Init BIV=Base of Interrupts Vectors
	isync

					; Set ICR initial value.

    	mov.u	d2, 1			; disable interrupts and set CCPN to 1
    	mtcr	(ICR & 0xffff), d2	
    	isync

; Set the SYSCON register

    	mov.u	d2, 0x1
    	mtcr	(SYSCON & 0xffff), d2
    	isync

	ret16

	.globl	OSInitFlags	
OSInitFlags:
					; void OSInitFlags(void)
	xor   	d0, d0,d0
	st.w	%zdaoff(flg_sw),d0
	ret16

;*******************************************************************************************
;
;	void *OSTaskStkInit 	(void (*task)(void *pd), //) 
;				void *pdata,
;				OS_STK *ptos,
;				uint16_t opt )
;
;	The name OSTaskStkInit was used to keep UCOS terminology
;	However for Infineon TriCore OSContextInit would have been more appropriate.
;	THe TriCore architecture actually make context swithing very simple..and very fast
; 	so the code is really simple. 
;	This is due to the implicit and context save/restore.
;	The upper context is saved/restored implicitly
;	The lower context has to be saved restored explicitly.
; 	A good understanding of this mecahnism, as well as the TriCore ve 1.4 EABI specification
; 	are required to understand this code: 
;	See TriCore architechture manual and EABI Ve 1.4 Specification.
;	
;	So far we do not use params: ptos and opt 
;
;	apology: using global variables for fcx, lcx, pcxi is not very satisfactory
; 	The main reason is to keep the code in os_core.c unmodified.(Mostly)
;
;*******************************************************************************************


;
; Each task has its private CSA free list.
; We need to initialize the two first CSA for lauching the task. 
; This is is what the following code is doing.
; The name OSTaskStkInit was keept for UCOS-II compatibility, but it is misleading
; It should rather be something like OSTaskCtxtListInit.
;
; Note: this works with the CSA format of GHS where the PCXI points to the next (higher) ctx

; void *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos,uint16_t opt)

	.globl   OSTaskStkInit
OSTaskStkInit:				; void *OSTaskStkInit(see_above)
	movh.a	a12, %hi(g_tsk_ctx0)   	; Translate g_tsk_ctx0 into an effective address
	ld.w	d8,[a12]%lo(g_tsk_ctx0) ; d8 has g_tsk_ctx0 in "fcx format"
	mov.aa	a13, a12		; keep a13= g_tsk_ctx0 in fcx format
	mov.u	d9,0xffff		
	and	d10,d9,d8		; 
        sh	d10,d10,6		; d10[21:6]=offset
        movh	d9,0x000f		; mask seg adr, upper 16 bits
	and	d11,d9,d8		; 
	sh	d11,d11,12		; d11[31:28]=seg
	or	d10,d11, d10		; d10 has EA of 1st ctxt			
	mov.a	a12,d10			; a12: ptr to task 1st ctxt (UC)
	ld.w	d0,[a12]		;
	
	LD_DREG	d2, 0x000fffff		; keep pcx0, pcxs, ul
	and	d0,d0,d2		; 
	movh	d2, 0x0180		; setup v0_tsk_pcxi for pie, pcpn
	or	d0, d2, d0			    	
	st.w	[a12], d0		; LC.PCXI
	mov.d	d10,a4			; get 1st param (tsk addr)	
	st.w	[a12]4, d10		; Init LC.A11/RA
 
	mov.u	d9,64			; Ctx_ptr += sizeof(context)
	addsc.a	a12,a12,d9,0			

	xor  	d0,d0,d0		; 
	st.w	[a12],d0		; UC.PCXI= d0
	mov.u	d0, PSW_V0		; Task default PSW	
	st.w	[a12]4, d0		; UC.PSW=
	mov.d	d0,a6			; get 3rd parameter (tsk sp)		
	st.w	[a12]8, d0		; UC.A10/SP=
	ret16				; Of OSTaskStkInit



	.globl infinite_loop	
infinite_loop:				; We use this as a very crude trap handler.
	j infinite_loop		        ; Later we will issue an error explicit message.



.section ".traps","a"

  	.globl trap_vectors
trap_vectors:
	trapdbg 0
	trapdbg 1
	trapdbg 2
	trapdbg 3
	trapdbg 4
	trapdbg 5
	trapvec 6, OSCtxSw
	trapdbg 7
	trapend

.section ".interrupts", "a"
;
; Note 1: it is safer to create an interrupt entry for each 
; of the 256 possible interrupts, just in cas of dummy interrupts (noise etc...)
; Note 2: So far a static allocation of interrupt vectors has been chosen. 
;    Beside being a little simpler to implement, it give full visibility to the programmer.
;    If need arise, a service to hook an interrupt vector could be added.
;

	.globl OS_ASC0_TxISR		; Interrupt when char has been sent
	.globl OS_ASC0_TxISR		; Interrupt when a char has been received.

; interrupts vectors: ISRname, SRPN  (Service request priority number)

int_vectors:
	intvec	unused_interrupt_isr,0
	intvec	unused_interrupt_isr,1
	intvec	OSTimeTick,2
	intvec	OS_ASC0_TxISR, 3
	intvec	OS_ASC0_RxISR,4
	intvec	unused_interrupt_isr,5
	intvec	unused_interrupt_isr,6
	intvec	unused_interrupt_isr,7

	.section .spad, "ab"
 	.align 4
 	.globl	flg_sw
flg_sw:
	.word 0				; flag sw (request)




 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -