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

📄 sch.s

📁 Jan 04, 2007 1. Add SPI support, see spi.h and spi.c 2. Add driver.h 3. Modified keyboard modu
💻 S
字号:
/** * Copyright (c) 2006-2008 iWESUN (ShenZhen) Inf. * All rights reserved.  *  * Redistribution and use in source and binary forms, with or without modification,  * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, *    this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, *    this list of conditions and the following disclaimer in the documentation *    and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY  * OF SUCH DAMAGE. * * This file is part of the AvrcX MTOS *  * Author: Winter Hu  <winter.hu@gmail.com> * Create: Nov 24, 2006 *//*Changlog:Jan 4, 2007,  Re-write sleep in assembler  Modify method "prologue" to avoid using r25:r24*/#include "common.h"#include "scheduler.h"		_MODULE(scheduler)	_EXTERN(kernel)	/** * Create the task PID of specified TCB * * @param TCB*,  r25:r24 * @return PID*, r25:r24 * @see INTERFACE PID* createTask(PCB*) * * @regs: r0, r22, r23, r24, r25, X, Z */	_PUBLIC(create_task)create_task:	movw	Zl, _p1l	rcall	lpm_inc	mov	Xl, r0	rcall	lpm_inc	mov	Xh, r0		; Get task stack point	rcall	lpm_inc	st	X, r0	rcall	lpm_inc	st	-X, r0		; Push task entry point	ldi	_p1l, 0	ldi	_p1h, 33	; Push 32 regs + SREG1:	st	-X, _p1l	dec	_p1h	brne	1b	sbiw	Xl, 1		; SP	rcall	lpm_inc	mov	_r1l, r0	rcall	lpm_inc	mov	_r1h, r0	; Get PCB --> r25:r24	rcall	lpm_inc	mov	_r2l, r0	rcall	lpm_inc	mov	_r2h, r0	; Get PID --> r23:r22	rcall	lpm_inc		; Get predefine priority --> r0	mov	r1, r0		; priority --> r1	rcall	lpm_inc		; Get predefine tmslices --> r0		movw	Zl, _r1l	; PCB --> Z	std	Z+PCB_PRIORITY, r1	  ; Set PCB priority	std	Z+PCB_TMSLICES, r0	  ; Set PCB tmslices		std	Z+PCB_CONTEXT+0, Xl	std	Z+PCB_CONTEXT+1, Xh	  ; Set PCB Context	movw	Zl, _r2l	; PID --> Z	std	Z+NODE_PRIORITY, r0   ; Set PID node priority		std	Z+NODE_PDATA_LO, _r1l	std	Z+NODE_PDATA_HI, _r1h ; Set PID node pData point to PCB	ldi	_tmp1, NULL	std	Z+NODE_PNEXT_LO, _tmp1	std	Z+NODE_PNEXT_HI, _tmp1	movw	_r1l, Zl	; PID --> _r1l		clr	r1		; __zero_reg__ of GCC		ret	lpm_inc:	lpm	adiw	Zl, 1	ret/** * Pushes entire register context onto the current stack * * void prologue(void) * ASSUMES: SysLevel >= 0, running on kernel stack * REGS: r0, r24, r25, X, Y, Z */	_PUBLIC(prologue)prologue:	push	r1	push	Zh	push	Zl	push	Yh	push	Yl	in	r1, _SFR_IO_ADDR(SREG)		ldi	Zl, lo8(kernel)	ldi	Zh, hi8(kernel)	; Get kernel --> Z	ldd	Yl, Z+KERN_SYSLEVEL	subi	Yl, lo8(-1)	; Carry set if results 0	std	Z+KERN_SYSLEVEL, Yl 	brcs	saveContext			ldd	Yl, Z+KERN_RUNNING+0	ldd	Yh, Z+KERN_RUNNING+1	or	Yh, Yl		; Test kernel.Running	brne	saveContext	;; IDLE	in	Yl, _SFR_IO_ADDR(SPL)	in	Yh, _SFR_IO_ADDR(SPH)	ldd	Zh, Y+6	ldd	Zl, Y+7		; Get return address	adiw	Yl, 9	out	_SFR_IO_ADDR(SPL), Yl	out	_SFR_IO_ADDR(SPH), Yh	clr	__zero_reg__	ijmpsaveContext:	push	Xh	push	Xl	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	in	Yl, _SFR_IO_ADDR(SPL)	in	Yh, _SFR_IO_ADDR(SPH)	ldd	_p4h, Y+32	ldd	_p4l, Y+33	; Get Prologue caller return address	std	Y+32, r1	; save SREG	std	Y+33, r0	; save r0	;; End save task context	brcs	alreadyInKernel	; from above	ldd	Xl, Z+KERN_RUNNING+0	ldd	Xh, Z+KERN_RUNNING+1	movw	Zl, Xl		       ; Get kernel.PID --> Z	ldd	Xl, Z+NODE_PDATA_LO	ldd	Xh, Z+NODE_PDATA_HI	movw	Zl, Xl                 ; Get kernel.PID.pcb --> Z	std	Z+PCB_CONTEXT+0, Yl	std	Z+PCB_CONTEXT+1, Yh    ; Save task SP	ldi	Zl, lo8(kernel)	ldi	Zh, hi8(kernel)	ldd	Yl, Z+KERN_CONTEXT+0	ldd	Yh, Z+KERN_CONTEXT+1   ; Get kernel.Context	out	_SFR_IO_ADDR(SPL), Yl	out	_SFR_IO_ADDR(SPH), Yh  ; Change to kernel stackalreadyInKernel:	clr	__zero_reg__	; GCC	movw	Zl, _p4l	; Prologue caller return address --> Z	ijmp	/** * Restore previous context (kernel or user) * * void epilogue(void) * ASSUMES: SysLevel >= 0, running on kernel stack * REGS: */	_PUBLIC(epilogue)epilogue:	pop	r24	pop	r24		; This method never return caller	_PUBLIC(_epilogue)_epilogue:	cli		ldi	Zl, lo8(kernel)	ldi	Zh, hi8(kernel)		ldd	Xl, Z+KERN_SYSLEVEL	dec	Xl	std	Z+KERN_SYSLEVEL, Xl	brge	stillInKernel	ldd	Xl, Z+KERN_RUNNING+0	ldd	Xh, Z+KERN_RUNNING+1	adiw	Xl, 0	breq	idleTask	movw	Zl, Xl		         ; Get kernel.PID --> Z	ldd	Xl, Z+NODE_PDATA_LO	ldd	Xh, Z+NODE_PDATA_HI	movw	Zl, Xl                   ; Get kernel.PID.pcb --> Z	ldd	Yl, Z+PCB_CONTEXT+0	ldd	Yh, Z+PCB_CONTEXT+1	out	_SFR_IO_ADDR(SPL), Yl	out	_SFR_IO_ADDR(SPH), Yh    ; Set stack to current taskstillInKernel:	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	Xl	pop	Xh	pop	Yl	pop	Yh	pop	Zl	pop	Zh	pop	r1	pop	r0	out	_SFR_IO_ADDR(SREG), r0	pop	r0	retiidleTask:	sei	nop			; sleep	rjmp	idleTask	/** * Causes the currently executing task to temporarily pause in TimQueue * until delay expire.  * * @param unsigned int, Ticks for sleeping */	_PUBLIC(sleep)sleep:	cli	rcall	prologue	movw	_p2l, _p1l	lds	_p1l, kernel+KERN_RUNNING+0	lds	_p1h, kernel+KERN_RUNNING+1	rcall	delay_task	rcall	swapping	rjmp	_epilogue			_ENDMOD

⌨️ 快捷键说明

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