I guess I found a bug in Timer.cpp (mbed OS module) I'll explain what is happening (Correct me if I am wrong). Then I will explain another problem happening, I can't even debug or think of root cause, so I'd really appreciate it if someone brainstorm with me.
So First let's talk about first bug in Timer.cpp, there are two function
int Timer::read_us() {
core_util_critical_section_enter();
int time = _time + slicetime();
core_util_critical_section_exit();
return time;
}
int Timer::slicetime() {
core_util_critical_section_enter();
int ret = 0;
if (_running) {
ret = ticker_read(_ticker_data) - _start;
}
core_util_critical_section_exit();
return ret;
}
*
As you can see, read_us() calls slicetime() inside critical section, while slicetime() contain critical section. So what happen is we enter nested critical section and the counter inside the critical section increment before it's decremented.
*
void core_util_critical_section_enter(void)
{
bool interrupts_disabled = !core_util_are_interrupts_enabled();
__disable_irq();
/* Save the interrupt disabled state as it was prior to any nested critical section lock use */
if (!interrupt_enable_counter) {
critical_interrupts_disabled = interrupts_disabled;
}
/* If the interrupt_enable_counter overflows or we are in a nested critical section and interrupts
are enabled, then something has gone badly wrong thus assert an error.
*/
MBED_ASSERT(interrupt_enable_counter < UINT32_MAX);
// FIXME
#ifndef FEATURE_UVISOR
if (interrupt_enable_counter > 0) {
MBED_ASSERT(interrupts_disabled);
}
#else
#warning "core_util_critical_section_enter needs fixing to work from unprivileged code"
#endif /* FEATURE_UVISOR */
interrupt_enable_counter++;
}
void core_util_critical_section_exit(void)
{
/* If critical_section_enter has not previously been called, do nothing */
if (interrupt_enable_counter) {
// FIXME
#ifndef FEATURE_UVISOR
bool interrupts_disabled = !core_util_are_interrupts_enabled(); /* get the current interrupt disabled state */
MBED_ASSERT(interrupts_disabled); /* Interrupts must be disabled on invoking an exit from a critical section */
#else
#warning "core_util_critical_section_exit needs fixing to work from unprivileged code"
#endif /* FEATURE_UVISOR */
interrupt_enable_counter--;
/* Only re-enable interrupts if we are exiting the last of the nested critical sections and
interrupts were enabled on entry to the first critical section.
*/
if (!interrupt_enable_counter && !critical_interrupts_disabled) {
__enable_irq();
}
}
}
*
Inside function void core_util_critical_section_enter(void), if counter interrupt_enable_counter>0, MBED should assert and go to mbed_die() function, which is what happens because there are two consecutive calls for function void core_util_critical_section_enter(void).
The second issue, which is related to my implementation,: I have been porting mbed to Tiva C using ARM GCC, I've successfully implemented GPIO and us_ticker, and was function alright so far, Until, I started to implement UART to communicate with ESP WIFI module. When there's UART receiver interrupt, Something weird happens to the counter inside the function void core_util_critical_section_enter(void), the counter suddenly increase to several hundreds. And the function calls before core_util_critical_section_enter(void) are always different and the incremented value are always different too. but when I force the counter to 0, the program continues normally (but not functioning the way I want). So the second question is, Can you think how should I debug this issue? or how could I exclude the problem one by one. You can find my code in the following link :
One last question, How to make sure that the compiler is not aligning the variable inside the memory? I am using Eclipse
Aucun commentaire:
Enregistrer un commentaire