]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Demo/RISC-V-Qemu-sifive_e-FreedomStudio/main.c
Recreate the RISC-V-Qemu demo using Vanilla Eclipse in place of Freedom Studio as...
[freertos] / FreeRTOS / Demo / RISC-V-Qemu-sifive_e-FreedomStudio / main.c
index 649218528de93fa4ec8ef39760412297bf9612a5..07912293e2e09061bc8bc1ea630e3d169cc6cc5e 100644 (file)
-// See LICENSE for license details.\r
+/*\r
+ * FreeRTOS Kernel V10.2.1\r
+ * Copyright (C) 2019 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
+/* FreeRTOS kernel includes. */\r
 #include <FreeRTOS.h>\r
 #include <task.h>\r
 \r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include "platform.h"\r
-#include <string.h>\r
-#include "plic/plic_driver.h"\r
-#include "encoding.h"\r
-#include <unistd.h>\r
-#include "stdatomic.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
+ * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting (defined in this file) is used to\r
+ * select between the two.  The simply blinky demo is implemented and described\r
+ * in main_blinky.c.  The more comprehensive test and demo application is\r
+ * implemented and described in main_full.c.\r
+ *\r
+ * This file implements the code that is not demo specific, including the\r
+ * hardware setup and standard FreeRTOS hook functions.\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
+ * NOTE 1:\r
+ *\r
+ * This project has only been tested in the QEMU emulation of the HiFive board\r
+ * from SiFive.\r
+ *\r
+ * Start QEMU using the following command line:\r
+ *\r
+ * [your_path_1]\qemu-system-riscv32 -kernel [your_path_2]\FreeRTOS\Demo\RISC-V-Qemu-sifive_e-FreedomStudio\Debug\RTOSDemo.elf -S -s -machine sifive_e\r
+ *\r
+ * Where [your_path_1] must be replaced with the correct path to your QEMU\r
+ * installation and the elf file generated by this project respectively.\r
+ *\r
+ *\r
+ * NOTE 2:\r
+ *\r
+ * Start GDB using the following command line (this can be entered in the\r
+ * Eclipse Debug Launch Configuration dialogue):\r
+ *\r
+ * riscv64-unknown-elf-gdb.exe -iex "set mem inaccessible-by-default off" -iex "set arch riscv:rv32" -iex "set riscv use_compressed_breakpoint off"\r
+ *\r
+ *\r
+ * Note 3:\r
+ *\r
+ * Status information is sent to the QEMU serial console.\r
+ */\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
 \r
 /*\r
- * FreeRTOS hook for when malloc fails, enable in FreeRTOSConfig.\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
  */\r
-void vApplicationMallocFailedHook( void );\r
+#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1\r
+       extern void main_blinky( void );\r
+#else\r
+       extern void main_full( void );\r
+#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */\r
 \r
 /*\r
- * FreeRTOS hook for when FreeRtos is idling, enable in FreeRTOSConfig.\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
 /*\r
- * FreeRTOS hook for when a stack overflow occurs, enable in FreeRTOSConfig.\r
+ * Very simply polling write to the UART.  The full demo only writes single\r
+ * characters at a time so as not to disrupt the timing of the test and demo\r
+ * tasks.\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
-\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
-plic_instance_t g_plic;\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
+void vSendString( const char * pcString );\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
-}\r
+/*-----------------------------------------------------------*/\r
 \r
-int main(int argc, char **argv)\r
+int main( void )\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
-#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
+       vSendString( "Starting" );\r
+\r
+       /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top\r
+       of this file. */\r
+       #if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )\r
+       {\r
+               main_blinky();\r
+       }\r
+       #else\r
+       {\r
+               main_full();\r
+       }\r
+       #endif\r
 }\r
+/*-----------------------------------------------------------*/\r
 \r
 void vApplicationMallocFailedHook( void )\r
 {\r
@@ -316,11 +165,37 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+void vApplicationTickHook( void )\r
+{\r
+       /* The tests in the full demo expect some interaction with interrupts. */\r
+       #if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY != 1 )\r
+       {\r
+               extern void vFullDemoTickHook( void );\r
+               vFullDemoTickHook();\r
+       }\r
+       #endif\r
+}\r
+/*-----------------------------------------------------------*/\r
 \r
-\r
-void trap_entry( void )\r
+void vAssertCalled( void )\r
 {\r
-#warning Dummy until kernel code is incldued.\r
+volatile uint32_t ulSetTo1ToExitFunction = 0;\r
+\r
+       taskDISABLE_INTERRUPTS();\r
+       while( ulSetTo1ToExitFunction != 1 )\r
+       {\r
+               __asm volatile( "NOP" );\r
+       }\r
 }\r
+/*-----------------------------------------------------------*/\r
 \r
+void vSendString( const char * pcString )\r
+{\r
+       while( *pcString != 0x00 )\r
+       {\r
+               while( UART0_REG( UART_REG_TXFIFO ) & 0x80000000 );\r
+               UART0_REG( UART_REG_TXFIFO ) = *pcString;\r
+               *pcString++;\r
+       }\r
+}\r
 \r