реклама на сайте
подробности

 
 
> Чтение внутренних регистров STM32
hardgame
сообщение May 16 2016, 14:10
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 15-08-12
Из: Украина
Пользователь №: 73 140



В стареньком ADS 1.2 можно было в функции С делать вставку inline asm ссылкой сразу на внутренние регистры r0-r15. Столкнулся в Кеил, что предыдущие inline asm не компилится. А вот что нашел в доках
"The inline assembler provides no direct access to the physical registers of an ARM processor. If an ARM register name is used as an operand in an inline assembler instruction it becomes a reference to a variable of the same name, and not the physical ARM register."
Есть ли способ чтения внутренних регистров, возможно средствами cmsis, или нужно создавать asm раздел и увязывать?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Alechek
сообщение May 16 2016, 16:09
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 241
Регистрация: 15-11-05
Из: Челябинск
Пользователь №: 10 882



Единственное, для чего мне это понадобилось, это скинуть дамп регистров при возникновении Fault.
Пришлось написать вставку на ASM для копирования регистров в память (структуру). Остальная работа на C.
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 17 2016, 02:00
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Alechek @ May 16 2016, 22:09) *
Единственное, для чего мне это понадобилось, это скинуть дамп регистров при возникновении Fault.
Пришлось написать вставку на ASM для копирования регистров в память (структуру). Остальная работа на C.

И где гарантия, что компилятор при очередной перекомпиляции, не разместит какие-то переменные в регистрах которые Вы хотели сохранить до вашей вставки?
Такое надо делать целиком в asm-функциях. Напишите ISR fault-ов полностью на asm, там всё элементарно.

Цитата(adnega @ May 17 2016, 01:59) *
Реально, по значениям LR, PC, R0-R4 в подавляющем большинстве случаев можно найти причину фэйла.

Не знаю не знаю... У меня сохраняются все регистры + дамп стека. И то часто не хватает.

Цитата(aaarrr @ May 17 2016, 02:27) *
У меня алгоритм такой:
Исключение -> запись контекста исключения в RAM -> перезапуск -> сохранение контекста на внешнем носителе или передача на отладочный сервер -> возобновление работы

У меня все fault-ы примерно так же обрабатываются, только кроме дампа регистров сохраняю ещё и дамп текущего стека.
Отличия:
Для release-сборки: всё так же, кроме передачи на отладочный сервер.
Для debug-сборки: вместо перезапуска - переинициализация железа в минимальный дефолт-конфиг trap-режима и зацикливание в цикле периодического вывода инфы о событии в лог (UART). Чтобы не пропускать такие ошибки, а исправлять сразу.
Этот-же механизм используется для обработки программных критических ошибок (через SVC).

Цитата(aaarrr @ May 17 2016, 03:24) *
На удаленном оборудовании пару раз выручало. Всех подробностей не вспомню, но потребовалось

Помогает очень часто в обнаружении редко проявляющихся ошибок. Когда тестируем сразу несколько десятков (а то и сотни) устройств в течение длительного времени (дни/недели непрерывной работы).
С JTAG-ом тут не посидишь, а вот устройства защёлкнувшиеся в trap-цикле сразу видны. А потом - по регистрам-стеку ищем причину.
И если такие ошибки проявились уже на объектах заказчика - тут другого выбора нет, очень помогает.

Без дампа стека вообще мало когда эта инфа помогает. Типичная ситуация: срабатывание исключения MPU защиты памяти при попытке обращения к недопустимой памяти изнутри memcpy().
От регистров почти никакого толку - в каком месте кода произошёл сбой? Зато по стеку можно легко проследить цепочку вызовов. Уже сколько так багов нашли.
Go to the top of the page
 
+Quote Post
Alechek
сообщение May 17 2016, 05:22
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 241
Регистрация: 15-11-05
Из: Челябинск
Пользователь №: 10 882



Цитата(jcxz @ May 17 2016, 07:00) *
И где гарантия, что компилятор при очередной перекомпиляции, не разместит какие-то переменные в регистрах которые Вы хотели сохранить до вашей вставки?
Такое надо делать целиком в asm-функциях. Напишите ISR fault-ов полностью на asm, там всё элементарно.

С легкой руки (для IAR)
CODE
__stackless void FaultHandler(void * p_base, unsigned long EXC_RETURN)
{
SaveContext(p_base, EXC_RETURN);
EXPT.VERSION = APP_Get_FwVersion();
gMarker = EXCEPTION_MARKER;
#ifdef NDEBUG
SYS_Reset();
#else
while (1);
#endif
}

__stackless __irq void HardFaultHandler(void)
{
if (SCB->HFSR & SCB_HFSR_DEBUGEVT_Pos)
return;
FaultHandler((void*)( (__get_LR() & BIT(2)) ? __get_PSP() : __get_MSP()),
__get_LR());
}

__stackless __irq void MemoryFaultHandler(void)
{
FaultHandler((void*)( (__get_LR() & BIT(2)) ? __get_PSP() : __get_MSP()),
__get_LR());
}

__stackless __irq void BusFaultHandler(void)
{
FaultHandler((void*)( (__get_LR() & BIT(2)) ? __get_PSP() : __get_MSP()),
__get_LR());

}

__stackless __irq void UsageFaultHandler(void)
{
FaultHandler((void*)( (__get_LR() & BIT(2)) ? __get_PSP() : __get_MSP()),
__get_LR());

// while(1);
}


void SaveContext(void * p_base, unsigned long EXC_RETURN)
{
EXPT.Registers = *(struct exception_saved_context * )p_base;
EXPT.SP = (DWORD)p_base + sizeof(struct exception_saved_context);

EXPT.Status.dwRaw = SCB->CFSR;
EXPT.Exception = (int_source_t)(SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk);
EXPT.EXC_RETURN = ( EXPT.Status.BFSR.BFARVALID) ? SCB->BFAR : EXC_RETURN;
SCB->CFSR = 0;

EXPT.HeapFree = OS_MEMORY_AVAILABLE();
EXPT.ShedulerState = OS_GET_SHEDULER_STATE();
EXPT.Context.StackFree = OS_GET_TASK_STACK_WATERMARK(OS_GET_CURRENT_TASK_HANDLE());
strncpy(EXPT.Context.Name, (char*)OS_GET_CURRENT_TASK_NAME() , sizeof(EXPT.Context.Name));
EXPT.Context.Name[sizeof(EXPT.Context.Name)-1] = '\0';


Для CORTEX ядра все получается и без ASM функций.
А вот для ARM делал вставку на ASM с обработчиками исключений и функцией сохранения регистров.

В большинстве случаев эта информация помогает на столе.
В основном в исключения валимся при переполнении стека. Поэтому место возникновения исключения, при наличии RTOS, мало что скажет. Главное состояние планировщика, текущая задача(последняя в случае переключения контекста) и свободное место в стеке задачи.
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 17 2016, 08:48
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Alechek @ May 17 2016, 11:22) *
__stackless void FaultHandler(void * p_base, unsigned long EXC_RETURN)
{
SaveContext(p_base, EXC_RETURN);
...
Для CORTEX ядра все получается и без ASM функций.

Ещё раз: Где гарантия, что компилятор не вставит перед Вашей SaveContext() например создание стекового фрейма с занесением указателя на него в любой из R4-R11?
Типа:
PUSH {R7, LR}
ADD R7, SP, #N
...

или ещё чего, чего ему вздумается.
Go to the top of the page
 
+Quote Post
scifi
сообщение May 17 2016, 09:01
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(jcxz @ May 17 2016, 11:48) *
Ещё раз: Где гарантия, что компилятор не вставит перед Вашей SaveContext() например создание стекового фрейма с занесением указателя на него в любой из R4-R11?

Как где? __stackless же. У gcc есть аналогичная штука - naked.
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 17 2016, 10:33
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(scifi @ May 17 2016, 15:01) *
Как где? __stackless же. У gcc есть аналогичная штука - naked.

А это обязательное или только рекомендуемое как inline? А функции, которые из FaultHandler() вызываются тоже все __stackless?
И стек - это для примера. Что угодно, например - в какой-либо регистр может заранее положить указатель на секцию данных, либо какие-то другие данные.
Использование регистров внутри си-функции - по усмотрению компилятора, любые домыслы по их содержимому - потенциальные грабли.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- hardgame   Чтение внутренних регистров STM32   May 16 2016, 14:10
- - Forger   Цитата(hardgame @ May 16 2016, 17:10) Ест...   May 16 2016, 14:31
|- - prottoss   Цитата(Forger @ May 16 2016, 20:31) Я бы ...   May 16 2016, 14:35
||- - Forger   Цитата(prottoss @ May 16 2016, 17:35) А е...   May 16 2016, 14:44
||- - prottoss   Цитата(Forger @ May 16 2016, 20:44) Вот п...   May 16 2016, 16:17
|- - scifi   Цитата(Forger @ May 16 2016, 17:31) Я бы ...   May 16 2016, 15:05
|- - adnega   Цитата(Alechek @ May 16 2016, 19:09) Един...   May 16 2016, 16:20
||- - aaarrr   Цитата(adnega @ May 16 2016, 19:20) Зачем...   May 16 2016, 19:42
||- - adnega   Цитата(aaarrr @ May 16 2016, 22:42) А R4-...   May 16 2016, 19:59
||- - aaarrr   Цитата(adnega @ May 16 2016, 22:59) Меня ...   May 16 2016, 20:27
||- - adnega   Цитата(aaarrr @ May 16 2016, 23:27) У мен...   May 16 2016, 20:38
||- - aaarrr   Цитата(adnega @ May 16 2016, 23:38) А на ...   May 16 2016, 21:24
- - prottoss   ИМХО - лучше всего сделать отдельный ассемблерный ...   May 16 2016, 16:21
- - hardgame   Всем Спасибо за комментарии. Регистры были необход...   May 16 2016, 17:35
- - Alechek   jcxz, если делать что-то бездумно - то возможны лю...   May 17 2016, 11:00
|- - adnega   Цитата(Alechek @ May 17 2016, 14:00) И не...   May 17 2016, 11:10
||- - Копейкин   Цитата(adnega @ May 17 2016, 14:10) Листи...   May 17 2016, 11:34
||- - adnega   Цитата(Копейкин @ May 17 2016, 14:34) Ком...   May 17 2016, 11:51
||- - Alechek   Цитата(adnega @ May 17 2016, 16:41) Зачем...   May 17 2016, 11:57
|- - jcxz   Цитата(Alechek @ May 17 2016, 17:00) jcxz...   May 18 2016, 05:05
- - Alechek   adnega, речь немного не про такой случай. Использо...   May 17 2016, 11:40
- - Alechek   jcxz, сравнивать неопределеность, исходящую от ком...   May 18 2016, 06:00


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 26th June 2025 - 14:22
Рейтинг@Mail.ru


Страница сгенерированна за 0.01463 секунд с 7
ELECTRONIX ©2004-2016