Hi I am working a port for the Renesas RISC-V.
The problems I am encountering are many, I’ll list them (they are all exclusive, happens only one of them at a time):
- running the program, after not much time it asserts at line 2448 of tasks.c (plus
xTickCount
has a value of0xa5a5a5a5
) - it goes in a loop where xPendingTicks grows indefinetly and
xTickCount
is still at value0x20005a34
- process ‘\0’ asserts a stack overflow
- it “ping pongs” in the exception handler between
freertos_risc_v_exception_handler
and IRQ0 entry in the vector list
All those problems derive from adding the interrupt_mtimer_interrupt_handler inside the vector entry for it (in my case it must be defined inside the IDE, more specifically inside a function named INT_ACLINT_MTIP
. It does not work by setting the mtvec for some reason, although setting the mtvec is necessary for handling the exceptions that otherwise setting them through the IDE for entry 0 of the vector table does not work. With does not work I mean I get sent into an are name gp_ExceptVector at position 0x1C
, which strangely is where also the INT_ACLINT_MTIP
should be).
I’ll add other odd things that happen and that are not clear to me.
- the stack in my case seems really odd, I mean this is the specific part of the linker script:
PROVIDE(__stack_size = 0x200);
.stack 0x20006FFC (NOLOAD) : AT(0x20006FFC)
{
PROVIDE(__stack = .);
ASSERT((__stack > (end + __stack_size)), "Error: Too much data - no room left for the stack");
. = ALIGN(16);
__freertos_irq_stack_top = .;
} >RAM
Here is the address space: https://www.renesas.com/en/document/mah/r9a02g021-users-manual-hardware?r=25470171#unique_196
I know that the __freertos_irq_stack_top
variable is not set up correctly, but based on the image I attach about the address space, can you help figure this out?
- when there is an ecall is it right to enter the first entry of the interrupt vector table? Since from the IDE I cannot set up the exception handler (first entry of the interrupt vector table) directly and I need to overwrite the mtvec, is there a way to setup only the exception handler and not the whole interrupt vector table? However even by overwriting the whole mtvec the handler for the machine timer interrupt is invoked somehow.
Just for adding more useful information, here is the main:
#include "r_smc_entry.h"
#include "FreeRTOS.h"
#include "task.h"
volatile uint32_t blinkDelay = 1000; // Initial blink delay of 1 second (1 Hz)
extern volatile void freertos_vector_table(void);
extern volatile void freertos_risc_v_trap_handler(void);
int main(void);
void vTaskFunction1(void *pvParameters) {
machine_timer_start();
while(1)
{
/* Toggle LED status */
PIN_WRITE(LED2) = ~PIN_READ(LED2);
/* Delay blinkDelay milliseconds before returning */
vTaskDelay(blinkDelay);
}
}
int main(void)
{
/* Setup and start the machine timer */
asm volatile ( "csrw mtvec, %0" : : "r" ( ( uintptr_t ) freertos_vector_table | 0x01 ));
/* Start SW Interrupt */
R_Config_ICU_IRQ4_Start();
/* Create the task(s) */
int taskReturnValue1 = xTaskCreate(
vTaskFunction1, /* Pointer to the function that implements the task. */
"Task 1 BLINK", /* Text name for the task (useful for debugging). */
configMINIMAL_STACK_SIZE, /* Stack depth in words. */
NULL, /* Task input parameter (if any). */
tskIDLE_PRIORITY + 1, /* Priority at which the task will run. */
NULL /* Task handle (not used in this case). */
);
if (taskReturnValue1 == pdTRUE)
vTaskStartScheduler();
for (;;);
return 0;
}
In the r_cg_inthandler.c
:
/*
* INT_ACLINT_MSIP (0x00)
*/
void INT_ACLINT_MSIP(void)
{
/* Start user code for INT_ACLINT_MSIP. Do not edit comment generated here */
freertos_risc_v_mtimer_interrupt_handler();
/* End user code. Do not edit comment generated here */
}
/*
* INT_ACLINT_MTIP (0x1C)
*/
void INT_ACLINT_MTIP(void)
{
/* Start user code for INT_ACLINT_MTIP. Do not edit comment generated here */
freertos_risc_v_mtimer_interrupt_handler();
/* End user code. Do not edit comment generated here */
}
/*
* INT_IELSR0 (0x4C)
*/
void INT_IELSR0(void)
{
/* Start user code for INT_IELSR0. Do not edit comment generated here */
freertos_risc_v_exception_handler();
/* End user code. Do not edit comment generated here */
}
/*
* INT_IELSR1 (0x50)
*/
void INT_IELSR1(void)
{
/* Start user code for INT_IELSR1. Do not edit comment generated here */
freertos_risc_v_interrupt_handler();
/* End user code. Do not edit comment generated here */
}
I have also tried calling the function that Renesas provides for refreshing machine timer (changing mtimecmp value) but doing so I lose the use of uxTimerIncrementsForOneTick
(suggest me if it makes sense making Renesas API use this value).
As I said the problems are many, if you can help in any of them I would be very glad to you.