FreeRTOS and Nios II in a Cyclone IV FPGA: the system executes the task but not responding to vTaskDelay()
Hi. I am having trouble with a Nios II and FreeRTOS. I will post all the information I think is relevant, thank you in advance for reading and trying to help.
I have this board, a Cyclone IV EP4CE6E22C8N
Currently, I was able to use Qsys to generate a system with Nios II, On-chip ram, RS-232 and a few more PIO, LEDS, and so on.
I program the Nios II with the Eclipse IDE, creating a memory initialization file that later I upload to the On-chip memory.
I was able also to successfully use the timer interrupts by my own, but when I try to implement the FreeRTOS, it is not working as expected.
When I use this sample code in Main.c:
#include <stdio.h>
#include "system.h"
# include "sys/alt_stdio.h"
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "StackMacros.h"
#include "altera_avalon_pio_regs.h"
#include "io.h"
#include "altera_avalon_timer_regs.h"
#include "altera_avalon_timer.h"
#include "sys/alt_irq.h"
#include "altera_up_avalon_rs232_regs.h"
#include "altera_up_avalon_rs232.h"
#include "alt_types.h"
#define WRITE_FIFO_EMPTY 0x80
#include "FreeRTOS.h"
#include "task.h"
#define mainTASK1_PRIORITY ( tskIDLE_PRIORITY + 2 )
void imprimir (char * cadena);
void delay(int time);
static void prvPrintTask1( void *pvParameters );
int main()
{
xTaskCreate( prvPrintTask1, "Task1", configMINIMAL_STACK_SIZE, NULL, mainTASK1_PRIORITY, NULL );
vTaskStartScheduler();
while(1)
{
alt_irq_enabled()==0 ? IOWR_ALTERA_AVALON_PIO_SET_BITS(LED_BASE,0x80): IOWR_ALTERA_AVALON_PIO_CLEAR_BITS(LED_BASE,0x80);
imprimir("Main\r\n\0");
}
return 0;
}
static void prvPrintTask1( void *pvParameters )
{
int i=0;
int count2=0;
for( ;; )
{
alt_irq_enabled()==0 ? IOWR_ALTERA_AVALON_PIO_SET_BITS(LED_BASE,0x80): IOWR_ALTERA_AVALON_PIO_CLEAR_BITS(LED_BASE,0x80);
if(i==0)
{
i=2;
IOWR_ALTERA_AVALON_PIO_SET_BITS(LED_BASE,0x01);
IOWR_ALTERA_AVALON_PIO_CLEAR_BITS(LED_BASE,0x02);
}
else
{
i=0;
IOWR_ALTERA_AVALON_PIO_CLEAR_BITS(LED_BASE,0x01);
IOWR_ALTERA_AVALON_PIO_SET_BITS(LED_BASE,0x02);
}
delay(2);
vTaskDelay(1000);
}
}
int k=0;
int count3=0;
void vApplicationIdleHook( void )
{
k ==2 ? set_bit(0x20) : clear_bit(0x20);
if(k==0)
k=2;
else
k=0;
//imprimir("IdleHook\r\n\0");
}
int l=0;
void vApplicationTickHook( void )
{
alt_irq_enabled()==0 ? IOWR_ALTERA_AVALON_PIO_SET_BITS(LED_BASE,0x80): IOWR_ALTERA_AVALON_PIO_CLEAR_BITS(LED_BASE,0x80);
l==2 ? IOWR_ALTERA_AVALON_PIO_SET_BITS(LED_BASE,0x04): IOWR_ALTERA_AVALON_PIO_CLEAR_BITS(LED_BASE,0x04);
if(l==0)
l=2;
else
l=0;
delay(2);
}
void vApplicationStackOverflowHook( xTaskHandle xTask, signed char *pcTaskName )
{
set_bit(0x08);
imprimir("StackOverflow\r\n\0");
}
void imprimir (char * cadena)
{
int i=0,exit=0;
int write_FIFO_space=0;
alt_up_rs232_dev* rs232_dev;
rs232_dev = alt_up_rs232_open_dev("/dev/rs232_0");
// open the RS232 UART port
if(rs232_dev == NULL)
{
IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE,0xf0);
while(1);
}
else
{
while(exit==0)
{
write_FIFO_space = alt_up_rs232_get_available_space_in_write_FIFO(
rs232_dev);
if (write_FIFO_space >= WRITE_FIFO_EMPTY)
{
alt_up_rs232_write_data(rs232_dev, cadena[i]);
if(cadena[i]!='\0')
i++;
else
exit=1;
}
}
}
}
void delay(int time)
{
int count=0;
while (count <100000*time)
count++;
}With this FreertosConfig.h
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#include "system.h"
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 1
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
#define configCPU_CLOCK_HZ ( ( unsigned long ) SYS_CLK_FREQ )
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 10 )
#define configMINIMAL_STACK_SIZE ( 128 )
#define configISR_STACK_SIZE configMINIMAL_STACK_SIZE
#define configTOTAL_HEAP_SIZE ( ( size_t ) 10000 )//( ( size_t ) 8388608 )
#define configMAX_TASK_NAME_LEN ( 8 )
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 0
#define configUSE_MUTEXES 0
#define configUSE_RECURSIVE_MTEXES 0
#define configUSE_COUNTING_SEMAPHORES 0
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configQUEUE_REGISTRY_SIZE 0
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 0
#define INCLUDE_uxTaskPriorityGet 0
#define INCLUDE_vTaskDelete 0
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 0
#define INCLUDE_vTaskDelayUntil 0
#define INCLUDE_vTaskDelay 1
#define INCLUDE_uxTaskGetStackHighWaterMark 0
/* The priority at which the tick interrupt runs. This should probably be
kept at 1. */
#define configKERNEL_INTERRUPT_PRIORITY 0x01
/* The maximum interrupt priority from which FreeRTOS.org API functions can
be called. Only API functions that end in ...FromISR() can be used within
interrupts. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 0x03
#endif /* FREERTOS_CONFIG_H */And the Nios II port from the FreeRTOS page (this is the one I am using)
https://drive.google.com/file/d/1s-cwfXSmzCXlUQyTv8qg9cuDt6Mm0OLh/view?usp=sharing
The behavior is more or less like this:
-The scheduler starts, I can verify this because it never reaches below that statement, and also, the Task1 is executed.
-I have verified the overflow, but the StackOverflow hook is never called.
-The system hangs in the Task, doing it over and over again like an infinite loop without responding to vTaskDelay(). I see the Led's blinking only because of the delay.
-I assume it is not switching context, the Idle hook never turns on the Led, and the tick hook is not being called neither.
My assumption is that the interrupts are being disabled and never turned on again, because the alt_irq_enabled() is always 0, as I can see from the LED 0x80.
I was nos able to debug it, because when I ran the debugger, it claims that the System ID and the timestamp are not correct, so I am not able to track the code in order to find where it is getting stuck. (Could it be a Qsys interconnection problem?)
So, I would appreciate any clue to solve this issue.
Thanks again.