tantonini wrote on Saturday, June 06, 2015:
Hello everybody
I’m developping a firmware for a SIM3U167 and I’m trying to implement FreeRTOS 8.2.0 on this one.
To summary, my firmware uses the ADC of my µC and I want to notify a task when I am in the scan done’s interruption routine. This is my problem : when I want to increase the speed of my ADC, I go in an HardFault Handler when I want to call the function vTaskNotifyGiveFromISR in my interruption.
When I go in the SARADC0_scan_done_handler over 1 kHz (approximately), it crashes. I don’t know if I have a problem with priorities, if I try to switch contexts to quickly for FreeRTOS or if it is an other problem.
I use the IDE furnished by Silabs : Precision32
I have cut the code to show you only principal things (sorry I don’t know how to color C language)
int main()
{
extern uint8_t start;
extern TaskHandle_t xTaskPotentiometers;
// Enter the default operating mode for this application (gModes.c)
enter_default_mode_from_reset();
NVIC_SetPriority(SARADC0_IRQn, 100);
xTaskCreate(vTaskPotentiometers, "pot", 200, NULL, 1, &xTaskPotentiometers);
// Initialisation
mySARADC0_init();
/* Start the scheduler running the tasks and co-routines just created. */
vTaskStartScheduler();
while(1);
// Loop forever...
}
void SARADC0_conv_complete_handler(void)
{
SI32_SARADC_A_clear_single_conversion_complete_interrupt(SI32_SARADC_0);
}
void SARADC0_scan_done_handler(void)
{
uint8_t k=0;
extern TaskHandle_t xTaskPotentiometers;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
SI32_SARADC_A_clear_single_conversion_complete_interrupt(SI32_SARADC_0);
SI32_SARADC_A_clear_scan_done_interrupt(SI32_SARADC_0);
SI32_SARADC_A_disable_autoscan(SI32_SARADC_0);
SI32_SARADC_A_enable_autoscan(SI32_SARADC_0);
for (k = 0; k < 8; k++)
{
adc_read[k] = SI32_SARADC_A_read_data(SI32_SARADC_0);
}
vTaskNotifyGiveFromISR(xTaskPotentiometers, &xHigherPriorityTaskWoken); <--------------BUG
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
void vTaskPotentiometers(void *pvParameters)
{
extern SemaphoreHandle_t xMutexUsb;
uint32_t adc_output_old[8], adc_output[8];
uint32_t adc_output_old128[8], adc_output128[8];
uint32_t adc_value_send[8];
uint8_t adc_number_send[8];
extern uint32_t adc_read[8];
uint8_t first_conversion = 1;
uint8_t index_adc = 0;
SI32_TIMER_A_start_high_timer(SI32_TIMER_0);
for( ;; )
{
ulTaskNotifyTake( pdTRUE, /* Clear the notification value before exiting. */
portMAX_DELAY ); /* Block indefinitely. */
index_adc = 0;
for (uint8_t i = 0; i < 8; i++)
{
if (first_conversion == 1)
{
adc_output_old[i] = 0;
adc_output_old128[i] = 0;
adc_output[i] = adc_read[i] >> 2;
adc_output128[i] = (adc_output[i]*8388)>>16;
if (adc_output128[i] >= 128)
{
adc_output128[i] = 127;
}
adc_number_send[index_adc] = i;
adc_value_send[index_adc] = adc_output128[i];
index_adc++;
if (i == 7)
{
first_conversion = 0;
}
}
else
{
adc_output_old[i] = adc_output[i];
adc_output_old128[i] = adc_output128[i];
adc_output[i] = (adc_read[i] >> 2) + (adc_output_old[i]*3/4);
adc_output128[i] = (adc_output[i]*8388)>>16;
if (adc_output128[i] >= 128)
{
adc_output128[i] = 127;
}
if (adc_output128[i] != adc_output_old128[i])
{
adc_number_send[index_adc] = i;
adc_value_send[index_adc] = adc_output128[i];
index_adc++;
}
}
}
if (index_adc != 0)
{
xSemaphoreTake(xMutexUsb, 0);
while(index_adc > 0)
{
SI32_USBEP_A_write_fifo_u8(SI32_USB_0_EP1, 0x01);
SI32_USBEP_A_write_fifo_u8(SI32_USB_0_EP1, adc_number_send[index_adc-1]);
SI32_USBEP_A_write_fifo_u8(SI32_USB_0_EP1, (uint8_t) adc_value_send[index_adc-1]);
index_adc--;
}
xSemaphoreGive(xMutexUsb);
vTaskResume(xTaskSendUSBControls);
}
index_adc = 0;
}
}
I also show you the FreeRTOSConfig.h
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( ( unsigned long ) 48000000 )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 7000 ) )
#define configMAX_TASK_NAME_LEN ( 10 )
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 0
#define configUSE_CO_ROUTINES 0
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
#define configMAX_PRIORITIES ( 5 )
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
#define configUSE_MUTEXES 1
/* 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 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
#define configKERNEL_INTERRUPT_PRIORITY 255
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 95 /* equivalent to priority 5. */
#endif /* FREERTOS_CONFIG_H */
I am a new user of FreeRTOS and new on the forum, if information are missing, don’t hesitate to ask me.
Thank you in advance for your help (sorry if there are mistakes in my English, I’m French ^^)
Thomas