mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-20 05:21:59 -04:00
152 lines
3.8 KiB
NASM
152 lines
3.8 KiB
NASM
#include <msp430x14x.h>
|
|
|
|
/*
|
|
* Milos Prokic
|
|
*/
|
|
|
|
/**********************************************************
|
|
All Interrupts should follow the naming convention : ISR"name" and declared
|
|
as a normal function in C.
|
|
|
|
One must not forget to allocate interrupts below (see the line "MSPINT OsTick"
|
|
below for an example).
|
|
|
|
By default the ISR will not cause the context switch, but if called in
|
|
conjunction with portENTER_SWITCHING_ISR/portEXIT_SWITCHING_ISR(wakeup), where
|
|
wakeup = TRUE upon exit the ISR will force the context switch via the
|
|
ucReschedule global variable.
|
|
**********************************************************/
|
|
MSPINT macro name
|
|
_##name::
|
|
call #_portSAVE_CONTEXT
|
|
call #_ISR##name
|
|
br #_portSWITCH_EXIT
|
|
endm
|
|
|
|
|
|
/**********************************************************
|
|
API code
|
|
**********************************************************/
|
|
|
|
.CODE
|
|
_vPortYield::
|
|
/* Mimic an INT call by pushing SR. */
|
|
push SR
|
|
/* no INTs !! */
|
|
dint
|
|
/* Save the context of the current task. */
|
|
call #_portSAVE_CONTEXT
|
|
/* Switch to the highest priority task that is ready to run. */
|
|
call #_vTaskSwitchContext
|
|
/* Restore the context of the new task. */
|
|
br #_portSWITCH_EXIT
|
|
|
|
_xPortStartScheduler::
|
|
/* Setup the hardware to generate the tick. Interrupts are disabled when
|
|
this function is called. */
|
|
call #_prvSetupTimerInterrupt
|
|
|
|
/* Restore the context of the first task that is going to run. */
|
|
jmp _portRESTORE_CONTEXT
|
|
|
|
_portSAVE_CONTEXT::
|
|
/* Function to save the context. When this function is called the
|
|
return address will appear on the stack. This does not need to be
|
|
saved so is overwritten by R4 - hence R4 is not saved initially.
|
|
|
|
Save the general purpose registers. */
|
|
push R5
|
|
push R6
|
|
push R7
|
|
push R8
|
|
push R9
|
|
push R10
|
|
push R11
|
|
push R12
|
|
push R13
|
|
push R14
|
|
push R15
|
|
|
|
/* Now R10 has been saved we can use it to hold the return address,
|
|
which is about to be overwritten. */
|
|
mov 22(R1),R10
|
|
|
|
/* Store R4 where the return address was on the stack. */
|
|
mov R4,22(R1)
|
|
|
|
/* Save the critical nesting depth. */
|
|
mov.w &_usCriticalNesting, R14
|
|
push R14
|
|
|
|
/* Finally save the new top of stack. */
|
|
mov.w &_pxCurrentTCB, R12
|
|
mov.w R1, @R12
|
|
|
|
/* No rescheduling by default. */
|
|
mov.b #0,&_ucReschedule
|
|
|
|
/* Return using the saved return address. */
|
|
br R10
|
|
|
|
|
|
_portSWITCH_EXIT::
|
|
/* Check ucReschedule to see if a context switch is required. */
|
|
tst.b &_ucReschedule
|
|
jz _portRESTORE_CONTEXT
|
|
call #_vTaskSwitchContext
|
|
_portRESTORE_CONTEXT::
|
|
/* Restore the context in the opposite order to the save. */
|
|
mov.w &_pxCurrentTCB, R12
|
|
mov.w @R12, R1
|
|
pop R15
|
|
mov.w R15, &_usCriticalNesting
|
|
pop R15
|
|
pop R14
|
|
pop R13
|
|
pop R12
|
|
pop R11
|
|
pop R10
|
|
pop R9
|
|
pop R8
|
|
pop R7
|
|
pop R6
|
|
pop R5
|
|
pop R4
|
|
|
|
/* Ensure any low power mode bits are cleared within the status
|
|
register about to be restored. */
|
|
bic #(SCG1+SCG0+OSCOFF+CPUOFF),0(SP)
|
|
reti
|
|
|
|
|
|
/**********************************************************
|
|
Allocate Interrupts using the MSPINT macro (defined at the top of this file.
|
|
ex: MSPINT "name"
|
|
**********************************************************/
|
|
|
|
MSPINT OsTick
|
|
MSPINT Com1Rx
|
|
MSPINT Com1Tx
|
|
|
|
|
|
/*********************************************************
|
|
Interrupt Vectors
|
|
Timer_A0
|
|
ex: PORT1 would look like:
|
|
ORG PORT1_VECTOR
|
|
DW _"name"
|
|
**********************************************************/
|
|
.VECTORS
|
|
.KEEP
|
|
|
|
ORG TIMERA0_VECTOR
|
|
DW _OsTick
|
|
|
|
ORG UART1RX_VECTOR
|
|
DW _Com1Rx
|
|
|
|
ORG UART1TX_VECTOR
|
|
DW _Com1Tx
|
|
|
|
END
|