blob: 0b12a88336b1d5d8e38ecac82e5d4f2981b598e1 [file] [log] [blame]
/*
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
extern void vPortStartTask( void );
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
* will be set to 0 prior to the first task being started. */
portLONG ulCriticalNesting = 0x9999UL;
/* Used to record one tack want to swtich task after enter critical area, we need know it
* and implement task switch after exit critical area */
portLONG pendsvflag = 0;
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters )
{
StackType_t * stk = NULL;
stk = pxTopOfStack;
*( --stk ) = ( uint32_t ) pxCode; /* Entry Point */
*( --stk ) = ( uint32_t ) 0xE0000140L; /* PSR */
*( --stk ) = ( uint32_t ) 0xFFFFFFFEL; /* R15 (LR) (init value will cause fault if ever used) */
*( --stk ) = ( uint32_t ) 0x13131313L; /* R13 */
*( --stk ) = ( uint32_t ) 0x12121212L; /* R12 */
*( --stk ) = ( uint32_t ) 0x11111111L; /* R11 */
*( --stk ) = ( uint32_t ) 0x10101010L; /* R10 */
*( --stk ) = ( uint32_t ) 0x09090909L; /* R9 */
*( --stk ) = ( uint32_t ) 0x08080808L; /* R8 */
*( --stk ) = ( uint32_t ) 0x07070707L; /* R7 */
*( --stk ) = ( uint32_t ) 0x06060606L; /* R6 */
*( --stk ) = ( uint32_t ) 0x05050505L; /* R5 */
*( --stk ) = ( uint32_t ) 0x04040404L; /* R4 */
*( --stk ) = ( uint32_t ) 0x03030303L; /* R3 */
*( --stk ) = ( uint32_t ) 0x02020202L; /* R2 */
*( --stk ) = ( uint32_t ) 0x01010101L; /* R1 */
*( --stk ) = ( uint32_t ) pvParameters; /* R0 : argument */
return stk;
}
BaseType_t xPortStartScheduler( void )
{
ulCriticalNesting = 0UL;
vPortStartTask();
return pdFALSE;
}
void vPortEndScheduler( void )
{
/* Not implemented as there is nothing to return to. */
}
void vPortEnterCritical( void )
{
portDISABLE_INTERRUPTS();
ulCriticalNesting++;
}
void vPortExitCritical( void )
{
if( ulCriticalNesting == 0 )
{
while( 1 )
{
}
}
ulCriticalNesting--;
if( ulCriticalNesting == 0 )
{
portENABLE_INTERRUPTS();
if( pendsvflag )
{
pendsvflag = 0;
portYIELD();
}
}
}
#if configUSE_PREEMPTION == 0
void xPortSysTickHandler( void )
{
portLONG ulDummy;
ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
xTaskIncrementTick();
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
}
#else
void xPortSysTickHandler( void )
{
portLONG ulDummy;
ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
{
if( xTaskIncrementTick() != pdFALSE )
{
portYIELD_FROM_ISR( pdTRUE );
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
}
#endif /* if configUSE_PREEMPTION == 0 */
void vPortYieldHandler( void )
{
uint32_t ulSavedInterruptMask;
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
vTaskSwitchContext();
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
}
__attribute__( ( weak ) ) void vApplicationStackOverflowHook( xTaskHandle * pxTask,
signed portCHAR * pcTaskName )
{
for( ; ; )
{
}
}
__attribute__( ( weak ) ) void vApplicationMallocFailedHook( void )
{
for( ; ; )
{
}
}