Starting point for IAR RISC-V project created some time ago - checking in now so it can be completed - currently work in progress.

pull/4/head
Richard Barry 6 years ago
parent 5352cb4f45
commit 72af51cd86

@ -0,0 +1,101 @@
/*
* FreeRTOS Kernel V10.2.1
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*
* See http://www.freertos.org/a00110.html.
*----------------------------------------------------------*/
#define configISR_STACK_SIZE_WORDS ( 200 )
#define configCLINT_BASE_ADDRESS 0x2000000
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 1
#define configCPU_CLOCK_HZ ( ( uint32_t ) ( 32768 ) )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES ( 5 )
#define configMINIMAL_STACK_SIZE ( ( uint32_t ) 170 ) /* Can be as low as 60 but some of the demo tasks that use this constant require it to be higher. */
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 54 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 0
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 1
#define configGENERATE_RUN_TIME_STATS 0
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Software timer definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define configTIMER_QUEUE_LENGTH 4
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE )
/* Task priorities. Allow these to be overridden. */
#ifndef uartPRIMARY_PRIORITY
#define uartPRIMARY_PRIORITY ( configMAX_PRIORITIES - 3 )
#endif
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xTaskAbortDelay 1
#define INCLUDE_xTaskGetHandle 1
#define INCLUDE_xSemaphoreGetMutexHolder 1
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); __asm volatile( "ebreak" ); for( ;; ); }
#endif /* FREERTOS_CONFIG_H */

File diff suppressed because it is too large Load Diff

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<workspace>
<project>
<path>$WS_DIR$\RTOSDemo.ewp</path>
</project>
<batchBuild />
</workspace>

@ -0,0 +1,172 @@
/* Copyright 2018 SiFive, Inc */
/* SPDX-License-Identifier: Apache-2.0 */
#include <metal/machine/platform.h>
#ifdef METAL_RISCV_PLIC0
#include <metal/io.h>
#include <metal/shutdown.h>
#include <metal/drivers/riscv_plic0.h>
#include <metal/machine.h>
unsigned int __metal_plic0_claim_interrupt (struct __metal_driver_riscv_plic0 *plic)
{
unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)plic);
return __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base +
METAL_RISCV_PLIC0_CLAIM));
}
void __metal_plic0_complete_interrupt(struct __metal_driver_riscv_plic0 *plic,
unsigned int id)
{
unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)plic);
__METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base +
METAL_RISCV_PLIC0_CLAIM)) = id;
}
void __metal_plic0_set_threshold(struct __metal_driver_riscv_plic0 *plic,
unsigned int threshold)
{
unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)plic);
__METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base +
METAL_RISCV_PLIC0_THRESHOLD)) = threshold;
}
void __metal_plic0_set_priority(struct __metal_driver_riscv_plic0 *plic,
int id, unsigned int priority)
{
unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)plic);
int max_priority = __metal_driver_sifive_plic0_max_priority((struct metal_interrupt *)plic);
if ( (max_priority) && (priority < max_priority) ) {
__METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base +
METAL_RISCV_PLIC0_PRIORITY_BASE +
(id << METAL_PLIC_SOURCE_PRIORITY_SHIFT))) = priority;
}
}
void __metal_plic0_enable(struct __metal_driver_riscv_plic0 *plic, int id, int enable)
{
unsigned int current;
unsigned long hartid = __metal_myhart_id();
unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)plic);
current = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base +
METAL_RISCV_PLIC0_ENABLE_BASE +
(id >> METAL_PLIC_SOURCE_SHIFT) * 4));
__METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base +
METAL_RISCV_PLIC0_ENABLE_BASE +
((id >> METAL_PLIC_SOURCE_SHIFT) * 4))) =
enable ? (current | (1 << (id & METAL_PLIC_SOURCE_MASK)))
: (current & ~(1 << (id & METAL_PLIC_SOURCE_MASK)));
}
void __metal_plic0_default_handler (int id, void *priv) {
metal_shutdown(300);
}
void __metal_plic0_handler (int id, void *priv)
{
struct __metal_driver_riscv_plic0 *plic = priv;
unsigned int idx = __metal_plic0_claim_interrupt(plic);
int num_interrupts = __metal_driver_sifive_plic0_num_interrupts((struct metal_interrupt *)plic);
if ( (idx < num_interrupts) && (plic->metal_exint_table[idx]) ) {
plic->metal_exint_table[idx](idx,
plic->metal_exdata_table[idx].exint_data);
}
__metal_plic0_complete_interrupt(plic, idx);
}
void __metal_driver_riscv_plic0_init (struct metal_interrupt *controller)
{
struct __metal_driver_riscv_plic0 *plic = (void *)(controller);
if ( !plic->init_done ) {
int num_interrupts, line;
struct metal_interrupt *intc;
for(int parent = 0; parent < __METAL_PLIC_NUM_PARENTS; parent++) {
num_interrupts = __metal_driver_sifive_plic0_num_interrupts(controller);
intc = __metal_driver_sifive_plic0_interrupt_parents(controller, parent);
line = __metal_driver_sifive_plic0_interrupt_lines(controller, parent);
/* Initialize ist parent controller, aka cpu_intc. */
intc->vtable->interrupt_init(intc);
for (int i = 0; i < num_interrupts; i++) {
__metal_plic0_enable(plic, i, METAL_DISABLE);
__metal_plic0_set_priority(plic, i, 0);
plic->metal_exint_table[i] = NULL;
plic->metal_exdata_table[i].sub_int = NULL;
plic->metal_exdata_table[i].exint_data = NULL;
}
__metal_plic0_set_threshold(plic, 0);
/* Register plic (ext) interrupt with with parent controller */
intc->vtable->interrupt_register(intc, line, NULL, plic);
/* Register plic handler for dispatching its device interrupts */
intc->vtable->interrupt_register(intc, line, __metal_plic0_handler, plic);
/* Enable plic (ext) interrupt with with parent controller */
intc->vtable->interrupt_enable(intc, line);
}
plic->init_done = 1;
}
}
int __metal_driver_riscv_plic0_register (struct metal_interrupt *controller,
int id, metal_interrupt_handler_t isr,
void *priv)
{
struct __metal_driver_riscv_plic0 *plic = (void *)(controller);
if (id >= __metal_driver_sifive_plic0_num_interrupts(controller)) {
return -1;
}
if (isr) {
__metal_plic0_set_priority(plic ,id, 2);
plic->metal_exint_table[id] = isr;
plic->metal_exdata_table[id].exint_data = priv;
} else {
__metal_plic0_set_priority(plic, id, 1);
plic->metal_exint_table[id] = __metal_plic0_default_handler;
plic->metal_exdata_table[id].sub_int = priv;
}
return 0;
}
int __metal_driver_riscv_plic0_enable (struct metal_interrupt *controller, int id)
{
struct __metal_driver_riscv_plic0 *plic = (void *)(controller);
if (id >= __metal_driver_sifive_plic0_num_interrupts(controller)) {
return -1;
}
__metal_plic0_enable(plic, id, METAL_ENABLE);
return 0;
}
int __metal_driver_riscv_plic0_disable (struct metal_interrupt *controller, int id)
{
struct __metal_driver_riscv_plic0 *plic = (void *)(controller);
if (id >= __metal_driver_sifive_plic0_num_interrupts(controller)) {
return -1;
}
__metal_plic0_enable(plic, id, METAL_DISABLE);
return 0;
}
__METAL_DEFINE_VTABLE(__metal_driver_vtable_riscv_plic0) = {
.plic_vtable.interrupt_init = __metal_driver_riscv_plic0_init,
.plic_vtable.interrupt_register = __metal_driver_riscv_plic0_register,
.plic_vtable.interrupt_enable = __metal_driver_riscv_plic0_enable,
.plic_vtable.interrupt_disable = __metal_driver_riscv_plic0_disable,
};
#endif /* METAL_RISCV_PLIC0 */

@ -0,0 +1,151 @@
/* Copyright 2018 SiFive, Inc */
/* SPDX-License-Identifier: Apache-2.0 */
#include <metal/machine/platform.h>
#ifdef METAL_SIFIVE_UART0
#include <metal/drivers/sifive_uart0.h>
#include <metal/machine.h>
/* TXDATA Fields */
#define UART_TXEN (1 << 0)
#define UART_TXFULL (1 << 31)
/* RXDATA Fields */
#define UART_RXEN (1 << 0)
#define UART_RXEMPTY (1 << 31)
/* TXCTRL Fields */
#define UART_NSTOP (1 << 1)
#define UART_TXCNT(count) ((0x7 & count) << 16)
/* IP Fields */
#define UART_TXWM (1 << 0)
#define UART_REG(offset) (((unsigned long)control_base + offset))
#define UART_REGB(offset) (__METAL_ACCESS_ONCE((__metal_io_u8 *)UART_REG(offset)))
#define UART_REGW(offset) (__METAL_ACCESS_ONCE((__metal_io_u32 *)UART_REG(offset)))
struct metal_interrupt *
__metal_driver_sifive_uart0_interrupt_controller(struct metal_uart *uart)
{
return __metal_driver_sifive_uart0_interrupt_parent(uart);
}
int __metal_driver_sifive_uart0_get_interrupt_id(struct metal_uart *uart)
{
return (__metal_driver_sifive_uart0_interrupt_line(uart) + METAL_INTERRUPT_ID_GL0);
}
int __metal_driver_sifive_uart0_putc(struct metal_uart *uart, unsigned char c)
{
long control_base = __metal_driver_sifive_uart0_control_base(uart);
while ((UART_REGW(METAL_SIFIVE_UART0_TXDATA) & UART_TXFULL) != 0) { }
UART_REGW(METAL_SIFIVE_UART0_TXDATA) = c;
return 0;
}
int __metal_driver_sifive_uart0_getc(struct metal_uart *uart, unsigned char *c)
{
uint32_t ch = UART_RXEMPTY;
long control_base = __metal_driver_sifive_uart0_control_base(uart);
while (ch & UART_RXEMPTY) {
ch = UART_REGW(METAL_SIFIVE_UART0_RXDATA);
}
*c = ch & 0xff;
return 0;
}
int __metal_driver_sifive_uart0_get_baud_rate(struct metal_uart *guart)
{
struct __metal_driver_sifive_uart0 *uart = (void *)guart;
return uart->baud_rate;
}
int __metal_driver_sifive_uart0_set_baud_rate(struct metal_uart *guart, int baud_rate)
{
struct __metal_driver_sifive_uart0 *uart = (void *)guart;
long control_base = __metal_driver_sifive_uart0_control_base(guart);
struct metal_clock *clock = __metal_driver_sifive_uart0_clock(guart);
uart->baud_rate = baud_rate;
if (clock != NULL) {
long clock_rate = clock->vtable->get_rate_hz(clock);
UART_REGW(METAL_SIFIVE_UART0_DIV) = clock_rate / baud_rate - 1;
UART_REGW(METAL_SIFIVE_UART0_TXCTRL) |= UART_TXEN;
UART_REGW(METAL_SIFIVE_UART0_RXCTRL) |= UART_RXEN;
}
return 0;
}
static void pre_rate_change_callback(void *priv)
{
struct __metal_driver_sifive_uart0 *uart = priv;
long control_base = __metal_driver_sifive_uart0_control_base((struct metal_uart *)priv);
struct metal_clock *clock = __metal_driver_sifive_uart0_clock((struct metal_uart *)priv);
/* Detect when the TXDATA is empty by setting the transmit watermark count
* to one and waiting until an interrupt is pending */
UART_REGW(METAL_SIFIVE_UART0_TXCTRL) &= ~(UART_TXCNT(0x7));
UART_REGW(METAL_SIFIVE_UART0_TXCTRL) |= UART_TXCNT(1);
while((UART_REGW(METAL_SIFIVE_UART0_IP) & UART_TXWM) == 0) ;
/* When the TXDATA clears, the UART is still shifting out the last byte.
* Calculate the time we must drain to finish transmitting and then wait
* that long. */
long bits_per_symbol = (UART_REGW(METAL_SIFIVE_UART0_TXCTRL) & (1 << 1)) ? 9 : 10;
long clk_freq = clock->vtable->get_rate_hz(clock);
long cycles_to_wait = bits_per_symbol * clk_freq / uart->baud_rate;
for(volatile long x = 0; x < cycles_to_wait; x++)
asm("nop");
}
static void post_rate_change_callback(void *priv)
{
struct __metal_driver_sifive_uart0 *uart = priv;
metal_uart_set_baud_rate(&uart->uart, uart->baud_rate);
}
void __metal_driver_sifive_uart0_init(struct metal_uart *guart, int baud_rate)
{
struct __metal_driver_sifive_uart0 *uart = (void *)(guart);
struct metal_clock *clock = __metal_driver_sifive_uart0_clock(guart);
struct __metal_driver_sifive_gpio0 *pinmux = __metal_driver_sifive_uart0_pinmux(guart);
if(clock != NULL) {
metal_clock_register_pre_rate_change_callback(clock, &pre_rate_change_callback, guart);
metal_clock_register_post_rate_change_callback(clock, &post_rate_change_callback, guart);
}
metal_uart_set_baud_rate(&(uart->uart), baud_rate);
if (pinmux != NULL) {
long pinmux_output_selector = __metal_driver_sifive_uart0_pinmux_output_selector(guart);
long pinmux_source_selector = __metal_driver_sifive_uart0_pinmux_source_selector(guart);
pinmux->gpio.vtable->enable_io(
(struct metal_gpio *) pinmux,
pinmux_output_selector,
pinmux_source_selector
);
}
}
__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_uart0) = {
.uart.init = __metal_driver_sifive_uart0_init,
.uart.putc = __metal_driver_sifive_uart0_putc,
.uart.getc = __metal_driver_sifive_uart0_getc,
.uart.get_baud_rate = __metal_driver_sifive_uart0_get_baud_rate,
.uart.set_baud_rate = __metal_driver_sifive_uart0_set_baud_rate,
.uart.controller_interrupt = __metal_driver_sifive_uart0_interrupt_controller,
.uart.get_interrupt_id = __metal_driver_sifive_uart0_get_interrupt_id,
};
#endif /* METAL_SIFIVE_UART0 */

@ -0,0 +1,262 @@
/*
* FreeRTOS Kernel V10.2.1
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
EXTERN ulRegTest1LoopCounter
EXTERN ulRegTest2LoopCounter
PUBLIC vRegTest1Implementation
PUBLIC vRegTest2Implementation
/*-----------------------------------------------------------*/
SECTION `.text`:CODE:NOROOT(2)
CODE
/*
* The register check tasks are described in the comments at the top of
* main_full.c.
*/
vRegTest1Implementation:
/* Fill the core registers with known values. */
li x5, 0x5
li x6, 0x6
li x7, 0x7
li x8, 0x8
li x9, 0x9
li x10, 0xa
li x11, 0xb
li x12, 0xc
li x13, 0xd
li x14, 0xe
li x15, 0xf
li x16, 0x10
li x17, 0x11
li x18, 0x12
li x19, 0x13
li x20, 0x14
li x21, 0x15
li x22, 0x16
li x23, 0x17
li x24, 0x18
li x25, 0x19
li x26, 0x1a
li x27, 0x1b
li x28, 0x1c
li x29, 0x1d
li x30, 0x1e
reg1_loop:
/* Check each register still contains the expected known value.
vRegTest1Implementation uses x31 as the temporary, vRegTest2Implementation
uses x5 as the temporary. */
li x31, 0x5
bne x31, x5, reg1_error_loop
li x31, 0x6
bne x31, x6, reg1_error_loop
li x31, 0x7
bne x31, x7, reg1_error_loop
li x31, 0x8
bne x31, x8, reg1_error_loop
li x31, 0x9
bne x31, x9, reg1_error_loop
li x31, 0xa
bne x31, x10, reg1_error_loop
li x31, 0xb
bne x31, x11, reg1_error_loop
li x31, 0xc
bne x31, x12, reg1_error_loop
li x31, 0xd
bne x31, x13, reg1_error_loop
li x31, 0xe
bne x31, x14, reg1_error_loop
li x31, 0xf
bne x31, x15, reg1_error_loop
li x31, 0x10
bne x31, x16, reg1_error_loop
li x31, 0x11
bne x31, x17, reg1_error_loop
li x31, 0x12
bne x31, x18, reg1_error_loop
li x31, 0x13
bne x31, x19, reg1_error_loop
li x31, 0x14
bne x31, x20, reg1_error_loop
li x31, 0x15
bne x31, x21, reg1_error_loop
li x31, 0x16
bne x31, x22, reg1_error_loop
li x31, 0x17
bne x31, x23, reg1_error_loop
li x31, 0x18
bne x31, x24, reg1_error_loop
li x31, 0x19
bne x31, x25, reg1_error_loop
li x31, 0x1a
bne x31, x26, reg1_error_loop
li x31, 0x1b
bne x31, x27, reg1_error_loop
li x31, 0x1c
bne x31, x28, reg1_error_loop
li x31, 0x1d
bne x31, x29, reg1_error_loop
li x31, 0x1e
bne x31, x30, reg1_error_loop
/* Everything passed, increment the loop counter. */
lw x31, ulRegTest1LoopCounter
//_RB_ lw x30, 0(x31)
addi x30, x30, 1
sw x30, 0(x31)
/* Restore clobbered register reading for next loop. */
li x30, 0x1e
/* Yield to increase code coverage. */
ecall
/* Start again. */
jal reg1_loop
reg1_error_loop:
/* Jump here if a register contains an uxpected value. This stops the loop
counter being incremented so the check task knows an error was found. */
jal reg1_error_loop
/*-----------------------------------------------------------*/
vRegTest2Implementation:
/* Fill the core registers with known values. */
li x6, 0x61
li x7, 0x71
li x8, 0x81
li x9, 0x91
li x10, 0xa1
li x11, 0xb1
li x12, 0xc1
li x13, 0xd1
li x14, 0xe1
li x15, 0xf1
li x16, 0x20
li x17, 0x21
li x18, 0x22
li x19, 0x23
li x20, 0x24
li x21, 0x25
li x22, 0x26
li x23, 0x27
li x24, 0x28
li x25, 0x29
li x26, 0x2a
li x27, 0x2b
li x28, 0x2c
li x29, 0x2d
li x30, 0x2e
li x31, 0x2f
Reg2_loop:
/* Check each register still contains the expected known value.
vRegTest2Implementation uses x5 as the temporary, vRegTest1Implementation
uses x31 as the temporary. */
li x5, 0x61
bne x5, x6, reg2_error_loop
li x5, 0x71
bne x5, x7, reg2_error_loop
li x5, 0x81
bne x5, x8, reg2_error_loop
li x5, 0x91
bne x5, x9, reg2_error_loop
li x5, 0xa1
bne x5, x10, reg2_error_loop
li x5, 0xb1
bne x5, x11, reg2_error_loop
li x5, 0xc1
bne x5, x12, reg2_error_loop
li x5, 0xd1
bne x5, x13, reg2_error_loop
li x5, 0xe1
bne x5, x14, reg2_error_loop
li x5, 0xf1
bne x5, x15, reg2_error_loop
li x5, 0x20
bne x5, x16, reg2_error_loop
li x5, 0x21
bne x5, x17, reg2_error_loop
li x5, 0x22
bne x5, x18, reg2_error_loop
li x5, 0x23
bne x5, x19, reg2_error_loop
li x5, 0x24
bne x5, x20, reg2_error_loop
li x5, 0x25
bne x5, x21, reg2_error_loop
li x5, 0x26
bne x5, x22, reg2_error_loop
li x5, 0x27
bne x5, x23, reg2_error_loop
li x5, 0x28
bne x5, x24, reg2_error_loop
li x5, 0x29
bne x5, x25, reg2_error_loop
li x5, 0x2a
bne x5, x26, reg2_error_loop
li x5, 0x2b
bne x5, x27, reg2_error_loop
li x5, 0x2c
bne x5, x28, reg2_error_loop
li x5, 0x2d
bne x5, x29, reg2_error_loop
li x5, 0x2e
bne x5, x30, reg2_error_loop
li x5, 0x2f
bne x5, x31, reg2_error_loop
/* Everything passed, increment the loop counter. */
lw x5, ulRegTest2LoopCounter
//_RB_ lw x6, 0(x5)
addi x6, x6, 1
sw x6, 0(x5)
/* Restore clobbered register reading for next loop. */
li x6, 0x61
/* Start again. */
jal Reg2_loop
reg2_error_loop:
/* Jump here if a register contains an uxpected value. This stops the loop
counter being incremented so the check task knows an error was found. */
jal reg2_error_loop
/*-----------------------------------------------------------*/

@ -0,0 +1,397 @@
/*
* FreeRTOS Kernel V10.2.1
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/******************************************************************************
* NOTE 1: This project provides two demo applications. A simple blinky style
* project, and a more comprehensive test and demo application. The
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select
* between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
* in main.c. This file implements the comprehensive test and demo version.
*
* NOTE 2: This file only contains the source code that is specific to the
* full demo. Generic functions, such FreeRTOS hook functions, and functions
* required to configure the hardware, are defined in main.c.
*
******************************************************************************
*
* main_full() creates all the demo application tasks and software timers, then
* starts the scheduler. The web documentation provides more details of the
* standard demo application tasks, which provide no particular functionality,
* but do provide a good example of how to use the FreeRTOS API.
*
* In addition to the standard demo tasks, the following tasks and tests are
* defined and/or created within this file:
*
* "Reg test" tasks - These fill both the core registers with known values, then
* check that each register maintains its expected value for the lifetime of the
* task. Each task uses a different set of values. The reg test tasks execute
* with a very low priority, so get preempted very frequently. A register
* containing an unexpected value is indicative of an error in the context
* switching mechanism.
*
* "Check" task - The check executes every three seconds. It checks that all
* the standard demo tasks, and the register check tasks, are not only still
* executing, but are executing without reporting any errors. If the check task
* discovers that a task has either stalled, or reported an error, then it
* prints an error message to the UART, otherwise it prints "Pass.".
*/
/* Standard includes. */
#include <stdio.h>
#include <string.h>
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "semphr.h"
/* Standard demo application includes. */
#include "dynamic.h"
#include "blocktim.h"
#include "GenQTest.h"
#include "recmutex.h"
#include "TimerDemo.h"
#include "EventGroupsDemo.h"
#include "TaskNotify.h"
#include "AbortDelay.h"
#include "countsem.h"
#include "death.h"
#include "MessageBufferDemo.h"
#include "StreamBufferDemo.h"
#include "StreamBufferInterrupt.h"
/* Priorities for the demo application tasks. */
#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL )
/* The period of the check task, in ms, converted to ticks using the
pdMS_TO_TICKS() macro. mainNO_ERROR_CHECK_TASK_PERIOD is used if no errors have
been found, mainERROR_CHECK_TASK_PERIOD is used if an error has been found. */
#define mainNO_ERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 3000UL )
#define mainERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 500UL )
/* Parameters that are passed into the register check tasks solely for the
purpose of ensuring parameters are passed into tasks correctly. */
#define mainREG_TEST_TASK_1_PARAMETER ( ( void * ) 0x12345678 )
#define mainREG_TEST_TASK_2_PARAMETER ( ( void * ) 0x87654321 )
/* The base period used by the timer test tasks. */
#define mainTIMER_TEST_PERIOD ( 50 )
/* The size of the stack allocated to the check task (as described in the
comments at the top of this file. */
#define mainCHECK_TASK_STACK_SIZE_WORDS 100
/* Size of the stacks to allocated for the register check tasks. */
#define mainREG_TEST_STACK_SIZE_WORDS 70
/*-----------------------------------------------------------*/
/*
* Called by main() to run the full demo (as opposed to the blinky demo) when
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.
*/
void main_full( void );
/*
* The check task, as described at the top of this file.
*/
static void prvCheckTask( void *pvParameters );
/*
* Initialise and start the peripheral timers that are used to exercise external
* interrupt processing.
*/
static void prvSetupPeripheralTimers( void );
/*
* Register check tasks as described at the top of this file. The nature of
* these files necessitates that they are written in an assembly file, but the
* entry points are kept in the C file for the convenience of checking the task
* parameter.
*/
static void prvRegTestTaskEntry1( void *pvParameters );
extern void vRegTest1Implementation( void );
static void prvRegTestTaskEntry2( void *pvParameters );
extern void vRegTest2Implementation( void );
/*
* Tick hook used by the full demo, which includes code that interacts with
* some of the tests.
*/
void vFullDemoTickHook( void );
/*-----------------------------------------------------------*/
/* The following two variables are used to communicate the status of the
register check tasks to the check task. If the variables keep incrementing,
then the register check tasks have not discovered any errors. If a variable
stops incrementing, then an error has been found. */
volatile uint32_t ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
/*-----------------------------------------------------------*/
void main_full( void )
{
/* Start all the other standard demo/test tasks. They have no particular
functionality, but do demonstrate how to use the FreeRTOS API and test the
kernel port. */
vStartDynamicPriorityTasks();
vCreateBlockTimeTasks();
vStartGenericQueueTasks( tskIDLE_PRIORITY );
vStartRecursiveMutexTasks();
vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
vStartEventGroupTasks();
vStartTaskNotifyTask();
vCreateAbortDelayTasks();
vStartCountingSemaphoreTasks();
vStartMessageBufferTasks( configMINIMAL_STACK_SIZE );
vStartStreamBufferTasks();
vStartStreamBufferInterruptDemo();
/* Create the register check tasks, as described at the top of this file.
Use xTaskCreateStatic() to create a task using only statically allocated
memory. */
xTaskCreate( prvRegTestTaskEntry1, /* The function that implements the task. */
"Reg1", /* The name of the task. */
mainREG_TEST_STACK_SIZE_WORDS, /* Size of stack to allocate for the task - in words not bytes!. */
mainREG_TEST_TASK_1_PARAMETER, /* Parameter passed into the task. */
tskIDLE_PRIORITY, /* Priority of the task. */
NULL ); /* Can be used to pass out a handle to the created task. */
xTaskCreate( prvRegTestTaskEntry2, "Reg2", mainREG_TEST_STACK_SIZE_WORDS, mainREG_TEST_TASK_2_PARAMETER, tskIDLE_PRIORITY, NULL );
/* Create the task that performs the 'check' functionality, as described at
the top of this file. */
xTaskCreate( prvCheckTask, "Check", mainCHECK_TASK_STACK_SIZE_WORDS, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* The set of tasks created by the following function call have to be
created last as they keep account of the number of tasks they expect to see
running. */
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
/* Start the scheduler. */
vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then
there was insufficient FreeRTOS heap memory available for the Idle and/or
timer tasks to be created. See the memory management section on the
FreeRTOS web site for more details on the FreeRTOS heap
http://www.freertos.org/a00111.html. */
for( ;; );
}
/*-----------------------------------------------------------*/
static void prvCheckTask( void *pvParameters )
{
TickType_t xDelayPeriod = mainNO_ERROR_CHECK_TASK_PERIOD;
TickType_t xLastExecutionTime;
uint32_t ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
char * const pcPassMessage = ".";
char * pcStatusMessage = pcPassMessage;
extern void vSendString( const char * const pcString );
extern void vToggleLED( void );
/* Just to stop compiler warnings. */
( void ) pvParameters;
/* Start with a pass message, after which a '.' character will be printed
out on each successful loop. */
vSendString( "Pass" );
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
works correctly. */
xLastExecutionTime = xTaskGetTickCount();
/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. The onboard LED is toggled on each iteration.
If an error is detected then the delay period is decreased from
mainNO_ERROR_CHECK_TASK_PERIOD to mainERROR_CHECK_TASK_PERIOD. This has the
effect of increasing the rate at which the onboard LED toggles, and in so
doing gives visual feedback of the system status. */
for( ;; )
{
/* Delay until it is time to execute again. */
vTaskDelayUntil( &xLastExecutionTime, xDelayPeriod );
/* Check all the demo tasks (other than the flash tasks) to ensure
that they are all still running, and that none have detected an error. */
if( xAreDynamicPriorityTasksStillRunning() == pdFALSE )
{
pcStatusMessage = "ERROR: Dynamic priority demo/tests.\r\n";
}
if( xAreBlockTimeTestTasksStillRunning() == pdFALSE )
{
pcStatusMessage = "ERROR: Block time demo/tests.\r\n";
}
if( xAreGenericQueueTasksStillRunning() == pdFALSE )
{
pcStatusMessage = "ERROR: Generic queue demo/tests.\r\n";
}
if( xAreRecursiveMutexTasksStillRunning() == pdFALSE )
{
pcStatusMessage = "ERROR: Recursive mutex demo/tests.\r\n";
}
if( xAreTimerDemoTasksStillRunning( ( TickType_t ) xDelayPeriod ) == pdFALSE )
{
pcStatusMessage = "ERROR: Timer demo/tests.\r\n";
}
if( xAreEventGroupTasksStillRunning() == pdFALSE )
{
pcStatusMessage = "ERROR: Event group demo/tests.\r\n";
}
if( xAreTaskNotificationTasksStillRunning() == pdFALSE )
{
pcStatusMessage = "ERROR: Task notification demo/tests.\r\n";
}
if( xAreAbortDelayTestTasksStillRunning() == pdFALSE )
{
pcStatusMessage = "ERROR: Abort delay.\r\n";
}
if( xAreCountingSemaphoreTasksStillRunning() == pdFALSE )
{
pcStatusMessage = "ERROR: Counting semaphores.\r\n";
}
if( xIsCreateTaskStillRunning() == pdFALSE )
{
pcStatusMessage = "ERROR: Suicide tasks.\r\n";
}
if( xAreMessageBufferTasksStillRunning() == pdFALSE )
{
pcStatusMessage = "ERROR: Message buffer.\r\n";
}
if( xAreStreamBufferTasksStillRunning() == pdFALSE )
{
pcStatusMessage = "ERROR: Stream buffer.\r\n";
}
if( xIsInterruptStreamBufferDemoStillRunning() == pdFALSE )
{
pcStatusMessage = "ERROR: Stream buffer interrupt.\r\n";
}
/* Check that the register test 1 task is still running. */
if( ulLastRegTest1Value == ulRegTest1LoopCounter )
{
pcStatusMessage = "ERROR: Register test 1.\r\n";
}
ulLastRegTest1Value = ulRegTest1LoopCounter;
/* Check that the register test 2 task is still running. */
if( ulLastRegTest2Value == ulRegTest2LoopCounter )
{
pcStatusMessage = "ERROR: Register test 2.\r\n";
}
ulLastRegTest2Value = ulRegTest2LoopCounter;
/* Write the status message to the UART. */
vSendString( pcStatusMessage );
/* If an error has been found then increase the LED toggle rate by
increasing the cycle frequency. */
if( pcStatusMessage != pcPassMessage )
{
xDelayPeriod = mainERROR_CHECK_TASK_PERIOD;
}
}
}
/*-----------------------------------------------------------*/
static void prvRegTestTaskEntry1( void *pvParameters )
{
/* Although the regtest task is written in assembler, its entry point is
written in C for convenience of checking the task parameter is being passed
in correctly. */
if( pvParameters == mainREG_TEST_TASK_1_PARAMETER )
{
/* Start the part of the test that is written in assembler. */
vRegTest1Implementation();
}
/* The following line will only execute if the task parameter is found to
be incorrect. The check task will detect that the regtest loop counter is
not being incremented and flag an error. */
vTaskDelete( NULL );
}
/*-----------------------------------------------------------*/
static void prvRegTestTaskEntry2( void *pvParameters )
{
/* Although the regtest task is written in assembler, its entry point is
written in C for convenience of checking the task parameter is being passed
in correctly. */
if( pvParameters == mainREG_TEST_TASK_2_PARAMETER )
{
/* Start the part of the test that is written in assembler. */
vRegTest2Implementation();
}
/* The following line will only execute if the task parameter is found to
be incorrect. The check task will detect that the regtest loop counter is
not being incremented and flag an error. */
vTaskDelete( NULL );
}
/*-----------------------------------------------------------*/
void vFullDemoTickHook( void )
{
/* The full demo includes a software timer demo/test that requires
prodding periodically from the tick interrupt. */
vTimerPeriodicISRTests();
/* Call the periodic event group from ISR demo. */
vPeriodicEventGroupsProcessing();
/* Use task notifications from an interrupt. */
xNotifyTaskFromISR();
/* Writes to stream buffer byte by byte to test the stream buffer trigger
level functionality. */
vPeriodicStreamBufferProcessing();
/* Writes a string to a string buffer four bytes at a time to demonstrate
a stream being sent from an interrupt to a task. */
vBasicStreamBufferSendFromISR();
/* Called from vApplicationTickHook() when the project is configured to
build the full test/demo applications. */
}
/*-----------------------------------------------------------*/

@ -0,0 +1,222 @@
/*
* FreeRTOS Kernel V10.2.1
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/* FreeRTOS kernel includes. */
#include <FreeRTOS.h>
#include <task.h>
/******************************************************************************
* This project provides two demo applications. A simple blinky style project,
* and a more comprehensive test and demo application. The
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting (defined in this file) is used to
* select between the two. The simply blinky demo is implemented and described
* in main_blinky.c. The more comprehensive test and demo application is
* implemented and described in main_full.c.
*
* This file implements the code that is not demo specific, including the
* hardware setup and standard FreeRTOS hook functions.
*
* ENSURE TO READ THE DOCUMENTATION PAGE FOR THIS PORT AND DEMO APPLICATION ON
* THE http://www.FreeRTOS.org WEB SITE FOR FULL INFORMATION ON USING THIS DEMO
* APPLICATION, AND ITS ASSOCIATE FreeRTOS ARCHITECTURE PORT!
*
*/
/* UART hardware constants. */
#define mainUART_BASE_ADDRESS ( *( volatile uint32_t * ) 0x20000000UL )
#define mainUART_TX_DATA 0x00
#define mainUART_TX_CTRL 0x08
#define mainUART_RX_CTRL 0x0c
#define mainUART_CLOCK_DIV 0x18
#define mainUART_TX_ENABLE_BIT (1UL << 0UL)
#define mainUART_RX_ENABLE_BIT (1UL << 0UL)
#define mainUART_TX_FULL_BIT (1UL << 31UL)
#define mainUART_REGISTER( offset ) ( ( mainUART_BASE_ADDRESS + offset ) )
#define mainUART_REGISTER_WORD( offset ) ( *( ( uint32_t * ) mainUART_REGISTER( offset ) ) )
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0
/*
* main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
* main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.
*/
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
extern void main_blinky( void );
#else
extern void main_full( void );
#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
/* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. See https://www.freertos.org/a00016.html */
void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
void vApplicationTickHook( void );
/* Prepare hardware to run the demo. */
static void prvSetupHardware( void );
/* Send a message to the UART initialised in prvSetupHardware. */
void vSendString( const char * const pcString );
/*-----------------------------------------------------------*/
int main( void )
{
prvSetupHardware();
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
of this file. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
{
main_blinky();
}
#else
{
main_full();
}
#endif
}
/*-----------------------------------------------------------*/
static void prvSetupHardware( void )
{
const unsigned long clock_rate = 66000000, baud_rate = 115200;
/* Initialise the UART. */
mainUART_REGISTER_WORD( mainUART_CLOCK_DIV ) = clock_rate / baud_rate - 1;
mainUART_REGISTER_WORD( mainUART_TX_CTRL ) |= mainUART_TX_ENABLE_BIT;
mainUART_REGISTER_WORD( mainUART_RX_CTRL ) |= mainUART_RX_ENABLE_BIT;
}
/*-----------------------------------------------------------*/
void vToggleLED( void )
{
static uint32_t ulLEDState = 0;
ulLEDState = !ulLEDState;
}
/*-----------------------------------------------------------*/
void vSendString( const char * const pcString )
{
uint32_t ulIndex = 0;
while( pcString[ ulIndex ] != 0x00 )
{
while( ( mainUART_REGISTER_WORD( mainUART_TX_DATA ) & mainUART_TX_FULL_BIT ) != 0UL );
mainUART_REGISTER_WORD(mainUART_TX_DATA) = pcString[ ulIndex ];
ulIndex++;
}
}
/*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS();
__asm volatile( "ebreak" );
for( ;; );
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
__asm volatile( "ebreak" );
for( ;; );
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
/* The tests in the full demo expect some interaction with interrupts. */
#if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY != 1 )
{
extern void vFullDemoTickHook( void );
vFullDemoTickHook();
}
#endif
}
/*-----------------------------------------------------------*/
/* Called from the kernel's port layer to handle device specific external
interrupts. */
void vApplicationHandleTrap( uint32_t mcause )
{
/* Not implemented yet. */
configASSERT( mcause == 0 );
#warning vApplicationHandleTrap not implemented.
#if 0
uint32_t ulInterruptNumber;
typedef void ( * irq_handler_t )( void );
extern const irq_handler_t isrTable[];
ulInterruptNumber = PLIC->TARGET[ 0 ].CLAIM_COMPLETE;
/* Read handler from table. */
/* Call handler. */
PLIC->TARGET[ 0 ].CLAIM_COMPLETE = ulInterruptNumber;
#endif
}

@ -0,0 +1,205 @@
/*
* FreeRTOS Kernel V10.2.1
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/******************************************************************************
* NOTE 1: This project provides two demo applications. A simple blinky
* style project, and a more comprehensive test and demo application. The
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select
* between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
* in main.c. This file implements the simply blinky style version.
*
* NOTE 2: This file only contains the source code that is specific to the
* basic demo. Generic functions, such FreeRTOS hook functions, and functions
* required to configure the hardware are defined in main.c.
******************************************************************************
*
* main_blinky() creates one queue, and two tasks. It then starts the
* scheduler.
*
* The Queue Send Task:
* The queue send task is implemented by the prvQueueSendTask() function in
* this file. prvQueueSendTask() sits in a loop that causes it to repeatedly
* block for 1000 milliseconds, before sending the value 100 to the queue that
* was created within main_blinky(). Once the value is sent, the task loops
* back around to block for another 1000 milliseconds...and so on.
*
* The Queue Receive Task:
* The queue receive task is implemented by the prvQueueReceiveTask() function
* in this file. prvQueueReceiveTask() sits in a loop where it repeatedly
* blocks on attempts to read data from the queue that was created within
* main_blinky(). When data is received, the task checks the value of the
* data, and if the value equals the expected 100, writes 'Blink' to the UART
* (the UART is used in place of the LED to allow easy execution in QEMU). The
* 'block time' parameter passed to the queue receive function specifies that
* the task should be held in the Blocked state indefinitely to wait for data to
* be available on the queue. The queue receive task will only leave the
* Blocked state when the queue send task writes to the queue. As the queue
* send task writes to the queue every 1000 milliseconds, the queue receive
* task leaves the Blocked state every 1000 milliseconds, and therefore toggles
* the LED every 200 milliseconds.
*/
/* Standard includes. */
#include <stdio.h>
#include <string.h>
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
/* Priorities used by the tasks. */
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the pdMS_TO_TICKS() macro. */
#define mainQUEUE_SEND_FREQUENCY_MS pdMS_TO_TICKS( 1000 )
/* The maximum number items the queue can hold. The priority of the receiving
task is above the priority of the sending task, so the receiving task will
preempt the sending task and remove the queue items each time the sending task
writes to the queue. Therefore the queue will never have more than one item in
it at any time, and even with a queue length of 1, the sending task will never
find the queue full. */
#define mainQUEUE_LENGTH ( 1 )
/*-----------------------------------------------------------*/
/*
* Called by main when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1 in
* main.c.
*/
void main_blinky( void );
/*
* The tasks as described in the comments at the top of this file.
*/
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
/*-----------------------------------------------------------*/
/* The queue used by both tasks. */
static QueueHandle_t xQueue = NULL;
/*-----------------------------------------------------------*/
void main_blinky( void )
{
/* Create the queue. */
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) );
if( xQueue != NULL )
{
/* Start the two tasks as described in the comments at the top of this
file. */
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE * 2U, /* The size of the stack to allocate to the task. */
NULL, /* The parameter passed to the task - not used in this case. */
mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */
NULL ); /* The task handle is not required, so NULL is passed. */
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE * 2U, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* Start the tasks and timer running. */
vTaskStartScheduler();
}
/* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then
there was insufficient FreeRTOS heap memory available for the Idle and/or
timer tasks to be created. See the memory management section on the
FreeRTOS web site for more details on the FreeRTOS heap
http://www.freertos.org/a00111.html. */
for( ;; );
}
/*-----------------------------------------------------------*/
static void prvQueueSendTask( void *pvParameters )
{
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
BaseType_t xReturned;
/* Remove compiler warning about unused parameter. */
( void ) pvParameters;
/* Initialise xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount();
for( ;; )
{
/* Place this task in the blocked state until it is time to run again. */
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and
toggle the LED. 0 is used as the block time so the sending operation
will not block - it shouldn't need to block as the queue should always
be empty at this point in the code. */
xReturned = xQueueSend( xQueue, &ulValueToSend, 0U );
configASSERT( xReturned == pdPASS );
}
}
/*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters )
{
unsigned long ulReceivedValue;
const unsigned long ulExpectedValue = 100UL;
const char * const pcPassMessage = "Blink\r\n";
const char * const pcFailMessage = "Unexpected value received\r\n";
extern void vSendString( const char * const pcString );
extern void vToggleLED( void );
/* Remove compiler warning about unused parameter. */
( void ) pvParameters;
for( ;; )
{
/* Wait until something arrives in the queue - this task will block
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
FreeRTOSConfig.h. */
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == ulExpectedValue )
{
vSendString( pcPassMessage );
vToggleLED();
ulReceivedValue = 0U;
}
else
{
vSendString( pcFailMessage );
}
}
}
/*-----------------------------------------------------------*/

@ -0,0 +1,40 @@
@REM This batch file has been generated by the IAR Embedded Workbench
@REM C-SPY Debugger, as an aid to preparing a command line for running
@REM the cspybat command line utility using the appropriate settings.
@REM
@REM Note that this file is generated every time a new debug session
@REM is initialized, so you may want to move or rename the file before
@REM making changes.
@REM
@REM You can launch cspybat by typing the name of this batch file followed
@REM by the name of the debug file (usually an ELF/DWARF or UBROF file).
@REM
@REM Read about available command line parameters in the C-SPY Debugging
@REM Guide. Hints about additional command line parameters that may be
@REM useful in specific cases:
@REM --download_only Downloads a code image without starting a debug
@REM session afterwards.
@REM --silent Omits the sign-on message.
@REM --timeout Limits the maximum allowed execution time.
@REM
@echo off
if not "%~1" == "" goto debugFile
@echo on
"C:\devtools\IAR Systems\Embedded Workbench 8.3\common\bin\cspybat" -f "C:\Users\ribarry\Dev\FreeRTOS\WorkingCopy\FreeRTOS\Demo\RISC-V_RV32_SiFive_IAR\settings\RTOSDemo.Debug.general.xcl" --backend -f "C:\Users\ribarry\Dev\FreeRTOS\WorkingCopy\FreeRTOS\Demo\RISC-V_RV32_SiFive_IAR\settings\RTOSDemo.Debug.driver.xcl"
@echo off
goto end
:debugFile
@echo on
"C:\devtools\IAR Systems\Embedded Workbench 8.3\common\bin\cspybat" -f "C:\Users\ribarry\Dev\FreeRTOS\WorkingCopy\FreeRTOS\Demo\RISC-V_RV32_SiFive_IAR\settings\RTOSDemo.Debug.general.xcl" "--debug_file=%~1" --backend -f "C:\Users\ribarry\Dev\FreeRTOS\WorkingCopy\FreeRTOS\Demo\RISC-V_RV32_SiFive_IAR\settings\RTOSDemo.Debug.driver.xcl"
@echo off
:end

@ -0,0 +1,31 @@
param([String]$debugfile = "");
# This powershell file has been generated by the IAR Embedded Workbench
# C - SPY Debugger, as an aid to preparing a command line for running
# the cspybat command line utility using the appropriate settings.
#
# Note that this file is generated every time a new debug session
# is initialized, so you may want to move or rename the file before
# making changes.
#
# You can launch cspybat by typing Powershell.exe -File followed by the name of this batch file, followed
# by the name of the debug file (usually an ELF / DWARF or UBROF file).
#
# Read about available command line parameters in the C - SPY Debugging
# Guide. Hints about additional command line parameters that may be
# useful in specific cases :
# --download_only Downloads a code image without starting a debug
# session afterwards.
# --silent Omits the sign - on message.
# --timeout Limits the maximum allowed execution time.
#
if ($debugfile -eq "")
{
& "C:\devtools\IAR Systems\Embedded Workbench 8.3\common\bin\cspybat" -f "C:\Users\ribarry\Dev\FreeRTOS\WorkingCopy\FreeRTOS\Demo\RISC-V_RV32_SiFive_IAR\settings\RTOSDemo.Debug.general.xcl" --backend -f "C:\Users\ribarry\Dev\FreeRTOS\WorkingCopy\FreeRTOS\Demo\RISC-V_RV32_SiFive_IAR\settings\RTOSDemo.Debug.driver.xcl"
}
else
{
& "C:\devtools\IAR Systems\Embedded Workbench 8.3\common\bin\cspybat" -f "C:\Users\ribarry\Dev\FreeRTOS\WorkingCopy\FreeRTOS\Demo\RISC-V_RV32_SiFive_IAR\settings\RTOSDemo.Debug.general.xcl" --debug_file=$debugfile --backend -f "C:\Users\ribarry\Dev\FreeRTOS\WorkingCopy\FreeRTOS\Demo\RISC-V_RV32_SiFive_IAR\settings\RTOSDemo.Debug.driver.xcl"
}

@ -0,0 +1,13 @@
"--core=RV32IMAC"
"-p"
"C:\devtools\IAR Systems\Embedded Workbench 8.3\riscv\config\debugger\SiFive\e31arty35t.ddf"
"-d"
"sim"

@ -0,0 +1,11 @@
"C:\devtools\IAR Systems\Embedded Workbench 8.3\riscv\bin\riscvproc.dll"
"C:\devtools\IAR Systems\Embedded Workbench 8.3\riscv\bin\riscvsim.dll"
"C:\Users\ribarry\Dev\FreeRTOS\WorkingCopy\FreeRTOS\Demo\RISC-V_RV32_SiFive_IAR\Debug\Exe\RTOSDemo.out"
--plugin="C:\devtools\IAR Systems\Embedded Workbench 8.3\riscv\bin\riscvbat.dll"

File diff suppressed because one or more lines are too long

@ -0,0 +1,111 @@
<?xml version="1.0"?>
<settings>
<Stack>
<FillEnabled>0</FillEnabled>
<OverflowWarningsEnabled>1</OverflowWarningsEnabled>
<WarningThreshold>90</WarningThreshold>
<SpWarningsEnabled>1</SpWarningsEnabled>
<WarnLogOnly>1</WarnLogOnly>
<UseTrigger>1</UseTrigger>
<TriggerName>main</TriggerName>
<LimitSize>0</LimitSize>
<ByteLimit>50</ByteLimit>
</Stack>
<DebugChecksum>
<Checksum>1686049390</Checksum>
</DebugChecksum>
<Disassembly>
<InstrCount>0</InstrCount>
<MixedMode>1</MixedMode>
</Disassembly>
<CodeCoverage>
<Enabled>0</Enabled>
<ShowSource>0</ShowSource>
<HideCovered>0</HideCovered>
</CodeCoverage>
<CallStack>
<ShowArgs>0</ShowArgs>
</CallStack>
<DataAlign>
<Action>1</Action>
<Notification>1</Notification>
</DataAlign>
<DriverProfiling>
<Enabled>0</Enabled>
<Mode>1</Mode>
<Graph>0</Graph>
<Symbiont>0</Symbiont>
</DriverProfiling>
<CallStackLog>
<Enabled>0</Enabled>
</CallStackLog>
<CallStackStripe>
<ShowTiming>1</ShowTiming>
</CallStackStripe>
<InterruptLog>
<LogEnabled>0</LogEnabled>
<GraphEnabled>0</GraphEnabled>
<ShowTimeLog>1</ShowTimeLog>
<SumEnabled>0</SumEnabled>
<ShowTimeSum>1</ShowTimeSum>
<SumSortOrder>0</SumSortOrder>
</InterruptLog>
<DataLog>
<LogEnabled>0</LogEnabled>
<GraphEnabled>0</GraphEnabled>
<ShowTimeLog>1</ShowTimeLog>
<SumEnabled>0</SumEnabled>
<ShowTimeSum>1</ShowTimeSum>
</DataLog>
<Interrupts>
<Enabled>1</Enabled>
</Interrupts>
<MemConfig>
<Base>1</Base>
<Manual>0</Manual>
<Ddf>1</Ddf>
<TypeViol>0</TypeViol>
<Stop>1</Stop>
</MemConfig>
<Trace1>
<Enabled>0</Enabled>
<ShowSource>1</ShowSource>
</Trace1>
<Simulator>
<Freq>50000000</Freq>
<FreqHi>0</FreqHi>
<MultiCoreRunAll>1</MultiCoreRunAll>
</Simulator>
<Jet>
<JetConnSerialNo>73866</JetConnSerialNo>
<JetConnFoundProbes />
<PrevWtdReset>Hardware</PrevWtdReset>
<OnlineReset>Software</OnlineReset>
<DisableInterrupts>0</DisableInterrupts>
<LeaveRunning>0</LeaveRunning>
<MultiCoreRunAll>0</MultiCoreRunAll>
</Jet>
<PlDriver>
<FirstRun>0</FirstRun>
<MemConfigValue>C:\devtools\IAR Systems\Embedded Workbench 8.3\riscv\config\debugger\SiFive\e31arty35t.ddf</MemConfigValue>
</PlDriver>
<RiscvDriver>
<EnableCache>1</EnableCache>
</RiscvDriver>
<TermIOLog>
<LoggingEnabled>_ 0</LoggingEnabled>
<LogFile>_ ""</LogFile>
</TermIOLog>
<LogFile>
<LoggingEnabled>_ 0</LoggingEnabled>
<LogFile>_ ""</LogFile>
<Category>_ 0</Category>
</LogFile>
<Breakpoints2>
<Count>0</Count>
</Breakpoints2>
<Aliases>
<Count>0</Count>
<SuppressDialog>0</SuppressDialog>
</Aliases>
</settings>

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save