From 29b143cfbd1c3b96559cbee13ab961080e97c4aa Mon Sep 17 00:00:00 2001 From: richardbarry Date: Mon, 3 Jan 2011 16:48:59 +0000 Subject: [PATCH] Convert the CCS4 MSP430X port layer to permit large and small data models, and large and small code models. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1219 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- Source/portable/CCS4/MSP430X/data_model.h | 79 +++++++++++++++++++++++ Source/portable/CCS4/MSP430X/port.c | 78 ++++++++++++++-------- Source/portable/CCS4/MSP430X/portext.asm | 34 +++++----- Source/portable/CCS4/MSP430X/portmacro.h | 8 ++- 4 files changed, 155 insertions(+), 44 deletions(-) create mode 100644 Source/portable/CCS4/MSP430X/data_model.h diff --git a/Source/portable/CCS4/MSP430X/data_model.h b/Source/portable/CCS4/MSP430X/data_model.h new file mode 100644 index 000000000..4cc526ef7 --- /dev/null +++ b/Source/portable/CCS4/MSP430X/data_model.h @@ -0,0 +1,79 @@ +; FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd. +; +; *************************************************************************** +; * * +; * If you are: * +; * * +; * + New to FreeRTOS, * +; * + Wanting to learn FreeRTOS or multitasking in general quickly * +; * + Looking for basic training, * +; * + Wanting to improve your FreeRTOS skills and productivity * +; * * +; * then take a look at the FreeRTOS books - available as PDF or paperback * +; * * +; * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * +; * http://www.FreeRTOS.org/Documentation * +; * * +; * A pdf reference manual is also available. Both are usually delivered * +; * to your inbox within 20 minutes to two hours when purchased between 8am * +; * and 8pm GMT (although please allow up to 24 hours in case of * +; * exceptional circumstances). Thank you for your support! * +; * * +; *************************************************************************** +; +; This file is part of the FreeRTOS distribution. +; +; FreeRTOS is free software; you can redistribute it and/or modify it under +; the terms of the GNU General Public License (version 2) as published by the +; Free Software Foundation AND MODIFIED BY the FreeRTOS exception. +; ***NOTE*** The exception to the GPL is included to allow you to distribute +; a combined work that includes FreeRTOS without being obliged to provide the +; source code for proprietary components outside of the FreeRTOS kernel. +; FreeRTOS is distributed in the hope that it will be useful, but WITHOUT +; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +; more details. You should have received a copy of the GNU General Public +; License and the FreeRTOS license exception along with FreeRTOS; if not it +; can be viewed here: http://www.freertos.org/a00114.html and also obtained +; by writing to Richard Barry, contact details for whom are available on the +; FreeRTOS WEB site. +; +; 1 tab == 4 spaces! +; +; http://www.FreeRTOS.org - Documentation, latest information, license and +; contact details. +; +; http://www.SafeRTOS.com - A version that is certified for use in safety +; critical systems. +; +; http://www.OpenRTOS.com - Commercial support, development, porting, +; licensing and training services. + + .if $DEFINED( __LARGE_DATA_MODEL__ ) + .define "pushm.a", pushm_x + .define "popm.a", popm_x + .define "push.a", push_x + .define "pop.a", pop_x + .define "mov.a", mov_x + .define "cmp.a", cmp_x + .else + .define "pushm.w", pushm_x + .define "popm.w", popm_x + .define "push.w", push_x + .define "pop.w", pop_x + .define "mov.w", mov_x + .define "cmp.w", cmp_x + .endif + + .if $DEFINED( __LARGE_CODE_MODEL__ ) + .define "calla", call_x + .define "reta", ret_x + .else + .define "call", call_x + .define "ret", ret_x + .endif + + + + + diff --git a/Source/portable/CCS4/MSP430X/port.c b/Source/portable/CCS4/MSP430X/port.c index 73af84f96..2ba97b0c9 100644 --- a/Source/portable/CCS4/MSP430X/port.c +++ b/Source/portable/CCS4/MSP430X/port.c @@ -98,6 +98,7 @@ 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. @@ -111,38 +112,61 @@ unsigned short *pusTopOfStack; pxTopOfStack--; */ - *pxTopOfStack = ( portSTACK_TYPE ) pxCode; - pusTopOfStack = ( unsigned short * ) pxTopOfStack; + /* Data types are need either 16 bits or 32 bits depending on the data + and code model used. */ + if( sizeof( pxCode ) == sizeof( unsigned short ) ) + { + pusTopOfStack = ( unsigned short * ) pxTopOfStack; + *pusTopOfStack = ( unsigned short ) pxCode; + } + else + { + /* Make room for a 20 bit value stored as a 32 bit value. */ + pusTopOfStack = ( unsigned short * ) pxTopOfStack; + pusTopOfStack--; + pulTopOfStack = ( unsigned long * ) pusTopOfStack; + *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--; - *pxTopOfStack = ( portSTACK_TYPE ) 0xeeeeee; - pxTopOfStack--; - *pxTopOfStack = ( portSTACK_TYPE ) 0xdddddd; - pxTopOfStack--; - *pxTopOfStack = ( portSTACK_TYPE ) pvParameters; - pxTopOfStack--; - *pxTopOfStack = ( portSTACK_TYPE ) 0xbbbbbb; - pxTopOfStack--; - *pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaa; - pxTopOfStack--; - *pxTopOfStack = ( portSTACK_TYPE ) 0x999999; - pxTopOfStack--; - *pxTopOfStack = ( portSTACK_TYPE ) 0x888888; - pxTopOfStack--; - *pxTopOfStack = ( portSTACK_TYPE ) 0x555555; - pxTopOfStack--; - *pxTopOfStack = ( portSTACK_TYPE ) 0x666666; - pxTopOfStack--; - *pxTopOfStack = ( portSTACK_TYPE ) 0x555555; - pxTopOfStack--; - *pxTopOfStack = ( portSTACK_TYPE ) 0x444444; - pxTopOfStack--; + #ifdef PRELOAD_REGISTER_VALUES + *pxTopOfStack = ( portSTACK_TYPE ) 0xffff; + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0xeeee; + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0xdddd; + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) pvParameters; + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0xbbbb; + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0xaaaa; + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x9999; + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x8888; + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x5555; + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x6666; + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x5555; + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) 0x4444; + pxTopOfStack--; + #else + pxTopOfStack -= 3; + *pxTopOfStack = ( portSTACK_TYPE ) pvParameters; + pxTopOfStack -= 9; + #endif /* A variable is used to keep track of the critical section nesting. This variable has to be stored as part of the task context and is diff --git a/Source/portable/CCS4/MSP430X/portext.asm b/Source/portable/CCS4/MSP430X/portext.asm index 44ff501f2..1e09101f7 100644 --- a/Source/portable/CCS4/MSP430X/portext.asm +++ b/Source/portable/CCS4/MSP430X/portext.asm @@ -53,6 +53,8 @@ ; * The definition of the "register test" tasks, as described at the top of ; * main.c + .include data_model.h + .global vTaskIncrementTick .global vTaskSwitchContext .global vPortSetupTimerInterrupt @@ -69,21 +71,21 @@ 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 ) + pushm_x #12, r15 + mov.w &usCriticalNesting, r14 + push_x r14 + mov_x &pxCurrentTCB, r12 + mov_x 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 + 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 @@ -91,7 +93,7 @@ portRESTORE_CONTEXT .macro bic.w #0xf0, 0( sp ) pop.w sr - reta + ret_x .endm ;----------------------------------------------------------- @@ -113,8 +115,8 @@ vPortPreemptiveTickISR: push.w sr portSAVE_CONTEXT - calla #vTaskIncrementTick - calla #vTaskSwitchContext + call_x #vTaskIncrementTick + call_x #vTaskSwitchContext portRESTORE_CONTEXT ;----------------------------------------------------------- @@ -126,7 +128,7 @@ vPortCooperativeTickISR: push.w sr portSAVE_CONTEXT - calla #vTaskIncrementTick + call_x #vTaskIncrementTick portRESTORE_CONTEXT ;----------------------------------------------------------- @@ -147,7 +149,7 @@ vPortYield: portSAVE_CONTEXT ; Select the next task to run. - calla #vTaskSwitchContext + call_x #vTaskSwitchContext ; Restore the context of the new task. portRESTORE_CONTEXT @@ -162,7 +164,7 @@ xPortStartScheduler: ; Setup the hardware to generate the tick. Interrupts are disabled ; when this function is called. - calla #vPortSetupTimerInterrupt + call_x #vPortSetupTimerInterrupt ; Restore the context of the first task that is going to run. portRESTORE_CONTEXT diff --git a/Source/portable/CCS4/MSP430X/portmacro.h b/Source/portable/CCS4/MSP430X/portmacro.h index 3929bffdf..d4422d9ec 100644 --- a/Source/portable/CCS4/MSP430X/portmacro.h +++ b/Source/portable/CCS4/MSP430X/portmacro.h @@ -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. */ +#ifdef __LARGE_DATA_MODEL__ + #define portSTACK_TYPE unsigned long +#else + #define portSTACK_TYPE unsigned short +#endif + #if( configUSE_16_BIT_TICKS == 1 ) typedef unsigned portSHORT portTickType; #define portMAX_DELAY ( portTickType ) 0xffff -- 2.39.5