* 1 tab == 4 spaces!\r
*/\r
\r
-/* FreeRTOS kernel includes. */\r
-#include <FreeRTOS.h>\r
-#include <task.h>\r
-\r
-/* Freedom metal driver includes. */\r
-#include <metal/cpu.h>\r
-#include <metal/led.h>\r
-#include <metal/button.h>\r
-\r
/******************************************************************************\r
* This project provides two demo applications. A simple blinky style project,\r
* and a more comprehensive test and demo application. The\r
* This file implements the code that is not demo specific, including the\r
* hardware setup and standard FreeRTOS hook functions.\r
*\r
+ * When running on the HiFive Rev B hardware:\r
+ * When executing correctly the blue LED will toggle every three seconds. If\r
+ * the blue LED toggles every 500ms then one of the self-monitoring test tasks\r
+ * discovered a potential issue. If the red led toggles rapidly then a hardware\r
+ * exception occurred.\r
+ *\r
* ENSURE TO READ THE DOCUMENTATION PAGE FOR THIS PORT AND DEMO APPLICATION ON\r
* THE http://www.FreeRTOS.org WEB SITE FOR FULL INFORMATION ON USING THIS DEMO\r
* APPLICATION, AND ITS ASSOCIATE FreeRTOS ARCHITECTURE PORT!\r
*\r
- *\r
*/\r
\r
-#warning Also test in QEMU and add instructions above.\r
+/* FreeRTOS kernel includes. */\r
+#include <FreeRTOS.h>\r
+#include <task.h>\r
+\r
+/* Freedom metal driver includes. */\r
+#include <metal/cpu.h>\r
+#include <metal/led.h>\r
\r
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,\r
or 0 to run the more comprehensive test and demo application. */\r
-#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0\r
+#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1\r
\r
/* Index to first HART (there is only one). */\r
#define mainHART_0 0\r
\r
-/* Register addresses within the PLIC. */\r
+/* Registers used to initialise the PLIC. */\r
#define mainPLIC_PENDING_0 ( * ( ( volatile uint32_t * ) 0x0C001000UL ) )\r
#define mainPLIC_PENDING_1 ( * ( ( volatile uint32_t * ) 0x0C001004UL ) )\r
#define mainPLIC_ENABLE_0 ( * ( ( volatile uint32_t * ) 0x0C002000UL ) )\r
#define mainPLIC_ENABLE_1 ( * ( ( volatile uint32_t * ) 0x0C002004UL ) )\r
\r
+/*-----------------------------------------------------------*/\r
+\r
/*\r
* main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.\r
* main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.\r
extern void main_full( void );\r
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */\r
\r
-/* Prototypes for the standard FreeRTOS callback/hook functions implemented\r
-within this file. See https://www.freertos.org/a00016.html */\r
+/*\r
+ * Prototypes for the standard FreeRTOS callback/hook functions implemented\r
+ * within this file. See https://www.freertos.org/a00016.html\r
+ */\r
void vApplicationMallocFailedHook( void );\r
void vApplicationIdleHook( void );\r
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );\r
void vApplicationTickHook( void );\r
\r
-/* Setup the hardware to run this demo. */\r
+/*\r
+ * Setup the hardware to run this demo.\r
+ */\r
static void prvSetupHardware( void );\r
\r
-/* Used by the Freedom Metal drivers. */\r
-static struct metal_led *pxLED = NULL;\r
+/*\r
+ * Used by the Freedom Metal drivers.\r
+ */\r
+static struct metal_led *pxBlueLED = NULL;\r
\r
/*-----------------------------------------------------------*/\r
\r
struct metal_interrupt *pxInterruptController;\r
\r
/* Initialise the blue LED. */\r
- pxLED = metal_led_get_rgb( "LD0", "blue" );\r
- configASSERT( pxLED );\r
- metal_led_enable( pxLED );\r
- metal_led_off( pxLED );\r
+ pxBlueLED = metal_led_get_rgb( "LD0", "blue" );\r
+ configASSERT( pxBlueLED );\r
+ metal_led_enable( pxBlueLED );\r
+ metal_led_off( pxBlueLED );\r
\r
/* Initialise the interrupt controller. */\r
pxCPU = metal_cpu_get( mainHART_0 );\r
{\r
static struct metal_led *pxRedLED = NULL;\r
volatile uint32_t ul;\r
+const uint32_t ulNullLoopDelay = 0x1ffffUL;\r
\r
taskDISABLE_INTERRUPTS();\r
\r
\r
/* Flash the red LED to indicate that assert was hit - interrupts are off\r
here to prevent any further tick interrupts or context switches, so the\r
- delay is implemented as a crude loop. */\r
+ delay is implemented as a crude loop instead of a peripheral timer. */\r
for( ;; )\r
{\r
- for( ul = 0; ul < 0x1ffff; ul++ )\r
+ for( ul = 0; ul < ulNullLoopDelay; ul++ )\r
{\r
__asm volatile( "nop" );\r
}\r
}\r
/*-----------------------------------------------------------*/\r
\r
-volatile uint32_t ulMEPC = 0UL, ulMCAUSE = 0UL, ulPending0Register = 0UL, ulPending1Register = 0UL;\r
-\r
void handle_trap( void )\r
{\r
-#warning Not implemented.\r
+volatile uint32_t ulMEPC = 0UL, ulMCAUSE = 0UL, ulPLICPending0Register = 0UL, ulPLICPending1Register = 0UL;\r
\r
+ /* Store a few register values that might be useful when determining why this\r
+ function was called. */\r
__asm volatile( "csrr %0, mepc" : "=r"( ulMEPC ) );\r
__asm volatile( "csrr %0, mcause" : "=r"( ulMCAUSE ) );\r
- ulPending0Register = mainPLIC_PENDING_0;\r
- ulPending1Register = mainPLIC_PENDING_1;\r
+ ulPLICPending0Register = mainPLIC_PENDING_0;\r
+ ulPLICPending1Register = mainPLIC_PENDING_1;\r
+\r
+ /* Prevent compiler warnings about unused variables. */\r
+ ( void ) ulPLICPending0Register;\r
+ ( void ) ulPLICPending1Register;\r
+\r
+ /* Force an assert as this function has not been implemented as the demo\r
+ does not use external interrupts. */\r
configASSERT( metal_cpu_get( mainHART_0 ) == 0x00 );\r
}\r
/*-----------------------------------------------------------*/\r
\r
void vToggleLED( void )\r
{\r
- metal_led_toggle( pxLED );\r
+ metal_led_toggle( pxBlueLED );\r
}\r
/*-----------------------------------------------------------*/\r
\r
void *malloc( size_t xSize )\r
{\r
+ /* The linker script does not define a heap so artificially force an assert()\r
+ if something unexpectedly uses the C library heap. See\r
+ https://www.freertos.org/a00111.html for more information. */\r
configASSERT( metal_cpu_get( mainHART_0 ) == 0x00 );\r
return NULL;\r
}\r