Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: HardFault handler M0
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
toweroff
Вот такая вот возникла потребность...
для M3 есть, когда-то давно был сделан, но для M0 не подходит
Хоть посмотреть, откуда вылетели...
Смотрел тырнеты всякие, только что-то оформленное для того же M3 и M4

Есть что-то простое, хоть PC посмотреть
Сергей Борщ
Если совсем простое:
CODE
void HardFault_Handler(void)
{
    volatile int i = 0;
    while(!i)
       ;
}

В отладчике меняем i, выходим из обработчика в точку возникновения исключения.
toweroff
Цитата(Сергей Борщ @ Feb 15 2017, 23:24) *
Если совсем простое:

ого...

Код
void rt_sem_psh (P_SCB p_CB) {
  /* Check if task has to be waken up */
  P_TCB p_TCB;

  if (p_CB->p_lnk != NULL) {
    /* A task is waiting for token */
    p_TCB = rt_get_first ((P_XCB)p_CB);
    rt_rmv_dly (p_TCB);
    p_TCB->state   = READY;
    p_TCB->ret_val = OS_R_SEM;
    rt_put_prio (&os_rdy, p_TCB);
  }
  else {
    /* Store token */
    p_CB->tokens++;
  }
}


вылет тут
Код
  if (p_CB->p_lnk != NULL) {


и как понимать эту обработку семафора?
firew0rker
Посмотрите значение указателя p_CB.
toweroff
Цитата(firew0rker @ Feb 16 2017, 04:47) *
Посмотрите значение указателя p_CB.

0x00000001
Сергей Борщ
QUOTE (toweroff @ Feb 16 2017, 08:34) *
0x00000001
И что вы ожидатете получить с таким указателем? Мало того, что он указывает на вектора прерываний, так еще и невыровнен (из-за этого и исключение). В общем ищите, откуда в него попадает такое дивное число.
ViKo
Цитата(toweroff @ Feb 15 2017, 23:59) *
ого...

Код
/*!****************************************************************************
  @author    ViKo
  @brief    Simple HardFault Handler
  @details    В пошаговом режиме переставить программный счетчик, выйти,
            PC будет содержать команду, следующую за вызвавшей сбой
  */
__asm void HardFault_Handler(void)
{
  B .        ; бесконечный цикл
  BX LR        ; установить программный счетчик сюда
}
toweroff
Цитата(Сергей Борщ @ Feb 16 2017, 10:55) *
В общем ищите, откуда в него попадает такое дивное число.

Интересно, что вызов этой функции происходит один раз, но сразу в яблочко

Кстати, попутно вот такой вопрос:
Есть функция, через которую в юарт валится отладочная информация. Вызывать может кто угодно. Чем ее правильнее закрывать, бинарным семафором или мьютексом? По сути тоже самое
toweroff
В общем докопался. Из прерывания отправлялся сигнал задаче, ID которой был нарушен
ohmjke
Цитата(toweroff @ Feb 16 2017, 12:21) *
Есть функция, через которую в юарт валится отладочная информация. Вызывать может кто угодно. Чем ее правильнее закрывать, бинарным семафором или мьютексом?


Для безопасного доступа к разделяемым ресурсам используются мьютексы.

Цитата(toweroff @ Feb 16 2017, 12:21) *
По сути тоже самое


Не похоже - https://stackoverflow.com/questions/62814/d...phore-and-mutex
toweroff
Цитата(ohmjke @ Feb 16 2017, 19:15) *


Цитата
(A mutex is really a semaphore with value 1.)

и как это противоречит моему бинарному семафору?
ohmjke
Там помимо этого сообщения есть много других, где объясняется, почему это не одно и то же.
Даже к этому сообщению есть комментарии:
Цитата
... but this is regarding mutex vs counting semaphore. The question was asked about binary. – Roman Nikitchenko Nov 10 '09 at 7:47
14

While what is said by david is correct, but it is NOT the answer to the question asked. Mladen Jankovic answer is the answer to the question asked, where point is made to differentiate "binary-semaphore" vs "mutex". – Ajeet Ganga Aug 21 '11 at 15:45
8

Unfortunately, this incorrect answer has more votes than the best answer by @Benoit

@JacobRitchie the problem is with the statement that says "A mutex is really a semaphore with value 1" but that is not the case. ThreadA and only ThreadA can increment (and hence release) the mutex that it decremented whereas ThreadB can increment the binSemaphore decremented by ThreadA, which also happens to be the answer to the question in question.
toweroff
Цитата(ohmjke @ Feb 17 2017, 21:49) *
Там помимо этого сообщения есть много других, где объясняется, почему это не одно и то же.
Даже к этому сообщению есть комментарии:

еще раз. Семафор с числом вхождений 1. Кто схватил - тот и пользуется, пока не освободит. Кто и как его может нарушить?
ohmjke
Цитата(toweroff @ Feb 17 2017, 23:11) *
еще раз. Семафор с числом вхождений 1. Кто схватил - тот и пользуется, пока не освободит. Кто и как его может нарушить?


Что же не ясно?
Цитата
Note that with a binary semaphore, it is OK for B to take the semaphore and A to give it.


Даже в википедии написано:
Цитата
Мьютекс отличается от семафора тем, что только владеющий им поток может его освободить, т.е. перевести в отмеченное состояние


Это если говорить о всем том, что пишут в данном случае.
А вообще, у меня сложилось впечатление, что каждый разработчик ОС вкладывает свой смысл в понятие бинарного семафора.
К примеру, из описания мьютексов в TNKernel (http://www.pic24.ru/doku.php/tnkernel/ref/mutex/intro):
Цитата
Мютекс представляет собой двоичный семафор с дополнительными свойствами (например, протоколы обхода неограниченной инверсии приоритетов).
toweroff
У меня лыжи, наверное, не едут. Если у семафора "ключей" > 1, то оно да, один поток может освободить, другой взять освободивщийся "ключ"
Но когда ключ один, его освободит только тот, кто занял. И пока ключ занят, никто другой не войдет...
Хотя, где-то тоже читал, что для reentrant функций правильно использовать мьютекс... Хрен поймешь их.
По сути, у меня с мьютексами работает, но прояснить на будущее сей момент не помешает точно
MoskWin32
Цитата(toweroff @ Feb 16 2017, 12:21) *
Чем ее правильнее закрывать, бинарным семафором или мьютексом?


Как альтернатива для функции потокобезопасного вывода - блокировка планировщика(на примере FreeRTOS):
Код
void vPrintString( const char *pcString )
{
    /* Print the string, suspending the scheduler as method of mutual
    exclusion. */
    vTaskSuspendAll();
    {
        sprintf( cBuffer, "%s", pcString );
        consoleprint( cBuffer );
    }
    xTaskResumeAll();
}
jcxz
Цитата(MoskWin32 @ Mar 2 2017, 17:19) *
Как альтернатива для функции потокобезопасного вывода - блокировка планировщика(на примере FreeRTOS):
...
consoleprint( cBuffer );

...и убивается весь смысл многозадачности. Выполнение превращается в суперцикл.
Это даже уже не говоря о том что лесом идут все приоритеты задач.
Если так пишете - значит Вы не поняли зачем вообще нужна многозадачная ОС.
MoskWin32
Цитата(jcxz @ Mar 2 2017, 19:55) *
...и убивается весь смысл многозадачности. Выполнение превращается в суперцикл.


Я понимаю, конечно на время вывода сообщения система "стопорится". Я использую это только для отладки чего-либо, в местах под макросом #ifdef _DEBUG_ANYTHING.
В рабочем приложении такого конечно нет.
Функция взята из учебника "FreeRTOS на Cortex-M3". Не такой уж и бред, если понимать, в каком контексте её можно использовать.
jcxz
Цитата(MoskWin32 @ Mar 2 2017, 19:35) *
Я понимаю, конечно на время вывода сообщения система "стопорится". Я использую это только для отладки чего-либо, в местах под макросом #ifdef _DEBUG_ANYTHING.
В рабочем приложении такого конечно нет.
Функция взята из учебника "FreeRTOS на Cortex-M3". Не такой уж и бред, если понимать, в каком контексте её можно использовать.

Один из главных плюсов использования ОС это: полезное использование времени процессора во время выполнения операций ввода/вывода.
Т.е. - например когда одна задача, как у вас, ждёт готовности FIFO UART-а принять очередной передаваемый байт, другая в этой время получает время CPU и выполняет полезную работу.
В суперцикле это невозможно, аналогично как и в приведённом Вами куске кода.
Плюс также - время реакции критичных по времени сервисов существенно меньше суперцикла. А у Вас, при выводе чего-то существенного в порт таким способом, все такие сервисы будут в пролёте.
Использовать такое для отладки тоже не имеет смысла, так как, при включении такой отладки, поведение программы сильно меняется (работа перестаёт быть многозадачной) и соответственно результаты отладки бессмысленны (отлаживается совсем не то ПО, которое нужно).
Если нужно корректное разделение ресурса (буфера вывода UART), то самое правильное - использовать семафор.
Можно использовать и запрет прерываний или запрет шедулера, но только на время вывода в программный буфер UART, а не на время вывода в IO-порт UART.
MoskWin32
jcxz, спасибо за разъяснение. Я все это понимаю, и полностью согласен.
Но если 1 тик шедулера = 1 мс, то на 115200бод/с можно успеть передать 11 символов. Если это будут сообщения типа "PING:ok" или "timeout", то ничего ведь страшного не случится?
Т.е. 1-2 тика не такой уж и криминал в этом случае? Все зависит от требований к времени реакции, конечно.
К тому же прерывания не запрещаются при блокировке шедулера и в некотором смысле многозадачность сохраняется.
По поводу защиты буфера - тогда нужно гарантировать, что все операции через UART для всех задач будут организованы только через него.
Ладно, это всё - скорее мои нелепые попытки оправдаться, знаю laughing.gif
zltigo
Цитата(MoskWin32 @ Mar 3 2017, 17:48) *
Но если 1 тик шедулера = 1 мс, то на 115200бод/с можно успеть передать 11 символов.

Много больше, если для передачи используется буфер, то сброс вывода в буфер просходит на порядки быстрее, чем вывод в нефифофированный порт.
Ну а за такой вывод через промежуточный буфер:
Код
sprintf( cBuffer, "%s", pcString );
        consoleprint( cBuffer );

Надо лишать права писать учебники пожизненно.

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.