Start to adjust to support both small and large memory models in the MSP430X IAR port layer.

This commit is contained in:
Richard Barry 2011-01-03 11:31:41 +00:00
parent 19fcd2d505
commit d195639bc1
4 changed files with 92 additions and 55 deletions

View File

@ -51,40 +51,24 @@
licensing and training services.
*/
#ifndef PORTASM_H
#define PORTASM_H
#ifndef DATA_MODEL_H
#define DATA_MODEL_H
IMPORT pxCurrentTCB
IMPORT usCriticalNesting
#ifdef __DATA_MODEL_SMALL__
#define pushm_x pushm.w
#define popm_x popm.w
#define push_x push.w
#define pop_x pop.w
#define mov_x mov.w
#define cmp_x cmp.w
#else /* DATA_MODEL_SMALL__ */
#define pushm_x pushm.a
#define popm_x popm.a
#define push_x pushx.a
#define pop_x popx.a
#define mov_x movx.a
#define cmp_x cmpx.a
#endif /* __DATA_MODEL_SMALL__
portSAVE_CONTEXT macro
/* Save the remaining registers. */
pushm.a #12, r15
movx.w &usCriticalNesting, r14
pushx.a r14
movx.a &pxCurrentTCB, r12
movx.a sp, 0( r12 )
endm
/*-----------------------------------------------------------*/
portRESTORE_CONTEXT macro
movx.a &pxCurrentTCB, r12
movx.a @r12, sp
popx.a r15
movx.w r15, &usCriticalNesting
popm.a #12, r15
/* The last thing on the stack will be the status register.
Ensure the power down bits are clear ready for the next
time this power down register is popped from the stack. */
bic.w #0xf0, 0( sp )
pop.w sr
reta
endm
/*-----------------------------------------------------------*/
#endif
#endif /* DATA_MODEL_H */

View File

@ -98,50 +98,68 @@ void vPortSetupTimerInterrupt( void );
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
unsigned short *pusTopOfStack;
unsigned long *pulTopOfStack;
/*
Place a few bytes of known values on the bottom of the stack.
This is just useful for debugging and can be included if required.
*pxTopOfStack = ( portSTACK_TYPE ) 0x1111;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x2222;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x3333;
pxTopOfStack--;
*/
*pxTopOfStack = ( portSTACK_TYPE ) pxCode;
pusTopOfStack = ( unsigned short * ) pxTopOfStack;
/* portSTACK_TYPE is either 16 bits or 32 bits depending on the data model.
Some stacked items do not change size depending on the data model so have
to be explicitly cast to the correct size so this function will work
whichever data model is being used. */
if( sizeof( portSTACK_TYPE ) == sizeof( unsigned short ) )
{
/* Make room for a 20 bit value stored as a 32 bit value. */
pusTopOfStack = ( unsigned short * ) pxTopOfStack;
pusTopOfStack--;
pulTopOfStack = ( unsigned long * ) pusTopOfStack;
}
else
{
pulTopOfStack = ( unsigned long * ) pxTopOfStack;
}
*pulTopOfStack = ( unsigned long ) pxCode;
pusTopOfStack = ( unsigned short * ) pulTopOfStack;
pusTopOfStack--;
*pusTopOfStack = portFLAGS_INT_ENABLED;
pusTopOfStack -= 2;
pusTopOfStack -= ( sizeof( portSTACK_TYPE ) / 2 );
/* From here on the size of stacked items depends on the memory model. */
pxTopOfStack = ( portSTACK_TYPE * ) pusTopOfStack;
/* Next the general purpose registers. */
*pxTopOfStack = ( portSTACK_TYPE ) 0xffffff;
*pxTopOfStack = ( portSTACK_TYPE ) 0xfffff;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xeeeeee;
*pxTopOfStack = ( portSTACK_TYPE ) 0xeeeee;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xdddddd;
*pxTopOfStack = ( portSTACK_TYPE ) 0xddddd;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xbbbbbb;
*pxTopOfStack = ( portSTACK_TYPE ) 0xbbbbb;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaa;
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaa;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x999999;
*pxTopOfStack = ( portSTACK_TYPE ) 0x99999;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x888888;
*pxTopOfStack = ( portSTACK_TYPE ) 0x88888;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x555555;
*pxTopOfStack = ( portSTACK_TYPE ) 0x55555;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x666666;
*pxTopOfStack = ( portSTACK_TYPE ) 0x66666;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x555555;
*pxTopOfStack = ( portSTACK_TYPE ) 0x55555;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) 0x444444;
*pxTopOfStack = ( portSTACK_TYPE ) 0x44444;
pxTopOfStack--;
/* A variable is used to keep track of the critical section nesting.

View File

@ -52,16 +52,47 @@
*/
#include "msp430.h"
#include "FreeRTOSConfig.h"
#include "portasm.h"
#include "data_model.h"
IMPORT vTaskIncrementTick
IMPORT vTaskSwitchContext
IMPORT vPortSetupTimerInterrupt
IMPORT pxCurrentTCB
IMPORT usCriticalNesting
EXPORT vPortTickISR
EXPORT vPortYield
EXPORT xPortStartScheduler
portSAVE_CONTEXT macro
/* Save the remaining registers. */
pushm_x #12, r15
mov.w &usCriticalNesting, r14
push_x r14
mov_x &pxCurrentTCB, r12
mov_x sp, 0( r12 )
endm
/*-----------------------------------------------------------*/
portRESTORE_CONTEXT macro
mov_x &pxCurrentTCB, r12
mov_x @r12, sp
pop_x r15
mov.w r15, &usCriticalNesting
popm_x #12, r15
/* The last thing on the stack will be the status register.
Ensure the power down bits are clear ready for the next
time this power down register is popped from the stack. */
bic.w #0xf0, 0( sp )
pop.w sr
reta
endm
/*-----------------------------------------------------------*/
/*
* The RTOS tick ISR.
@ -72,7 +103,7 @@
* If the preemptive scheduler is in use a context switch can also occur.
*/
RSEG ISR_CODE
RSEG CODE
vPortTickISR:
@ -90,8 +121,6 @@ vPortTickISR:
portRESTORE_CONTEXT
/*-----------------------------------------------------------*/
RSEG CODE
/*
* Manual context switch called by the portYIELD() macro.
*/

View File

@ -73,9 +73,15 @@
#define portDOUBLE double
#define portLONG long
#define portSHORT int
#define portSTACK_TYPE unsigned portLONG
#define portBASE_TYPE portSHORT
/* The stack type changes depending on the data model. */
#if( __DATA_MODEL__ == __DATA_MODEL_SMALL__ )
#define portSTACK_TYPE unsigned short
#else
#define portSTACK_TYPE unsigned long
#endif
#if( configUSE_16_BIT_TICKS == 1 )
typedef unsigned portSHORT portTickType;
#define portMAX_DELAY ( portTickType ) 0xffff