Jump to content

    

STM32L151 + SDIO + FreeRTOS

Картина проясняется.

 

Есть две задачи.

Есть два несвязанных друг с другом прерывания. Первое прерывание выдаёт симафор в первую задачу, второе эвенты во вторую.

И время от времени из-за какого-то наложения прерываний друг на друга возникает BusFault.

Бит 9 в CFSR говорит о том что : "PRECISERR Precise data bus error . A data bus error has occurred, and the PC value stacked for the exception return points to

the instruction that caused the fault" Т.е. речь как раз о проблеме при выходе из прерывания, из стека в PC загружается неправильное значение !!!!

 

 

 

В регистр SCB->AIRCR есть поле PRIGROUP , в котором задаётся, какие из 8и битов обозначают приоритет а какие субприоритет.

Раньше это поле было 0, хотя такого значения в документации нету, непонятно что это значит.

Сейчас пишу значение 3, т.е. 4 старших бита означают приоритет, субприоритетов нет.

Проверяю что записалось и что больше никогда не меняется.

Для конфигурации прерываний использую стандартные Кейловские NVIC_SetPriority и NVIC_EnableIRQ. Они пушут приоритет в старшие 4 бита, как и надо.

Вроде бы теперь настроил правильно, но глюк остался.

Вопрос: где в операционке настраивается то же самое ? Каким образом операционка понимает, в какие биты нужно писать её приоритеты ?

 

 

 

Share this post


Link to post
Share on other sites
Бит 9 в CFSR говорит о том что : "PRECISERR Precise data bus error . A data bus error has occurred, and the PC value stacked for the exception return points to

the instruction that caused the fault" Т.е. речь как раз о проблеме при выходе из прерывания, из стека в PC загружается неправильное значение !!!!

Совсем не так. Случилась ошибка доступа к данным (скажем, обращение по несуществующему адресу), сохраненное значение PC содержит адрес инструкции, вызвавшей исключение.

 

Вроде бы теперь настроил правильно, но глюк остался.

Вопрос: где в операционке настраивается то же самое ? Каким образом операционка понимает, в какие биты нужно писать её приоритеты ?

Проверьте значения непосредственно в регистрах NVIC. В ОС нигде не настраивается, просто задается число для записи в регистр.

Share this post


Link to post
Share on other sites
Проверьте значения непосредственно в регистрах NVIC. В ОС нигде не настраивается, просто задается число для записи в регистр.

 

А какие вообще прерывания использует ОС и зачем ? Помимо системного тика. Зачем ей прерывания приоритетом выше чем configMAX_SYSCALL_INTERRUPT_PRIORITY 0x60 (т.е. 6) , и почему это значение разрешается устанавливать самому ?

Share this post


Link to post
Share on other sites

С приоритетом KERNEL_INTERRUPT_PRIORITY работают все прерывания ОС: SysTick, PendSV и SVCall.

Уровнем MAX_SYSCALL_INTERRUPT_PRIORITY задается максимальный приоритет, на котором может быть осуществлен системный вызов. Понятно, что в системе могут быть прерывания с более высоким приоритетом, которые не используют сервисы ОС. Для них и предусмотрено конфигурирование.

Share this post


Link to post
Share on other sites
С приоритетом KERNEL_INTERRUPT_PRIORITY работают все прерывания ОС: SysTick, PendSV и SVCall.

 

SysTick, PendSV в SCB_SHPR ОС устанавливает самые низкие, 0xF0 . Приоритет SVCall самый высокий 0 , и я не вижу места, где бы он устанавливался.

 

Share this post


Link to post
Share on other sites
Приоритет SVCall самый высокий 0 , и я не вижу места, где бы он устанавливался.

SVCall действительно не устанавливается, но он и используется однократно, так что все равно.

Share this post


Link to post
Share on other sites

Поэкспериментировал ещё :

 

Оказывается, если заменить выдачу из прерывания эвента на симафор, то всё работает. Причём дело даже не в выдаче эвента из прерывания, а просто в том, что использование функции ожидания эвента каким-то неудачным образом накладывается на момент прерывания, и вот при этом происходит Bus Fault . Что-то не так именно с эвентами !

Share this post


Link to post
Share on other sites

Сломается точно так же и с семафорами в конце концов. Смысл экспериментов в чем?

 

Ключи все у Вас в руках:

1. Имеем Precise data bus error

2. Есть адрес инструкции, его вызвавшей

3. Известны ошибочные адреса (BFAR), по которым было обращение

Порой достаточно даже одного п.3: по характеру данных можно установить виновника.

 

Попробуйте своим прерываниям выставить минимальный приоритет (0xF0), посмотрите, будут ли воспроизводится проблемы.

Share this post


Link to post
Share on other sites

Проблема решилась.

После перехода с версии FreeRTOS 8.0.0 на 8.2.0 её не стало.

Выходит , что 8.0.0 была с глюком.

В общей сложности потратил на ковыряние недели 2 чистого времени. Причём начал тратить ещё тогда, когда версия 8.2.0 ещё и не вышла.

Share this post


Link to post
Share on other sites
После перехода с версии FreeRTOS 8.0.0 на 8.2.0 её не стало.

Выходит , что 8.0.0 была с глюком.

Из первого, увы, никак не следует второе. В history ничего похожего нет.

Share this post


Link to post
Share on other sites

у меня аналогичное случалось при банальном переполнении стека, по умолчанию в кейле, например не достаточно для такого примера

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this