Loading...
 

SW4STM32 and SW4Linux fully supports the STM32MP1 asymmetric multicore Cortex/A7+M4 MPUs

   With System Workbench for Linux, Embedded Linux on the STM32MP1 family of MPUs from ST was never as simple to build and maintain, even for newcomers in the Linux world. And, if you install System Workbench for Linux in System Workbench for STM32 you can seamlessly develop and debug asymmetric applications running partly on Linux, partly on the Cortex-M4.
You can get more information from the ac6-tools website and download (registration required) various documents highlighting:

System Workbench for STM32


Generate Software Interrupt (SI) with STM32F· Discovery board with HAL drivers

Hi everyone,

I’m trying to work with software interrupts with my STM32F3 Discovery board. What I’m doing is, first of all, generate a 1 KHz signal with a timer. This signal works well, my problem is generating a SI each time the timer activates its callback. My code is the following:

/* USER CODE BEGIN 0 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim->Instance == TIM3){
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_1);
contador_timer++;
if (contador_timer == 100){
contador_timer = 0;
HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_10);
__HAL_GPIO_EXTI_GENERATE_SWIT(EXTI_SWIER_SWIER0);
}

}
}
/* USER CODE END 0 */

The last macro, HAL_GPIO_EXTI_GENERATE_SWIT(), is supose to activate a software interrupt in the line especified, in this case line 0 (EXTI_SWIER_SWIER0).

To control this line, I have a function like this:

void EXTI0_IRQHandler(void)
{
/* USER CODE BEGIN EXTI0_IRQn 0 */
if (__HAL_GPIO_EXTI_GET_IT(EXTI_SWIER_SWIER0) != RESET){
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_2);
osDelay(200);
}
}

I’m trying to generate a change on GPIO in PC2 every 200 ms, but with this code the output is a signal of 25 KHz period and I don’t know why.

Can anyone help me with this problem? Thank you in advance for your time.

Best regards.

Andreas


Thanks for your answer. I checked the timer configuration and it seems to works fine, the interruption of the timer goes every 1 ms as I want, the problem I have is with the delay of the software interrupt. I’ve replaces osDelay() with HAL_Delay(), which use the ticks of the clock of the system to calculate the delay:
weak void HAL_Delay(IO uint32_t Delay)
{
uint32_t tickstart = HAL_GetTick();
while((HAL_GetTick() - tickstart) < Delay)
{
}
}

But when I do these, the software interrupt never goes out the HAL_Delay(), because the system stop increasing the ticks. I don’t understand why because the system interruption have hight priority than the software interrupt ( I’ve set the first to priority 0 and the other to priority 5). So I don’t know how to make a delay in this interruption whitout interrupting any other process of the system with highest priority. That’s the problem, but thanks for your time.

Andreas


i’m scare you can’t use osdelay from an isr :-(

it never exit becasue the systcik piroity use for hal_tick is lower priority than the isr you are ( systick is lowest pri wiht freerrtos)
so inc tick can’t be served why you do not exit from you rISR :-( you may find same isue in some hal driver like i2c and spi sd etc ...

Even it is not nice to delay and keep cpu buzy in isr (speilay fi very high pri) you can use one of the 32bit timer wiht pescraler set to get 1KHz period
then read/use the 32 cnt value for a “safe ” delay or timing mesure while in isr.

that is typicaly what i do when i use freertos i overload (weak) the HAL_GetTick() to read the 32 bit timer CNT instead of using dwTick
(i also overload inctick to make dummy as icnremting dwtick isnto need then anymore )


Thanks for the answer diabolo, and sorry for not answering you earlier. I’ve read more information about FreeRTOS but I still couldn’t figure out how to make a timer properly. Now I’ve defined a timer of 1KHz frequency with the FreeRTOS API and a callback function like this:

/* Create the timer(s) */
/* definition and creation of myTimer01 */
osTimerDef(myTimer01, Callback01);
myTimer01Handle = osTimerCreate(osTimer(myTimer01), osTimerPeriodic, NULL);

/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
osTimerStart(myTimer01Handle,1);
/* USER CODE END RTOS_TIMERS */

/* Create the thread(s) */
/* definition and creation of defaultTask */
osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

In the callback I set a clock of 1KHz in a GPIO and every 100 ms I activate a SWI.

/* Callback01 function */
void Callback01(void const * argument)
{
/* USER CODE BEGIN Callback01 */
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_1);
contador_timer++;
if (contador_timer == 100){
contador_timer = 0;
flag_SI = 1;
HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_10);
//EXTI->SWIER |= EXTI_SWIER_SWIER0;
__HAL_GPIO_EXTI_GENERATE_SWIT(EXTI_SWIER_SWIER2);
}
/* USER CODE END Callback01 */
}

In the SWI I trie to set a GPIO and wait 200 ms until the next change of value, but the output change every 100 ms and I don’t know why.

void EXTI2_TSC_IRQHandler(void)
{
/* USER CODE BEGIN EXTI2_TSC_IRQn 0 */
if ((__HAL_GPIO_EXTI_GET_IT(EXTI_SWIER_SWIER2) != RESET) && (flag_SI == 1)){
//HAL_GPIO_WritePin(GPIOC,GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_2);
while(delay_SI > 0)
{
delay_SI = delay_SI - 1;
}
delay_SI = 200;
__HAL_GPIO_EXTI_CLEAR_IT(EXTI_SWIER_SWIER2);
flag_SI = 0;

}
/* USER CODE END EXTI2_TSC_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);
/* USER CODE BEGIN EXTI2_TSC_IRQn 1 */

/* USER CODE END EXTI2_TSC_IRQn 1 */
}


There is some manual for the correct configuration of FreeRTOS for STM32CubeMX?

Thanks.

France

Hi,

I don’t understand the use of your waiting loop in EXTI2_TSC_IRQHandler: you will just wait for a few microseconds, or even less, before setting delay_SI to 200. Where did you see a 200ms delay?

According to your code, you toggle GPIO1 every millisecond, and GPIO10 and GPIO2 every 100ms (the first two in the callback, the last in the software generated interrupt handler, which is triggered every 100ms). If you want GPIO2 to be toggled every 200ms you should have a static counter in the SW handler, and only toggle GPIO2 when it is equal to 2 (then reset it to 0).

Bernard (Ac6)