www.freertos.org test on stm32f0

Fork of FreeRTOS by Rohit Grover

Revision:
1:fc62ab66aa39
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Source/portable/RVDS/ARM_CM0/port.c	Fri Mar 02 09:46:03 2018 +0000
@@ -0,0 +1,340 @@
+/*
+    FreeRTOS V7.6.0 - Copyright (C) 2013 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!
+*/
+
+/*-----------------------------------------------------------
+ * Implementation of functions defined in portable.h for the ARM CM0 port.
+ *----------------------------------------------------------*/
+
+/* Scheduler includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+
+/* Constants required to manipulate the NVIC. */
+#define portNVIC_SYSTICK_CTRL		( ( volatile unsigned long *) 0xe000e010 )
+#define portNVIC_SYSTICK_LOAD		( ( volatile unsigned long *) 0xe000e014 )
+#define portNVIC_INT_CTRL			( ( volatile unsigned long *) 0xe000ed04 )
+#define portNVIC_SYSPRI2			( ( volatile unsigned long *) 0xe000ed20 )
+#define portNVIC_SYSTICK_CLK		0x00000004
+#define portNVIC_SYSTICK_INT		0x00000002
+#define portNVIC_SYSTICK_ENABLE		0x00000001
+#define portNVIC_PENDSVSET			0x10000000
+#define portMIN_INTERRUPT_PRIORITY	( 255UL )
+#define portNVIC_PENDSV_PRI			( portMIN_INTERRUPT_PRIORITY << 16UL )
+#define portNVIC_SYSTICK_PRI		( portMIN_INTERRUPT_PRIORITY << 24UL )
+
+/* Constants required to set up the initial stack. */
+#define portINITIAL_XPSR			( 0x01000000 )
+
+/* Constants used with memory barrier intrinsics. */
+#define portSY_FULL_READ_WRITE		( 15 )
+
+/* Each task maintains its own interrupt status in the critical nesting
+variable. */
+static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa;
+
+/*
+ * Setup the timer to generate the tick interrupts.
+ */
+static void prvSetupTimerInterrupt( void );
+
+/*
+ * Exception handlers.
+ */
+void xPortPendSVHandler( void );
+void xPortSysTickHandler( void );
+void vPortSVCHandler( void );
+
+/*
+ * Start first task is a separate function so it can be tested in isolation.
+ */
+static void prvPortStartFirstTask( void );
+
+/*
+ * Used to catch tasks that attempt to return from their implementing function.
+ */
+static void prvTaskExitError( void );
+
+/*-----------------------------------------------------------*/
+
+/*
+ * See header file for description.
+ */
+portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
+{
+	/* Simulate the stack frame as it would be created by a context switch
+	interrupt. */
+	pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
+	*pxTopOfStack = portINITIAL_XPSR;	/* xPSR */
+	pxTopOfStack--;
+	*pxTopOfStack = ( portSTACK_TYPE ) pxCode;	/* PC */
+	pxTopOfStack--;
+	*pxTopOfStack = ( portSTACK_TYPE ) prvTaskExitError;	/* LR */
+	pxTopOfStack -= 5;	/* R12, R3, R2 and R1. */
+	*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;	/* R0 */
+	pxTopOfStack -= 8; /* R11..R4. */
+
+	return pxTopOfStack;
+}
+/*-----------------------------------------------------------*/
+
+static void prvTaskExitError( void )
+{
+	/* A function that implements a task must not exit or attempt to return to
+	its caller as there is nothing to return to.  If a task wants to exit it 
+	should instead call vTaskDelete( NULL ).
+	
+	Artificially force an assert() to be triggered if configASSERT() is 
+	defined, then stop here so application writers can catch the error. */
+	configASSERT( uxCriticalNesting == ~0UL );
+	portDISABLE_INTERRUPTS();	
+	for( ;; );
+}
+/*-----------------------------------------------------------*/
+
+void vPortSVCHandler( void )
+{
+	/* This function is no longer used, but retained for backward 
+	compatibility. */
+}
+/*-----------------------------------------------------------*/
+
+__asm void prvPortStartFirstTask( void )
+{
+	extern pxCurrentTCB;
+	
+	PRESERVE8
+	
+	/* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector
+	table offset register that can be used to locate the initial stack value.
+	Not all M0 parts have the application vector table at address 0. */
+	
+	ldr	r3, =pxCurrentTCB	/* Obtain location of pxCurrentTCB. */
+	ldr r1, [r3]			
+	ldr r0, [r1]			/* The first item in pxCurrentTCB is the task top of stack. */
+	adds r0, #32			/* Discard everything up to r0. */
+	msr psp, r0				/* This is now the new top of stack to use in the task. */
+	movs r0, #2				/* Switch to the psp stack. */
+	msr CONTROL, r0
+	pop {r0-r5}				/* Pop the registers that are saved automatically. */
+	mov lr, r5				/* lr is now in r5. */
+	cpsie i					/* The first task has its context and interrupts can be enabled. */
+	pop {pc}				/* Finally, pop the PC to jump to the user defined task code. */
+
+	ALIGN
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * See header file for description.
+ */
+portBASE_TYPE xPortStartScheduler( void )
+{
+	/* Make PendSV, CallSV and SysTick the same priroity as the kernel. */
+	*(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;
+	*(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI;
+
+	/* Start the timer that generates the tick ISR.  Interrupts are disabled
+	here already. */
+	prvSetupTimerInterrupt();
+
+	/* Initialise the critical nesting count ready for the first task. */
+	uxCriticalNesting = 0;
+
+	/* Start the first task. */
+	prvPortStartFirstTask();
+
+	/* Should not get here! */
+	return 0;
+}
+/*-----------------------------------------------------------*/
+
+void vPortEndScheduler( void )
+{
+  /* It is unlikely that the CM0 port will require this function as there
+    is nothing to return to.  */
+}
+/*-----------------------------------------------------------*/
+
+void vPortYield( void )
+{
+	/* Set a PendSV to request a context switch. */
+	*( portNVIC_INT_CTRL ) = portNVIC_PENDSVSET;
+
+	/* Barriers are normally not required but do ensure the code is completely
+	within the specified behaviour for the architecture. */
+	__dsb( portSY_FULL_READ_WRITE );
+	__isb( portSY_FULL_READ_WRITE );
+}
+/*-----------------------------------------------------------*/
+
+void vPortEnterCritical( void )
+{
+    portDISABLE_INTERRUPTS();
+    uxCriticalNesting++;
+	__dsb( portSY_FULL_READ_WRITE );
+	__isb( portSY_FULL_READ_WRITE );
+}
+/*-----------------------------------------------------------*/
+
+void vPortExitCritical( void )
+{
+    uxCriticalNesting--;
+    if( uxCriticalNesting == 0 )
+    {
+        portENABLE_INTERRUPTS();
+    }
+}
+/*-----------------------------------------------------------*/
+
+__asm unsigned long ulSetInterruptMaskFromISR( void )
+{
+	mrs r0, PRIMASK
+	cpsid i
+	bx lr
+}
+/*-----------------------------------------------------------*/
+
+__asm void vClearInterruptMaskFromISR( unsigned long ulMask )
+{
+	msr PRIMASK, r0
+	bx lr
+}
+/*-----------------------------------------------------------*/
+
+__asm void xPortPendSVHandler( void )
+{
+	extern vTaskSwitchContext
+	extern pxCurrentTCB
+
+	PRESERVE8
+
+	mrs r0, psp
+
+	ldr	r3, =pxCurrentTCB 	/* Get the location of the current TCB. */
+	ldr	r2, [r3]
+
+	subs r0, #32			/* Make space for the remaining low registers. */
+	str r0, [r2]			/* Save the new top of stack. */
+	stmia r0!, {r4-r7}		/* Store the low registers that are not saved automatically. */
+	mov r4, r8				/* Store the high registers. */
+	mov r5, r9
+	mov r6, r10
+	mov r7, r11
+	stmia r0!, {r4-r7}
+
+	push {r3, r14}
+	cpsid i
+	bl vTaskSwitchContext
+	cpsie i
+	pop {r2, r3}			/* lr goes in r3. r2 now holds tcb pointer. */
+
+	ldr r1, [r2]
+	ldr r0, [r1]			/* The first item in pxCurrentTCB is the task top of stack. */
+	adds r0, #16			/* Move to the high registers. */
+	ldmia r0!, {r4-r7}		/* Pop the high registers. */
+	mov r8, r4
+	mov r9, r5
+	mov r10, r6
+	mov r11, r7
+
+	msr psp, r0				/* Remember the new top of stack for the task. */
+
+	subs r0, #32			/* Go back for the low registers that are not automatically restored. */
+	ldmia r0!, {r4-r7}      /* Pop low registers.  */
+
+	bx r3
+	ALIGN
+}
+/*-----------------------------------------------------------*/
+
+void xPortSysTickHandler( void )
+{
+unsigned long ulPreviousMask;
+
+	ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
+	{
+		/* Increment the RTOS tick. */
+		if( xTaskIncrementTick() != pdFALSE )
+		{
+			/* Pend a context switch. */
+			*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
+		}
+	}
+	portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Setup the systick timer to generate the tick interrupts at the required
+ * frequency.
+ */
+void prvSetupTimerInterrupt( void )
+{
+	/* Configure SysTick to interrupt at the requested rate. */
+	*(portNVIC_SYSTICK_LOAD) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
+	*(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;
+}
+/*-----------------------------------------------------------*/
+