[Решено] hal_systick_callback не работает над Nucleo-F103RB в Arduino IDE

Дакли
Солнце 03 сентября 2017 22:47
HAL_SYSTICK_CALLBACK работает на NUCLEO-F103RB с использованием STM32CUBEMX/TRUESTUDIO, но не при использовании Arduino IDE с STM32Cores от ST-Microelectronics версии 2017.8.31. Прикрепленная эскиза Arduino Sketch не генерирует какое -либо сообщение об ошибке, но переменная OneScount никогда не уменьшается, как показано в серийном мониторе. Я предполагаю, что компилятор GCC в Arduino IDE не поддерживает атрибут __weak, связанный с подпрограммой HAL_SYSTICK_CALLBACK в STM32F1XX_HAL_CORTEX.c Файл.

Rogerclark
Солнце 03 сентября 2017 11:09
Обычно Systick используется Millis () и Delay () и т. Д. Arduino Core, но я не уверен, что это так с ядром STM.

Дакли
Пн сентября 04, 2017 1:28
Да, ядра Arduino использует один из его таймеров для Millis () и Delay (), в то время как в ядрах STM32 есть выделенный таймер Systick для получения 1 MSEC прерываний. Существует ряд процедур HAL, которые поддерживают использование этого таймера Systick для управления задачами планирования, и одним из них является функция hal_systick_callback (). Например, если вы в C: \ users \<имя пользователя>\ Appdata \ local \ arduino15 \ packages \ stm32 \ hareware \ stm32 \ 2017.8.31 \ System \ Drivers \ stm32f1xx_hal_driver \ src \ stm32f1xx_hal_cortex.c Файл, вы найдете код для серии процедур NVIC и Systick, включая
void hal_systick_irqhandler (void), который вызывает hal_systick_callback (). Подпрограмма hal_systick_callback () определяется следующим образом:
/**
* @brief Systick обратный вызов.
* @retval нет
*/
__weak void hal_systick_callback (void)
{
/* Примечание: эта функция не должна быть изменена, когда требуется обратный вызов,
HAL_SYSTICK_CALLBACK может быть реализован в пользовательском файле
*/
}
Для компилятора GCC атрибут «__weak» означает, что компиляция GCC заключается в использовании этого кода для определения по умолчанию этой подпрограммы, если только пользователь не дает свое собственное определение для этой рутины (i.эн. Без атрибута __weak), и в этом случае компилятор GCC должен использовать определение пользователя. Эта возможность широко используется для определения процедур прерывания держателя по умолчанию/месту для заполнения местоположения вектора прерывания микропроцессоров STM32.
То, что я и другие используют эту возможность микропроцессора STM32.
Таким образом, моя простая подпрограмма hal_systick_callback устанавливает один из них один раз в секунду, а мой основной процедурный цикл проверяет этот флаг, чтобы увидеть, пришло ли время что -то сделать, а затем очистит этот флаг.
В качестве примера: для правильного управления двигателем важно периодически измерять вращение вала двигателя и обновлять привод двигателя. Это лучше всего можно сделать, используя временное прерывание для чтения позиции вала двигателя, обновления значения привода двигателя и установив флаг, который планирует подпрограмму, которая использует положение вала для вычисления следующего значения привода двигателя.
Это именно то, что я хочу использовать hal_systick_callback для. То есть каждые 50 клещей (я.эн. 20 Гц) Прочитайте положение вала двигателя (с использованием возможностей квадратурного декодера STM32) и обновить значение ШИМ двигателя.
Извините за то, что был так долго завернут больше информации, чем я уверен, что вам интересно.

Рик Кимбалл
Пн, сентябрь 04, 2017 1:35 утра
В то время как ваш подход может работать с основным ядром HAL, это действительно не очень дружелюбно Arduino. Вы можете сделать то же самое, сделав вызов из вашей функции Loop () или добавив Serialevent функция обработчика.
volatile bool oneSecFlag = false; void setup() { // put your setup code here, to run once: Serial.begin(9600); delay(100); Serial.println("Hello World"); Serial.print("HAL Version = "); Serial.println(HAL_GetHalVersion()); } void loop() { process(); // put your main code here, to run repeatedly: if (oneSecFlag) { Serial.println("One Second Event"); Serial.print("millis() = "); Serial.println(millis()); oneSecFlag = false; } } void process() { static unsigned next_ms = 1000; unsigned curr = millis(); if ( curr >= next_ms ) { next_ms = (curr + 1000) - (curr % 1000); oneSecFlag = true; } }

Rogerclark
Пн, сентябрь 04, 2017 2:50 утра
@dackley

Предполагая, что вы еще не используете все остальные таймеры аппаратного обеспечения, почему бы вам просто не использовать один из таймеров и настраивать его на прерывание каждые 50 мс

Rogerclark
Пн сентября 04, 2017 2:57 утра
Рик

Разве Serialevent не является полным неправильным в Arduino API.

Он просто вызывается в основном после возврата loop ()

Я проверил ядро ​​STM, и именно так они справляются с этим

https: // github.com/stm32duino/arduino_c ... в.CPP#L54

я.E Это была давняя проблема, когда люди (включая меня) предполагали, что Serialevent был асинхронным обработчиком вызовов для сериала, но это не так.

Даниэфф
Пн, сентябрь 04, 2017 7:52 утра
.Файлы INO составлены с CPP, поэтому имена искажены, попробуйте с C Scine: extern "C" void HAL_SYSTICK_Callback(void) {...

fpistm
Пн сентября 04, 2017 9:31
На самом деле, hal_systick_callback не используется.
Используется systick_handler, он определяется в часах.C: /** * @brief Function called when t he tick interruption falls * @param None * @retval None */ void SysTick_Handler(void) { HAL_IncTick(); }

fpistm
Пн, сентябрь 04, 2017 12:29
Я проверил, как Hal_systick_callback () используется в проекте Cube:

Фактически:

Systick_handler () вызов Hal_systick_irqhandler() которые называют Hal_systick_callback()

Итак, как нам нужно определить Systick_handler Чтобы позвонить Hal_inctick () (база времени) Я думаю, что это не лучшая идея, чтобы попытаться изменить это поведение.

Одним из решений может быть добавление вызова Hal_systick_callback () в Systick_handler () void SysTick_Handler(void) { HAL_IncTick(); HAL_SYSTICK_Callback(); }

Даниэфф
Пн, сентябрь 04, 2017 12:39
У меня есть это systick_handler () {hal_inctick (); hal_systick_callback (); }, и не было никаких проблем.
Кроме того.

fpistm
Пн, сентябрь 04, 2017, 14:26
Thnaks @daniel за ваш отзыв.
Я подведу пиар.
https: // github.com/stm32duino/arduino_c ... /проблемы/98