mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-20 18:18:32 -04:00
Sync up MicroblazeV9 port with Xilinx tree (#220)
* MicroblazeV9: Add support for 64 bit microblaze * MicroblazeV9: Add support for generation of run time task stats * MicroblazeV9: Add default implementation for callback functions --------- Signed-off-by: Mubin Usman Sayyed <mubin.usman.sayyed@xilinx.com>
This commit is contained in:
parent
8e664fc984
commit
5040a67939
6 changed files with 508 additions and 298 deletions
|
@ -42,6 +42,7 @@
|
|||
#include <xintc_i.h>
|
||||
#include <xil_exception.h>
|
||||
#include <microblaze_exceptions_g.h>
|
||||
#include <microblaze_instructions.h>
|
||||
|
||||
/* Tasks are started with a critical section nesting of 0 - however, prior to
|
||||
* the scheduler being commenced interrupts should not be enabled, so the critical
|
||||
|
@ -58,6 +59,13 @@
|
|||
* given to the FSR register when the initial context is set up for a task being
|
||||
* created. */
|
||||
#define portINITIAL_FSR ( 0U )
|
||||
/*
|
||||
* Global counter used for calculation of run time statistics of tasks.
|
||||
* Defined only when the relevant option is turned on
|
||||
*/
|
||||
#if (configGENERATE_RUN_TIME_STATS==1)
|
||||
volatile uint32_t ulHighFrequencyTimerTicks;
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -116,10 +124,11 @@ static XIntc xInterruptControllerInstance;
|
|||
void * pvParameters )
|
||||
#endif
|
||||
{
|
||||
extern void * _SDA2_BASE_;
|
||||
extern void * _SDA_BASE_;
|
||||
const uint32_t ulR2 = ( uint32_t ) &_SDA2_BASE_;
|
||||
const uint32_t ulR13 = ( uint32_t ) &_SDA_BASE_;
|
||||
extern void *_SDA2_BASE_;
|
||||
extern void *_SDA_BASE_;
|
||||
const UINTPTR ulR2 = ( UINTPTR ) &_SDA2_BASE_;
|
||||
const UINTPTR ulR13 = ( UINTPTR ) &_SDA_BASE_;
|
||||
|
||||
extern void _start1( void );
|
||||
|
||||
/* Place a few bytes of known values on the bottom of the stack.
|
||||
|
@ -255,8 +264,8 @@ static XIntc xInterruptControllerInstance;
|
|||
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
extern void( vPortStartFirstTask )( void );
|
||||
extern uint32_t _stack[];
|
||||
extern void ( vPortStartFirstTask )( void );
|
||||
extern UINTPTR _stack[];
|
||||
|
||||
/* Setup the hardware to generate the tick. Interrupts are disabled when
|
||||
* this function is called.
|
||||
|
@ -270,7 +279,7 @@ BaseType_t xPortStartScheduler( void )
|
|||
vApplicationSetupTimerInterrupt();
|
||||
|
||||
/* Reuse the stack from main() as the stack for the interrupts/exceptions. */
|
||||
pulISRStack = ( uint32_t * ) _stack;
|
||||
pulISRStack = ( UINTPTR * ) _stack;
|
||||
|
||||
/* Ensure there is enough space for the functions called from the interrupt
|
||||
* service routines to write back into the stack frame of the caller. */
|
||||
|
@ -304,13 +313,18 @@ void vPortYield( void )
|
|||
* not interrupted by the tick ISR. It is not a problem to do this as
|
||||
* each task maintains its own interrupt status. */
|
||||
portENTER_CRITICAL();
|
||||
{
|
||||
/* Jump directly to the yield function to ensure there is no
|
||||
* compiler generated prologue code. */
|
||||
asm volatile ( "bralid r14, VPortYieldASM \n\t" \
|
||||
"or r0, r0, r0 \n\t" );
|
||||
}
|
||||
portEXIT_CRITICAL();
|
||||
{
|
||||
/* Jump directly to the yield function to ensure there is no
|
||||
* compiler generated prologue code. */
|
||||
#ifdef __arch64__
|
||||
asm volatile ( "brealid r14, VPortYieldASM \n\t" \
|
||||
"or r0, r0, r0 \n\t" );
|
||||
#else
|
||||
asm volatile ( "bralid r14, VPortYieldASM \n\t" \
|
||||
"or r0, r0, r0 \n\t" );
|
||||
#endif
|
||||
}
|
||||
portEXIT_CRITICAL();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -434,22 +448,34 @@ void vPortTickISR( void * pvUnused )
|
|||
{
|
||||
extern void vApplicationClearTimerInterrupt( void );
|
||||
|
||||
/* Ensure the unused parameter does not generate a compiler warning. */
|
||||
( void ) pvUnused;
|
||||
/* Ensure the unused parameter does not generate a compiler warning. */
|
||||
( void ) pvUnused;
|
||||
|
||||
/* This port uses an application defined callback function to clear the tick
|
||||
* interrupt because the kernel will run on lots of different MicroBlaze and
|
||||
* FPGA configurations - not all of which will have the same timer peripherals
|
||||
* defined or available. An example definition of
|
||||
* vApplicationClearTimerInterrupt() is provided in the official demo
|
||||
* application that accompanies this port. */
|
||||
vApplicationClearTimerInterrupt();
|
||||
|
||||
/* Increment the RTOS tick - this might cause a task to unblock. */
|
||||
if( xTaskIncrementTick() != pdFALSE )
|
||||
/* The Xilinx implementation of generating run time task stats uses the same timer used for generating
|
||||
* FreeRTOS ticks. In case user decides to generate run time stats the tick handler is called more
|
||||
* frequently (10 times faster). The timer ick handler uses logic to handle the same. It handles
|
||||
* the FreeRTOS tick once per 10 interrupts.
|
||||
* For handling generation of run time stats, it increments a pre-defined counter every time the
|
||||
* interrupt handler executes. */
|
||||
#if (configGENERATE_RUN_TIME_STATS == 1)
|
||||
ulHighFrequencyTimerTicks++;
|
||||
if (!(ulHighFrequencyTimerTicks % 10))
|
||||
#endif
|
||||
{
|
||||
/* Force vTaskSwitchContext() to be called as the interrupt exits. */
|
||||
ulTaskSwitchRequested = 1;
|
||||
/* This port uses an application defined callback function to clear the tick
|
||||
* interrupt because the kernel will run on lots of different MicroBlaze and
|
||||
* FPGA configurations - not all of which will have the same timer peripherals
|
||||
* defined or available. An example definition of
|
||||
* vApplicationClearTimerInterrupt() is provided in the official demo
|
||||
* application that accompanies this port. */
|
||||
vApplicationClearTimerInterrupt();
|
||||
|
||||
/* Increment the RTOS tick - this might cause a task to unblock. */
|
||||
if( xTaskIncrementTick() != pdFALSE )
|
||||
{
|
||||
/* Force vTaskSwitchContext() to be called as the interrupt exits. */
|
||||
ulTaskSwitchRequested = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -495,4 +521,25 @@ static int32_t prvInitialiseInterruptController( void )
|
|||
|
||||
return lStatus;
|
||||
}
|
||||
|
||||
#if( configGENERATE_RUN_TIME_STATS == 1 )
|
||||
/*
|
||||
* For Xilinx implementation this is a dummy function that does a redundant operation
|
||||
* of zeroing out the global counter.
|
||||
* It is called by FreeRTOS kernel.
|
||||
*/
|
||||
void xCONFIGURE_TIMER_FOR_RUN_TIME_STATS (void)
|
||||
{
|
||||
ulHighFrequencyTimerTicks = 0;
|
||||
}
|
||||
/*
|
||||
* For Xilinx implementation this function returns the global counter used for
|
||||
* run time task stats calculation.
|
||||
* It is called by FreeRTOS kernel task handling logic.
|
||||
*/
|
||||
uint32_t xGET_RUN_TIME_COUNTER_VALUE (void)
|
||||
{
|
||||
return ulHighFrequencyTimerTicks;
|
||||
}
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue