stm32f4 wakeup interrupt

Christian Mauderer list at c-mauderer.de
Sun Apr 28 07:27:05 UTC 2019


Am 27.04.19 um 16:40 schrieb Christian Mauderer:
> Am 24.04.19 um 10:00 schrieb Jython:
>> HI, ALL!
>> why the code stuck in wakeup handler while the RTC gets time work fine
>> i have checked some days, but no register error found, i suspect that
>> the handler function is the issue
>>
>>
>> // code
>> rtems_isr rtc_wakeup_handler(rtems_vector_number vector)
>> {
>>    
>>     uint32_t STM32F4_RTC_ISR = (*(volatile uint32_t *)(0x4000280C));
>>    
>>     // clear 10bit
>>     if(STM32F4_RTC_ISR & (1<<10))
>>     {
>>         //printk("wak\n");
>>         STM32F4_RTC_ISR &= ~(1<<10);
>>         STM32F4_RTC_ISR &= 0xfffffbff;
>>     }
>>    
>>     volatile uint32_t EXIT_PR = *(volatile uint32_t*)0x40013C14;
>>     printk("before clr %08x\n", EXIT_PR);
>>     EXIT_PR |= 1<<22;
>>    
>>     int i;
>>     for(i = 0; i < 1000; i++) i = i + 1 - 1;
>>     printk(" %08x\n", EXIT_PR);
>> }
>>
>>
>> the printed log attached,  why the EXIT_PR bit22 not cleared
>>
>>
> 
> Hello Jython,
> 
> your EXIT_PR seems to be slightly odd. What you do:
> 
>     volatile uint32_t EXIT_PR = *(volatile uint32_t*)0x40013C14;
> 
> This means you read the content of 0x40013C14 and write it to a 32 bit
> value.
> 
> Later you do
> 
>     EXIT_PR |= 1<<22;
> 
> This changes the _copy_ of the value.
> 
> What you most likely want to do is the following:
> 
>     volatile uint32_t *EXIT_PR = (volatile uint32_t*)0x40013C14;
>     *EXIT_PR |= 1<<22;
> 
> This would change the value at 0x40013C14 and not only your copy.
> 
> By the way: You tried to do a busy wait. That's not a good idea in an
> interrupt. The way you implemented it, the compiler most likely even
> just removes it:
> 
>     int i;
>     for(i = 0; i < 1000; i++) i = i + 1 - 1;
> 
> The compiler most likely notices that this statement has no effect. If
> you would like to implement a busy wait that way, you should use a
> volatile int.
> 
> Note that RTEMS has a rtems_counter_delay_nanoseconds() function. That
> is a busy wait loop. It is based on the CPU counter and provides a
> method for short busy waits for example during driver initialization.
> But again: Please don't use busy waits in Interrupts. It's not a good
> idea and will lead to problems sooner or later.
> 
> Best regards
> 
> Christian Mauderer

Oh, and I just noted: You are writing a one to the register but expect
the bit to be cleared. So it is most likely a "write one to clear"
register (which is quite common for interrupt flags). In that case you
maybe don't want to use a

    *EXIT_PR |= 1<<22;

but a

    *EXIT_PR = 1<<22;

Otherwise you clear other flags in that register too. Please have a look
at the reference manual of your chip to decide that.

Best regards

Christian


More information about the users mailing list