FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [May 2013 Threads] InterruptionPosted by Do on May 23, 2013 Hello, This is the first time taht i create a FreeRtos project so i started with a programm that allows me to turn on a led wehn i press a button, but i don't know how to create a button interruption. I started with this program: int main(void) {
prvSetupHardware();
setbuf(stdout,NULL); /* Start the scheduler. */ printf("########################## MINI PROJET CS530 ################\n"); vTaskStartScheduler(); xTaskHandle xLed,xbutton,xledInitTask,xledTaskFunc;
/* Will only get here if there was not enough heap space to create the idle task. */ return 0; /* creation semaphore et taches , */ xSemaphore0 = xSemaphoreCreateCounting( 1,0); if( xSemaphore0 != NULL ) { printf("DEBUG : CREATION SEMAPHORE SUCCED\n"); } /* TASKPRIORITY1 = (tskIDLE_PRIORITY + 1) et TASKPRIORITY1 = (tskIDLE_PRIORITY + 2) */
/* tache de haute priorite */ xTaskCreate(ledTaskFunc,"TASK1", configMINIMAL_STACK_SIZE+1000 , NULL, TASKPRIORITY1,&xledTaskFunc);
/* Create the queue used by the LCD task. Messages for display on the LCD are received via this queue. */ g_lcdQueue = xQueueCreate( LCD_QUEUE_SIZE, sizeof( LcdMsg ) );
xTaskCreate(lcdTaskFunc, "Task2", configMINIMAL_STACK_SIZE * 2, NULL, 2, NULL);
} /*-----------------------------------------------------------*/
static void prvSetupHardware(void) {
USART_InitTypeDef USART_InitStructure;
/* Enable GPIOA, GPIOB, GPIOC, GPIOD, GPIOE and AFIO clocks */ RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE);
/* Set the Vector Table base address at 0x08000000 */ #ifdef IAP_VECT_TAB_RELOCATE NVIC_SetVectorTable(NVIC_VectTab_FLASH_RELOCATED, 0x0); #else NVIC_SetVectorTable( NVIC_VectTab_FLASH, 0x0 ); #endif
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
/* Configure HCLK clock as SysTick clock source. */ SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
/* Configure UART */ USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
STM_EVAL_COMInit(COM2, &USART_InitStructure);
}
/*-----------------------------------------------------------*/
int ledInitTask(void *pParams) {
unsigned long n; LedInitParams *params; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
params = (LedInitParams*)pParams;
/* Enable GPIOD, GPIOE clocks */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE );
/* Configure PD13 output push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init( GPIOD, &GPIO_InitStructure );
// Enable timer clocks RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2, ENABLE );
TIM_TimeBaseStructInit( &TIM_TimeBaseStructure );
// Time base configuration for timer 2 - which generates the interrupts. n = (configCPU_CLOCK_HZ / params->toggleFrequency);
TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit( TIM2, &TIM_TimeBaseStructure ); TIM_ARRPreloadConfig( TIM2, ENABLE );
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 13; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init( &NVIC_InitStructure );
return 0; }
void ledTaskFunc(void *pParams) { TIM_ClearITPendingBit(TIM2, TIM_IT_Update); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); TIM_Cmd(TIM2, ENABLE);
for (;;) { if ( xSemaphoreTake(xSemaphore0, portMAX_DELAY) == pdTRUE ) {
GPIO_WriteBit( GPIOD, GPIO_Pin_13, Bit_SET);
} }
}
RE: InterruptionPosted by Richard on May 23, 2013 How an interrupt is generated is completely dependent on the hardware, not the RTOS. You don't say as much but it looks from your code that you are using the STM32 libraries.
Test your interrupt generation code without the RTOS first. You can use the libraries to configure the interrupt, then sit in a while(1) loop with a break point in the interrupt handler to ensure the interrupt triggers when you expect. Once you know the interrupt is working you can add the code to a working FreeRTOS project.
As you are using FreeRTOS I assume you want the task to handle the LED, rather than doing it directly in the interrupt. If that is the case then you need to ensure the priority of the interrupt is less then configMAX_LIBRARY_SYSCALL_INTERRUPT_PRIORITY, and that all the STM32 priority bits are assigned as preemption priority bits, not sub-priority bits. This is explained on this page: http://www.freertos.org/RTOS-Cortex-M3-M4.html
You then need to signal the task from the interrupt. The most common way of doing that is using a semaphore. See the function vTaskApplicationTickHook() on http://www.freertos.org/Hardware-independent-RTOS-example.html to see how a semaphore is given from an interrupt (the tick hook function in the example is called from an interrupt) and prvEventSemaphoreTask() on the same page to see how a semaphore is used to synchronise with the interrupt. The API documentation on the website and demos in the FreeRTOS download will show you how to context switch from the ISR.
Regards.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|