}\r
/*-----------------------------------------------------------*/\r
\r
-static void prvTimerCallback( TaskHandle_t xExpiredTimer )\r
+static void prvTimerCallback( TimerHandle_t xExpiredTimer )\r
{\r
uint32_t ulCount;\r
\r
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash.8320194" name="Create flash image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash" useByScannerDiscovery="false" value="true" valueType="boolean"/>\r
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting.379436257" name="Create extended listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting" useByScannerDiscovery="false"/>\r
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize.1043841176" name="Print size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize" useByScannerDiscovery="false" value="true" valueType="boolean"/>\r
- <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.383399415" name="Optimization Level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level" useByScannerDiscovery="true" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.more" valueType="enumerated"/>\r
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.383399415" name="Optimization Level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level" useByScannerDiscovery="true" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.none" valueType="enumerated"/>\r
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength.178339006" name="Message length (-fmessage-length=0)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength" useByScannerDiscovery="true" value="false" valueType="boolean"/>\r
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar.119459497" name="'char' is signed (-fsigned-char)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar" useByScannerDiscovery="true" value="false" valueType="boolean"/>\r
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections.735578493" name="Function sections (-ffunction-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections" useByScannerDiscovery="true" value="false" valueType="boolean"/>\r
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.1472778604" name="GNU RISC-V Cross Assembler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler">\r
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.usepreprocessor.874608690" name="Use preprocessor" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.usepreprocessor" useByScannerDiscovery="false" value="true" valueType="boolean"/>\r
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.include.paths.545620458" name="Include paths (-I)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.include.paths" useByScannerDiscovery="true" valueType="includePath">\r
- <listOptionValue builtIn="false" value="../../../../bsp/env"/>\r
- <listOptionValue builtIn="false" value="../../../../bsp/include"/>\r
- <listOptionValue builtIn="false" value="../../../../bsp/env/freedom-e300-hifive1"/>\r
- <listOptionValue builtIn="false" value="../../../../bsp/drivers"/>\r
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/freedom-e-sdk/env}""/>\r
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/freedom-e-sdk/include}""/>\r
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/freedom-e-sdk/env/freedom-e300-hifive1}""/>\r
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/freedom-e-sdk/drivers}""/>\r
</option>\r
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.other.855588508" name="Other assembler flags" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.assembler.other" useByScannerDiscovery="false" value="-c" valueType="string"/>\r
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input.1208356864" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input"/>\r
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/freedom-e-sdk/include}""/>\r
</option>\r
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.defs.1115817835" name="Defined symbols (-D)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.defs" useByScannerDiscovery="true" valueType="definedSymbols">\r
- <listOptionValue builtIn="false" value="USE_PLIC"/>\r
- <listOptionValue builtIn="false" value="USE_M_TIME"/>\r
+ <listOptionValue builtIn="false" value="DONT_USE_PLIC"/>\r
+ <listOptionValue builtIn="false" value="DONT_USE_M_TIME"/>\r
</option>\r
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.other.953712529" name="Other compiler flags" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.other" useByScannerDiscovery="true" value="-include sys/cdefs.h -fno-builtin-printf -c" valueType="string"/>\r
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.std.1963706020" name="Language standard" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.std" useByScannerDiscovery="true" value="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.std.default" valueType="enumerated"/>\r
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.otheroptimizations.1382786252" name="Other optimization flags" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.otheroptimizations" useByScannerDiscovery="true" value="" valueType="string"/>\r
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.517786622" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input"/>\r
</tool>\r
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler.890064572" name="GNU RISC-V Cross C++ Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler"/>\r
</toolChain>\r
</folderInfo>\r
<sourceEntries>\r
- <entry excluding="freedom-e-sdk/env/entry.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>\r
+ <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>\r
</sourceEntries>\r
</configuration>\r
</storageModule>\r
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>\r
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>\r
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>\r
- <provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="1914048489906665533" id="ilg.gnumcueclipse.managedbuild.cross.riscv.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT RISC-V Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">\r
+ <provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="1967898482140670668" id="ilg.gnumcueclipse.managedbuild.cross.riscv.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT RISC-V Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">\r
<language-scope id="org.eclipse.cdt.core.gcc"/>\r
<language-scope id="org.eclipse.cdt.core.g++"/>\r
</provider>\r
#ifndef FREERTOS_CONFIG_H\r
#define FREERTOS_CONFIG_H\r
\r
+#include "platform.h"\r
\r
/*-----------------------------------------------------------\r
* Application specific definitions.\r
* See http://www.freertos.org/a00110.html.\r
*----------------------------------------------------------*/\r
\r
-#define configCTRL_BASE 0x2000000\r
+#define configCLINT_BASE_ADDRESS CLINT_CTRL_ADDR\r
#define configUSE_PREEMPTION 1\r
#define configUSE_IDLE_HOOK 0\r
#define configUSE_TICK_HOOK 0\r
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )\r
#define configMAX_PRIORITIES ( 5 )\r
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 512 )\r
-#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 10 * 1024 ) )\r
+#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 8 * 1024 ) )\r
#define configMAX_TASK_NAME_LEN ( 16 )\r
#define configUSE_TRACE_FACILITY 1\r
#define configUSE_16_BIT_TICKS 0\r
--- /dev/null
+/*\r
+ * FreeRTOS Kernel V10.1.1\r
+ * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
+ * this software and associated documentation files (the "Software"), to deal in\r
+ * the Software without restriction, including without limitation the rights to\r
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
+ * the Software, and to permit persons to whom the Software is furnished to do so,\r
+ * subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://aws.amazon.com/freertos\r
+ *\r
+ * 1 tab == 4 spaces!\r
+ */\r
+\r
+ .extern ulRegTest1LoopCounter\r
+ .extern ulRegTest2LoopCounter\r
+\r
+ .global vRegTest1Task\r
+ .global vRegTest2Task\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+vRegTest1Task:\r
+\r
+ /* Fill the core registers with known values. */\r
+ li x5, 0x5\r
+ li x6, 0x6\r
+ li x7, 0x7\r
+ li x8, 0x8\r
+ li x9, 0x9\r
+ li x10, 0xa\r
+ li x11, 0xb\r
+ li x12, 0xc\r
+ li x13, 0xd\r
+ li x14, 0xe\r
+ li x15, 0xf\r
+ li x16, 0x10\r
+ li x17, 0x11\r
+ li x18, 0x12\r
+ li x19, 0x13\r
+ li x20, 0x14\r
+ li x21, 0x15\r
+ li x22, 0x16\r
+ li x23, 0x17\r
+ li x24, 0x18\r
+ li x25, 0x19\r
+ li x26, 0x1a\r
+ li x27, 0x1b\r
+ li x28, 0x1c\r
+ li x29, 0x1d\r
+ li x30, 0x1e\r
+\r
+reg1_loop:\r
+\r
+ /* Check each register still contains the expected known value.\r
+ vRegTest1Implementation uses x31 as the temporary, vRegTest2Implementation\r
+ uses x5 as the temporary. */\r
+ li x31, 0x5\r
+ bne x31, x5, reg1_error_loop\r
+ li x31, 0x6\r
+ bne x31, x6, reg1_error_loop\r
+ li x31, 0x7\r
+ bne x31, x7, reg1_error_loop\r
+ li x31, 0x8\r
+ bne x31, x8, reg1_error_loop\r
+ li x31, 0x9\r
+ bne x31, x9, reg1_error_loop\r
+ li x31, 0xa\r
+ bne x31, x10, reg1_error_loop\r
+ li x31, 0xb\r
+ bne x31, x11, reg1_error_loop\r
+ li x31, 0xc\r
+ bne x31, x12, reg1_error_loop\r
+ li x31, 0xd\r
+ bne x31, x13, reg1_error_loop\r
+ li x31, 0xe\r
+ bne x31, x14, reg1_error_loop\r
+ li x31, 0xf\r
+ bne x31, x15, reg1_error_loop\r
+ li x31, 0x10\r
+ bne x31, x16, reg1_error_loop\r
+ li x31, 0x11\r
+ bne x31, x17, reg1_error_loop\r
+ li x31, 0x12\r
+ bne x31, x18, reg1_error_loop\r
+ li x31, 0x13\r
+ bne x31, x19, reg1_error_loop\r
+ li x31, 0x14\r
+ bne x31, x20, reg1_error_loop\r
+ li x31, 0x15\r
+ bne x31, x21, reg1_error_loop\r
+ li x31, 0x16\r
+ bne x31, x22, reg1_error_loop\r
+ li x31, 0x17\r
+ bne x31, x23, reg1_error_loop\r
+ li x31, 0x18\r
+ bne x31, x24, reg1_error_loop\r
+ li x31, 0x19\r
+ bne x31, x25, reg1_error_loop\r
+ li x31, 0x1a\r
+ bne x31, x26, reg1_error_loop\r
+ li x31, 0x1b\r
+ bne x31, x27, reg1_error_loop\r
+ li x31, 0x1c\r
+ bne x31, x28, reg1_error_loop\r
+ li x31, 0x1d\r
+ bne x31, x29, reg1_error_loop\r
+ li x31, 0x1e\r
+ bne x31, x30, reg1_error_loop\r
+\r
+ /* Everything passed, increment the loop counter. */\r
+ lw x31, ulRegTest1LoopCounterConst\r
+ lw x30, 0(x31)\r
+ addi x30, x30, 1\r
+ sw x30, 0(x31)\r
+\r
+ /* Restore clobbered register reading for next loop. */\r
+ li x30, 0x1e\r
+\r
+ /* Yield to increase code coverage. */\r
+ ecall\r
+\r
+ /* Start again. */\r
+ jal reg1_loop\r
+\r
+reg1_error_loop:\r
+ /* Jump here if a register contains an uxpected value. This stops the loop\r
+ counter being incremented so the check task knows an error was found. */\r
+ jal reg1_error_loop\r
+\r
+ulRegTest1LoopCounterConst: .word ulRegTest1LoopCounter\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+vRegTest2Task:\r
+\r
+ /* Fill the core registers with known values. */\r
+ li x6, 0x61\r
+ li x7, 0x71\r
+ li x8, 0x81\r
+ li x9, 0x91\r
+ li x10, 0xa1\r
+ li x11, 0xb1\r
+ li x12, 0xc1\r
+ li x13, 0xd1\r
+ li x14, 0xe1\r
+ li x15, 0xf1\r
+ li x16, 0x20\r
+ li x17, 0x21\r
+ li x18, 0x22\r
+ li x19, 0x23\r
+ li x20, 0x24\r
+ li x21, 0x25\r
+ li x22, 0x26\r
+ li x23, 0x27\r
+ li x24, 0x28\r
+ li x25, 0x29\r
+ li x26, 0x2a\r
+ li x27, 0x2b\r
+ li x28, 0x2c\r
+ li x29, 0x2d\r
+ li x30, 0x2e\r
+ li x31, 0x2f\r
+\r
+Reg2_loop:\r
+\r
+ /* Check each register still contains the expected known value.\r
+ vRegTest2Implementation uses x5 as the temporary, vRegTest1Implementation\r
+ uses x31 as the temporary. */\r
+ li x5, 0x61\r
+ bne x5, x6, reg2_error_loop\r
+ li x5, 0x71\r
+ bne x5, x7, reg2_error_loop\r
+ li x5, 0x81\r
+ bne x5, x8, reg2_error_loop\r
+ li x5, 0x91\r
+ bne x5, x9, reg2_error_loop\r
+ li x5, 0xa1\r
+ bne x5, x10, reg2_error_loop\r
+ li x5, 0xb1\r
+ bne x5, x11, reg2_error_loop\r
+ li x5, 0xc1\r
+ bne x5, x12, reg2_error_loop\r
+ li x5, 0xd1\r
+ bne x5, x13, reg2_error_loop\r
+ li x5, 0xe1\r
+ bne x5, x14, reg2_error_loop\r
+ li x5, 0xf1\r
+ bne x5, x15, reg2_error_loop\r
+ li x5, 0x20\r
+ bne x5, x16, reg2_error_loop\r
+ li x5, 0x21\r
+ bne x5, x17, reg2_error_loop\r
+ li x5, 0x22\r
+ bne x5, x18, reg2_error_loop\r
+ li x5, 0x23\r
+ bne x5, x19, reg2_error_loop\r
+ li x5, 0x24\r
+ bne x5, x20, reg2_error_loop\r
+ li x5, 0x25\r
+ bne x5, x21, reg2_error_loop\r
+ li x5, 0x26\r
+ bne x5, x22, reg2_error_loop\r
+ li x5, 0x27\r
+ bne x5, x23, reg2_error_loop\r
+ li x5, 0x28\r
+ bne x5, x24, reg2_error_loop\r
+ li x5, 0x29\r
+ bne x5, x25, reg2_error_loop\r
+ li x5, 0x2a\r
+ bne x5, x26, reg2_error_loop\r
+ li x5, 0x2b\r
+ bne x5, x27, reg2_error_loop\r
+ li x5, 0x2c\r
+ bne x5, x28, reg2_error_loop\r
+ li x5, 0x2d\r
+ bne x5, x29, reg2_error_loop\r
+ li x5, 0x2e\r
+ bne x5, x30, reg2_error_loop\r
+ li x5, 0x2f\r
+ bne x5, x31, reg2_error_loop\r
+\r
+ /* Everything passed, increment the loop counter. */\r
+ lw x5, ulRegTest2LoopCounterConst\r
+ lw x6, 0(x5)\r
+ addi x6, x6, 1\r
+ sw x6, 0(x5)\r
+\r
+ /* Restore clobbered register reading for next loop. */\r
+ li x6, 0x61\r
+\r
+ /* Start again. */\r
+ jal Reg2_loop\r
+\r
+reg2_error_loop:\r
+ /* Jump here if a register contains an uxpected value. This stops the loop\r
+ counter being incremented so the check task knows an error was found. */\r
+ jal reg2_error_loop\r
+\r
+ulRegTest2LoopCounterConst: .word ulRegTest2LoopCounter\r
+\r
+\r
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );\r
\r
\r
-void reset_demo (void);\r
\r
-// Structures for registering different interrupt handlers\r
-// for different parts of the application.\r
-typedef void (*function_ptr_t) (void);\r
+void vRegTest1Task( void *pvParameters );\r
+void vRegTest2Task( void *pvParameters );\r
\r
-void no_interrupt_handler (void) {};\r
-\r
-function_ptr_t g_ext_interrupt_handlers[PLIC_NUM_INTERRUPTS];\r
-\r
-\r
-// Instance data for the PLIC.\r
\r
+const char * const pcStartMessage = "FreeRTOS demo\r\n";\r
+volatile uint32_t ulRegTest1LoopCounter = 0, ulRegTest2LoopCounter = 0;\r
+static void prvCheckTask( void *pvParameters );\r
plic_instance_t g_plic;\r
+uint32_t bitbang_mask = 0;\r
\r
-\r
-/*Entry Point for PLIC Interrupt Handler*/\r
-void handle_m_ext_interrupt(){\r
- plic_source int_num = PLIC_claim_interrupt(&g_plic);\r
- if ((int_num >=1 ) && (int_num < PLIC_NUM_INTERRUPTS)) {\r
- g_ext_interrupt_handlers[int_num]();\r
- }\r
- else {\r
- exit(1 + (uintptr_t) int_num);\r
- }\r
- PLIC_complete_interrupt(&g_plic, int_num);\r
-}\r
-\r
-\r
-/*Entry Point for Machine Timer Interrupt Handler*/\r
-void handle_m_time_interrupt(){\r
-\r
- clear_csr(mie, MIP_MTIP);\r
-\r
- // Reset the timer for 3s in the future.\r
- // This also clears the existing timer interrupt.\r
-\r
- volatile uint64_t * mtime = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIME);\r
- volatile uint64_t * mtimecmp = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIMECMP);\r
- uint64_t now = *mtime;\r
- uint64_t then = now + 2 * RTC_FREQ;\r
- *mtimecmp = then;\r
-\r
- // read the current value of the LEDS and invert them.\r
- uint32_t leds = GPIO_REG(GPIO_OUTPUT_VAL);\r
-\r
- GPIO_REG(GPIO_OUTPUT_VAL) ^= ((0x1 << RED_LED_OFFSET) |\r
- (0x1 << GREEN_LED_OFFSET) |\r
- (0x1 << BLUE_LED_OFFSET));\r
- \r
- // Re-enable the timer interrupt.\r
- set_csr(mie, MIP_MTIP);\r
-\r
-}\r
-\r
-\r
-const char * instructions_msg = " \\r
-\n\\r
- SIFIVE, INC.\n\\r
-\n\\r
- 5555555555555555555555555\n\\r
- 5555 5555\n\\r
- 5555 5555\n\\r
- 5555 5555\n\\r
- 5555 5555555555555555555555\n\\r
- 5555 555555555555555555555555\n\\r
- 5555 5555\n\\r
- 5555 5555\n\\r
- 5555 5555\n\\r
-5555555555555555555555555555 55555\n\\r
- 55555 555555555 55555\n\\r
- 55555 55555 55555\n\\r
- 55555 5 55555\n\\r
- 55555 55555\n\\r
- 55555 55555\n\\r
- 55555 55555\n\\r
- 55555 55555\n\\r
- 55555 55555\n\\r
- 555555555\n\\r
- 55555\n\\r
- 5\n\\r
-\n\\r
-SiFive E-Series Software Development Kit 'demo_gpio' program.\n\\r
-Every 2 second, the Timer Interrupt will invert the LEDs.\n\\r
-(Arty Dev Kit Only): Press Buttons 0, 1, 2 to Set the LEDs.\n\\r
-Pin 19 (HiFive1) or A5 (Arty Dev Kit) is being bit-banged\n\\r
-for GPIO speed demonstration.\n\\r
-\n\\r
- ";\r
-\r
-void print_instructions() {\r
-\r
- write (STDOUT_FILENO, instructions_msg, strlen(instructions_msg));\r
-\r
-}\r
-\r
-#ifdef HAS_BOARD_BUTTONS\r
-void button_0_handler(void) {\r
-\r
- // Red LED on\r
- GPIO_REG(GPIO_OUTPUT_VAL) |= (0x1 << RED_LED_OFFSET);\r
-\r
- // Clear the GPIO Pending interrupt by writing 1.\r
- GPIO_REG(GPIO_RISE_IP) = (0x1 << BUTTON_0_OFFSET);\r
-\r
-};\r
-\r
-void button_1_handler(void) {\r
-\r
- // Green LED On\r
- GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << GREEN_LED_OFFSET);\r
-\r
- // Clear the GPIO Pending interrupt by writing 1.\r
- GPIO_REG(GPIO_RISE_IP) = (0x1 << BUTTON_1_OFFSET);\r
-\r
-};\r
-\r
-\r
-void button_2_handler(void) {\r
-\r
- // Blue LED On\r
- GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << BLUE_LED_OFFSET);\r
-\r
- GPIO_REG(GPIO_RISE_IP) = (0x1 << BUTTON_2_OFFSET);\r
-\r
-};\r
-#endif\r
-\r
-void reset_demo (){\r
-\r
- // Disable the machine & timer interrupts until setup is done.\r
-\r
- clear_csr(mie, MIP_MEIP);\r
- clear_csr(mie, MIP_MTIP);\r
-\r
- for (int ii = 0; ii < PLIC_NUM_INTERRUPTS; ii ++){\r
- g_ext_interrupt_handlers[ii] = no_interrupt_handler;\r
- }\r
-\r
-#ifdef HAS_BOARD_BUTTONS\r
- g_ext_interrupt_handlers[INT_DEVICE_BUTTON_0] = button_0_handler;\r
- g_ext_interrupt_handlers[INT_DEVICE_BUTTON_1] = button_1_handler;\r
- g_ext_interrupt_handlers[INT_DEVICE_BUTTON_2] = button_2_handler;\r
-#endif\r
-\r
- print_instructions();\r
-\r
-#ifdef HAS_BOARD_BUTTONS\r
-\r
- // Have to enable the interrupt both at the GPIO level,\r
- // and at the PLIC level.\r
- PLIC_enable_interrupt (&g_plic, INT_DEVICE_BUTTON_0);\r
- PLIC_enable_interrupt (&g_plic, INT_DEVICE_BUTTON_1);\r
- PLIC_enable_interrupt (&g_plic, INT_DEVICE_BUTTON_2);\r
-\r
- // Priority must be set > 0 to trigger the interrupt.\r
- PLIC_set_priority(&g_plic, INT_DEVICE_BUTTON_0, 1);\r
- PLIC_set_priority(&g_plic, INT_DEVICE_BUTTON_1, 1);\r
- PLIC_set_priority(&g_plic, INT_DEVICE_BUTTON_2, 1);\r
-\r
- GPIO_REG(GPIO_RISE_IE) |= (1 << BUTTON_0_OFFSET);\r
- GPIO_REG(GPIO_RISE_IE) |= (1 << BUTTON_1_OFFSET);\r
- GPIO_REG(GPIO_RISE_IE) |= (1 << BUTTON_2_OFFSET);\r
-\r
-#endif\r
-\r
- // Set the machine timer to go off in 3 seconds.\r
- // The\r
- volatile uint64_t * mtime = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIME);\r
- volatile uint64_t * mtimecmp = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIMECMP);\r
- uint64_t now = *mtime;\r
- uint64_t then = now + 2*RTC_FREQ;\r
- *mtimecmp = then;\r
-\r
- // Enable the Machine-External bit in MIE\r
- set_csr(mie, MIP_MEIP);\r
-\r
- // Enable the Machine-Timer bit in MIE\r
- set_csr(mie, MIP_MTIP);\r
-\r
- // Enable interrupts in general.\r
- set_csr(mstatus, MSTATUS_MIE);\r
+int main( void )\r
+{\r
+ #ifdef HAS_BOARD_BUTTONS\r
+ GPIO_REG(GPIO_OUTPUT_EN) &= ~((0x1 << BUTTON_0_OFFSET) | (0x1 << BUTTON_1_OFFSET) | (0x1 << BUTTON_2_OFFSET));\r
+ GPIO_REG(GPIO_PULLUP_EN) &= ~((0x1 << BUTTON_0_OFFSET) | (0x1 << BUTTON_1_OFFSET) | (0x1 << BUTTON_2_OFFSET));\r
+ GPIO_REG(GPIO_INPUT_EN) |= ((0x1 << BUTTON_0_OFFSET) | (0x1 << BUTTON_1_OFFSET) | (0x1 << BUTTON_2_OFFSET));\r
+ #endif\r
+\r
+ GPIO_REG(GPIO_INPUT_EN) &= ~((0x1<< RED_LED_OFFSET) | (0x1<< GREEN_LED_OFFSET) | (0x1 << BLUE_LED_OFFSET)) ;\r
+ GPIO_REG(GPIO_OUTPUT_EN) |= ((0x1<< RED_LED_OFFSET)| (0x1<< GREEN_LED_OFFSET) | (0x1 << BLUE_LED_OFFSET)) ;\r
+ GPIO_REG(GPIO_OUTPUT_VAL) |= (0x1 << BLUE_LED_OFFSET) ;\r
+ GPIO_REG(GPIO_OUTPUT_VAL) &= ~((0x1<< RED_LED_OFFSET) | (0x1<< GREEN_LED_OFFSET)) ;\r
+\r
+ /* For Bit-banging with Atomics demo. */\r
+ #ifdef _SIFIVE_HIFIVE1_H\r
+ bitbang_mask = (1 << PIN_19_OFFSET);\r
+ #else\r
+ #ifdef _SIFIVE_COREPLEXIP_ARTY_H\r
+ bitbang_mask = (0x1 << JA_0_OFFSET);\r
+ #endif\r
+ #endif\r
+\r
+ GPIO_REG(GPIO_OUTPUT_EN) |= bitbang_mask;\r
+\r
+// xTaskCreate( vRegTest1Task, "RegTest1", 1000, NULL, tskIDLE_PRIORITY, NULL );\r
+// xTaskCreate( vRegTest2Task, "RegTest2", 1000, NULL, tskIDLE_PRIORITY, NULL );\r
+ xTaskCreate( prvCheckTask, "Check", 1000, NULL, configMAX_PRIORITIES - 1, NULL );\r
+\r
+ vTaskStartScheduler();\r
}\r
+/*-----------------------------------------------------------*/\r
\r
-int main(int argc, char **argv)\r
+static void prvCheckTask( void *pvParameters )\r
{\r
- // Set up the GPIOs such that the LED GPIO\r
- // can be used as both Inputs and Outputs.\r
- \r
-\r
-#ifdef HAS_BOARD_BUTTONS\r
- GPIO_REG(GPIO_OUTPUT_EN) &= ~((0x1 << BUTTON_0_OFFSET) | (0x1 << BUTTON_1_OFFSET) | (0x1 << BUTTON_2_OFFSET));\r
- GPIO_REG(GPIO_PULLUP_EN) &= ~((0x1 << BUTTON_0_OFFSET) | (0x1 << BUTTON_1_OFFSET) | (0x1 << BUTTON_2_OFFSET));\r
- GPIO_REG(GPIO_INPUT_EN) |= ((0x1 << BUTTON_0_OFFSET) | (0x1 << BUTTON_1_OFFSET) | (0x1 << BUTTON_2_OFFSET));\r
-#endif\r
-\r
- GPIO_REG(GPIO_INPUT_EN) &= ~((0x1<< RED_LED_OFFSET) | (0x1<< GREEN_LED_OFFSET) | (0x1 << BLUE_LED_OFFSET)) ;\r
- GPIO_REG(GPIO_OUTPUT_EN) |= ((0x1<< RED_LED_OFFSET)| (0x1<< GREEN_LED_OFFSET) | (0x1 << BLUE_LED_OFFSET)) ;\r
- GPIO_REG(GPIO_OUTPUT_VAL) |= (0x1 << BLUE_LED_OFFSET) ;\r
- GPIO_REG(GPIO_OUTPUT_VAL) &= ~((0x1<< RED_LED_OFFSET) | (0x1<< GREEN_LED_OFFSET)) ;\r
-\r
- \r
- // For Bit-banging with Atomics demo.\r
- \r
- uint32_t bitbang_mask = 0;\r
-#ifdef _SIFIVE_HIFIVE1_H\r
- bitbang_mask = (1 << PIN_19_OFFSET);\r
-#else\r
-#ifdef _SIFIVE_COREPLEXIP_ARTY_H\r
- bitbang_mask = (0x1 << JA_0_OFFSET);\r
-#endif\r
+const char *pcMessage = "PASS\r\n";\r
+const TickType_t xCheckPeriod = pdMS_TO_TICKS( 3000UL );\r
+uint32_t ulLastRegTest1LoopCounter = 0, ulLastRegTest2LoopCounter = 0;\r
+volatile uintptr_t mstatus;\r
+\r
+volatile uint32_t ulx;\r
+__asm volatile ("csrr %0, mstatus" : "=r"(mstatus));\r
+portENABLE_INTERRUPTS();\r
+__asm volatile ("csrr %0, mstatus" : "=r"(mstatus));\r
+for( ;; )\r
+{\r
+// for( ulx = 0; ulx < 0xffff; ulx++ ) __asm volatile( "NOP" );\r
+// vPortSetupTimerInterrupt();\r
+ vTaskDelay( xCheckPeriod );\r
+ write( STDOUT_FILENO, "Blip\r\n", strlen( "Blip\r\n" ) );\r
+}\r
+#if 0\r
+ for( ;; )\r
+ {\r
+ vTaskDelay( xCheckPeriod );\r
+\r
+ if( ulLastRegTest1LoopCounter == ulRegTest1LoopCounter )\r
+ {\r
+ /* The RegTest1 loop counter is no longer incrementing, indicating\r
+ the task failed its self check. */\r
+ pcMessage = "FAIL: RegTest1\r\n";\r
+ }\r
+ else\r
+ {\r
+ ulLastRegTest1LoopCounter = ulRegTest1LoopCounter;\r
+ }\r
+\r
+ if( ulLastRegTest2LoopCounter == ulRegTest2LoopCounter )\r
+ {\r
+ /* The RegTest1 loop counter is no longer incrementing, indicating\r
+ the task failed its self check. */\r
+ pcMessage = "FAIL: RegTest2\r\n";\r
+ }\r
+ else\r
+ {\r
+ ulLastRegTest2LoopCounter = ulRegTest2LoopCounter;\r
+ }\r
+\r
+ vUARTWriteString( pcMessage );\r
+ }\r
#endif\r
-\r
- GPIO_REG(GPIO_OUTPUT_EN) |= bitbang_mask;\r
- \r
- /**************************************************************************\r
- * Set up the PLIC\r
- *\r
- *************************************************************************/\r
- PLIC_init(&g_plic,\r
- PLIC_CTRL_ADDR,\r
- PLIC_NUM_INTERRUPTS,\r
- PLIC_NUM_PRIORITIES);\r
-\r
- reset_demo();\r
-\r
- /**************************************************************************\r
- * Demonstrate fast GPIO bit-banging.\r
- * One can bang it faster than this if you know\r
- * the entire OUTPUT_VAL that you want to write, but \r
- * Atomics give a quick way to control a single bit.\r
- *************************************************************************/\r
- // For Bit-banging with Atomics demo.\r
- \r
- while (1){\r
- atomic_fetch_xor_explicit(&GPIO_REG(GPIO_OUTPUT_VAL), bitbang_mask, memory_order_relaxed);\r
- }\r
-\r
- return 0;\r
-\r
}\r
+/*-----------------------------------------------------------*/\r
\r
void vApplicationMallocFailedHook( void )\r
{\r
}\r
/*-----------------------------------------------------------*/\r
\r
+#define mainINTERRUPT_BIT_SET 0x80000000UL\r
+#define mainENVIRONMENT_CALL 11UL\r
+#define mainEXTERNAL_INTERRRUPT ( mainINTERRUPT_BIT_SET | 11UL )\r
+#define mainTIMER_INTERRUPT ( mainINTERRUPT_BIT_SET | 7UL )\r
+#define mainSOFTWARE_INTERRUPT ( mainINTERRUPT_BIT_SET | 3UL )\r
\r
+extern void Timer_IRQHandler( void );\r
\r
-void trap_entry( void )\r
+uint32_t ulPortTrapHandler( uint32_t mcause, uint32_t mepc )\r
{\r
-#warning Dummy until kernel code is incldued.\r
+ if( mcause == mainENVIRONMENT_CALL )\r
+ {\r
+ vTaskSwitchContext();\r
+\r
+ /* Ensure not to return to the instruction that generated the exception. */\r
+ mepc += 4;\r
+ }\r
+ else if( mcause == mainEXTERNAL_INTERRRUPT )\r
+ {\r
+ for( ;; );\r
+ }\r
+ else if( mcause == mainTIMER_INTERRUPT )\r
+ {\r
+ Timer_IRQHandler();\r
+ }\r
+ else if( mcause == mainSOFTWARE_INTERRUPT )\r
+ {\r
+ for( ;; );\r
+ }\r
+\r
+ return mepc;\r
}\r
-\r
-\r
* memory to be allocated dynamically.\r
*\r
* @return If neither pxStackBuffer or pxTaskBuffer are NULL, then the task will\r
- * be created and pdPASS is returned. If either pxStackBuffer or pxTaskBuffer\r
- * are NULL then the task will not be created and\r
- * errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY is returned.\r
+ * be created and a handle to the created task is returned. If either\r
+ * pxStackBuffer or pxTaskBuffer are NULL then the task will not be created and\r
+ * NULL is returned.\r
*\r
* Example usage:\r
<pre>\r
/* Used to program the machine timer compare register. */\r
static uint64_t ullNextTime = 0ULL;\r
static const uint64_t ullTimerIncrementsForOneTick = ( uint64_t ) ( configCPU_CLOCK_HZ / configTICK_RATE_HZ );\r
-static volatile uint64_t * const pullMachineTimerCompareRegister = ( volatile uint64_t * const ) ( configCTRL_BASE + 0x4000 );\r
+static volatile uint64_t * const pullMachineTimerCompareRegister = ( volatile uint64_t * const ) ( configCLINT_BASE_ADDRESS + 0x4000 );\r
\r
/*-----------------------------------------------------------*/\r
\r
void vPortSetupTimerInterrupt( void )\r
{\r
uint32_t ulCurrentTimeHigh, ulCurrentTimeLow;\r
-volatile uint32_t * const pulTimeHigh = ( volatile uint32_t * const ) ( configCTRL_BASE + 0xBFFC );\r
-volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) ( configCTRL_BASE + 0xBFF8 );\r
+volatile uint32_t * const pulTimeHigh = ( volatile uint32_t * const ) ( configCLINT_BASE_ADDRESS + 0xBFFC );\r
+volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) ( configCLINT_BASE_ADDRESS + 0xBFF8 );\r
\r
do\r
{\r
\r
void Software_IRQHandler( void )\r
{\r
-volatile uint32_t * const ulSoftInterrupt = ( uint32_t * ) configCTRL_BASE;\r
+volatile uint32_t * const ulSoftInterrupt = ( uint32_t * ) configCLINT_BASE_ADDRESS;\r
\r
vTaskSwitchContext();\r
\r
/* Clear software interrupt. */\r
- *( ( uint32_t * ) configCTRL_BASE ) &= 0x08UL;\r
+ *( ( uint32_t * ) configCLINT_BASE_ADDRESS ) &= 0x08UL;\r
}\r
/*-----------------------------------------------------------*/\r
\r
should be executing. */\r
return pdFAIL;\r
}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortEndScheduler( void )\r
+{\r
+ /* Not implemented. */\r
+ for( ;; );\r
+}\r
+\r
\r
\r
\r
.global xPortStartFirstTask\r
.global vPortTrapHandler\r
.extern pxCurrentTCB\r
-.extern handle_trap\r
+.extern ulPortTrapHandler\r
\r
/*-----------------------------------------------------------*/\r
\r
.align 8\r
xPortStartFirstTask:\r
\r
+ la t0, vPortTrapHandler\r
+ csrw mtvec, t0\r
+\r
lw sp, pxCurrentTCB /* Load pxCurrentTCB. */\r
lw sp, 0( sp ) /* Read sp from first TCB member. */\r
\r
csrr a1, mepc\r
mv a2, sp\r
/*_RB_ Does stack need aligning here? */\r
- jal handle_trap\r
+ jal ulPortTrapHandler\r
csrw mepc, a0\r
/* Save exception return address. */\r
sw a0, 0( sp )\r
\r
\r
/* Scheduler utilities. */\r
-#define portYIELD() __asm volatile( "ecall" ); // software interrupt alternative *( ( uint32_t * ) configCTRL_BASE ) |= 0x08UL\r
+#define portYIELD() __asm volatile( "ecall" ); // software interrupt alternative *( ( uint32_t * ) configCLINT_BASE_ADDRESS ) |= 0x08UL\r
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYield()\r
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )\r
/*-----------------------------------------------------------*/\r
\r
#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
{\r
- #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE\r
- portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime );\r
- #else\r
- ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();\r
- #endif\r
+ #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE\r
+ portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime );\r
+ #else\r
+ ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();\r
+ #endif\r
\r
- /* Add the amount of time the task has been running to the\r
- accumulated time so far. The time the task started running was\r
- stored in ulTaskSwitchedInTime. Note that there is no overflow\r
- protection here so count values are only valid until the timer\r
- overflows. The guard against negative values is to protect\r
- against suspect run time stat counter implementations - which\r
- are provided by the application, not the kernel. */\r
- if( ulTotalRunTime > ulTaskSwitchedInTime )\r
- {\r
- pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime );\r
- }\r
- else\r
- {\r
- mtCOVERAGE_TEST_MARKER();\r
- }\r
- ulTaskSwitchedInTime = ulTotalRunTime;\r
+ /* Add the amount of time the task has been running to the\r
+ accumulated time so far. The time the task started running was\r
+ stored in ulTaskSwitchedInTime. Note that there is no overflow\r
+ protection here so count values are only valid until the timer\r
+ overflows. The guard against negative values is to protect\r
+ against suspect run time stat counter implementations - which\r
+ are provided by the application, not the kernel. */\r
+ if( ulTotalRunTime > ulTaskSwitchedInTime )\r
+ {\r
+ pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime );\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+ ulTaskSwitchedInTime = ulTotalRunTime;\r
}\r
#endif /* configGENERATE_RUN_TIME_STATS */\r
\r