text: /*
      FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd. 
      All rights reserved
  
      VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
  
      ***************************************************************************
       *                                                                       *
       *    FreeRTOS provides completely free yet professionally developed,    *
       *    robust, strictly quality controlled, supported, and cross          *
       *    platform software that has become a de facto standard.             *
       *                                                                       *
       *    Help yourself get started quickly and support the FreeRTOS         *
       *    project by purchasing a FreeRTOS tutorial book, reference          *
       *    manual, or both from: http://www.FreeRTOS.org/Documentation        *
       *                                                                       *
       *    Thank you!                                                         *
       *                                                                       *
      ***************************************************************************
  
      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 modification 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.  Full license text is available from the following
      link: http://www.freertos.org/a00114.html
  
      1 tab == 4 spaces!
  
      ***************************************************************************
       *                                                                       *
       *    Having a problem?  Start by reading the FAQ "My application does   *
       *    not run, what could be wrong?"                                     *
       *                                                                       *
       *    http://www.FreeRTOS.org/FAQHelp.html                               *
       *                                                                       *
      ***************************************************************************
  
      http://www.FreeRTOS.org - Documentation, books, training, latest versions,
      license and Real Time Engineers Ltd. contact details.
  
      http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
      including FreeRTOS+Trace - an indispensable productivity tool, a DOS
      compatible FAT file system, and our tiny thread aware UDP/IP stack.
  
      http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
      Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS
      licenses offer ticketed support, indemnification and middleware.
  
      http://www.SafeRTOS.com - High Integrity Systems also provide a safety
      engineered and independently SIL3 certified version for use in safety and
      mission critical applications that require provable dependability.
  
      1 tab == 4 spaces!
  */
  
  
  /*-----------------------------------------------------------
   * Components that can be compiled to either ARM or THUMB mode are
   * contained in port.c  The ISR routines, which can only be compiled
   * to ARM mode, are contained in this file.
   *----------------------------------------------------------*/
  
  /*
  */
  
  /* Scheduler includes. */
  #include "FreeRTOS.h"
  #include "task.h"
  
  /* Constants required to handle critical sections. */
  #define portNO_CRITICAL_NESTING		( ( uint32_t ) 0 )
  
  volatile uint32_t ulCriticalNesting = 9999UL;
  
  /*-----------------------------------------------------------*/
  
  /* 
   * The scheduler can only be started from ARM mode, hence the inclusion of this
   * function here.
   */
  void vPortISRStartFirstTask( void );
  /*-----------------------------------------------------------*/
  
  void vPortISRStartFirstTask( void )
  {
  	/* Simply start the scheduler.  This is included here as it can only be
  	called from ARM mode. */
  	asm volatile (														\
  	"LDR		R0, =pxCurrentTCB								\n\t"	\
  	"LDR		R0, [R0]										\n\t"	\
  	"LDR		LR, [R0]										\n\t"	\
  																		\
  	/* The critical nesting depth is the first item on the stack. */	\
  	/* Load it into the ulCriticalNesting variable. */					\
  	"LDR		R0, =ulCriticalNesting							\n\t"	\
  	"LDMFD	LR!, {R1}											\n\t"	\
  	"STR		R1, [R0]										\n\t"	\
  																		\
  	/* Get the SPSR from the stack. */									\
  	"LDMFD	LR!, {R0}											\n\t"	\
  	"MSR		SPSR, R0										\n\t"	\
  																		\
  	/* Restore all system mode registers for the task. */				\
  	"LDMFD	LR, {R0-R14}^										\n\t"	\
  	"NOP														\n\t"	\
  																		\
  	/* Restore the return address. */									\
  	"LDR		LR, [LR, #+60]									\n\t"	\
  																		\
  	/* And return - correcting the offset in the LR to obtain the */	\
  	/* correct address. */												\
  	"SUBS PC, LR, #4											\n\t"	\
  	);																	
  }
  /*-----------------------------------------------------------*/
  
  void vPortTickISR( void )
  {
  	/* Increment the RTOS tick count, then look for the highest priority 
  	task that is ready to run. */
  	if( xTaskIncrementTick() != pdFALSE )
  	{	
  		vTaskSwitchContext();
  	}
  			
  	/* Ready for the next interrupt. */
  	TB_ClearITPendingBit( TB_IT_Update );	
  }
  
  /*-----------------------------------------------------------*/
  
  /*
   * The interrupt management utilities can only be called from ARM mode.  When
   * THUMB_INTERWORK is defined the utilities are defined as functions here to
   * ensure a switch to ARM mode.  When THUMB_INTERWORK is not defined then
   * the utilities are defined as macros in portmacro.h - as per other ports.
   */
  #ifdef THUMB_INTERWORK
  
  	void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
  	void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
  
  	void vPortDisableInterruptsFromThumb( void )
  	{
  		asm volatile ( 
  			"STMDB	SP!, {R0}		\n\t"	/* Push R0.									*/
  			"MRS	R0, CPSR		\n\t"	/* Get CPSR.								*/
  			"ORR	R0, R0, #0xC0	\n\t"	/* Disable IRQ, FIQ.						*/
  			"MSR	CPSR, R0		\n\t"	/* Write back modified value.				*/
  			"LDMIA	SP!, {R0}		\n\t"	/* Pop R0.									*/
  			"BX		R14" );					/* Return back to thumb.					*/
  	}
  			
  	void vPortEnableInterruptsFromThumb( void )
  	{
  		asm volatile ( 
  			"STMDB	SP!, {R0}		\n\t"	/* Push R0.									*/	
  			"MRS	R0, CPSR		\n\t"	/* Get CPSR.								*/	
  			"BIC	R0, R0, #0xC0	\n\t"	/* Enable IRQ, FIQ.							*/	
  			"MSR	CPSR, R0		\n\t"	/* Write back modified value.				*/	
  			"LDMIA	SP!, {R0}		\n\t"	/* Pop R0.									*/
  			"BX		R14" );					/* Return back to thumb.					*/
  	}
  
  #endif /* THUMB_INTERWORK */
  /*-----------------------------------------------------------*/
  
  void vPortEnterCritical( void )
  {
  	/* Disable interrupts as per portDISABLE_INTERRUPTS(); 							*/
  	asm volatile ( 
  		"STMDB	SP!, {R0}			\n\t"	/* Push R0.								*/
  		"MRS	R0, CPSR			\n\t"	/* Get CPSR.							*/
  		"ORR	R0, R0, #0xC0		\n\t"	/* Disable IRQ, FIQ.					*/
  		"MSR	CPSR, R0			\n\t"	/* Write back modified value.			*/
  		"LDMIA	SP!, {R0}" );				/* Pop R0.								*/
  
  	/* Now interrupts are disabled ulCriticalNesting can be accessed 
  	directly.  Increment ulCriticalNesting to keep a count of how many times
  	portENTER_CRITICAL() has been called. */
  	ulCriticalNesting++;
  }
  /*-----------------------------------------------------------*/
  
  void vPortExitCritical( void )
  {
  	if( ulCriticalNesting > portNO_CRITICAL_NESTING )
  	{
  		/* Decrement the nesting count as we are leaving a critical section. */
  		ulCriticalNesting--;
  
  		/* If the nesting level has reached zero then interrupts should be
  		re-enabled. */
  		if( ulCriticalNesting == portNO_CRITICAL_NESTING )
  		{
  			/* Enable interrupts as per portEXIT_CRITICAL().					*/
  			asm volatile ( 
  				"STMDB	SP!, {R0}		\n\t"	/* Push R0.						*/	
  				"MRS	R0, CPSR		\n\t"	/* Get CPSR.					*/	
  				"BIC	R0, R0, #0xC0	\n\t"	/* Enable IRQ, FIQ.				*/	
  				"MSR	CPSR, R0		\n\t"	/* Write back modified value.	*/	
  				"LDMIA	SP!, {R0}" );			/* Pop R0.						*/
  		}
  	}
  }
  
  
  
  
  
  