Code: Select all
#include <STM32FreeRTOS.h>
TIM_HandleTypeDef timerInstance;
static TaskHandle_t ht = NULL;
void task(void* p) {
while (1) {
ulTaskNotifyTake(pdFALSE, portMAX_DELAY);
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
}
}
void initTimer() {
// TIM2 Update Event (Hz) @ 1 Hz
__TIM2_CLK_ENABLE();
timerInstance.Instance = TIM2 ;
timerInstance.Init.Period = 83999;
timerInstance.Init.Prescaler = 999;
timerInstance.Init.CounterMode = TIM_COUNTERMODE_UP;
timerInstance.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
timerInstance.Init.RepetitionCounter = 0;
HAL_TIM_Base_Init(&timerInstance);
HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
HAL_TIM_Base_Start_IT(&timerInstance);
}
extern "C" void TIM2_IRQHandler() { HAL_TIM_IRQHandler(&timerInstance); }
extern "C" void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { vTaskNotifyGiveFromISR(ht, NULL); }
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
initTimer();
xTaskCreate(task, "task", 2048, NULL, 1, &ht);
vTaskStartScheduler();
}
void loop() { }
The really odd thing is, if I use my home-grown semaphore in place of the notification, it blinks properly:
Code: Select all
#include <STM32FreeRTOS.h>
#include <atomic>
class Mutex {
volatile std::atomic_flag mutex = ATOMIC_FLAG_INIT;
public:
void acquire() { while (mutex.test_and_set()); }
void release() { mutex.clear(); }
};
class Semaphore {
volatile std::atomic<size_t> value;
Mutex mutex;
public:
explicit Semaphore(size_t n = 0) {
if (n > 0)
value = n;
else
value = 0;
}
void take() {
mutex.acquire();
while (std::atomic_load(&value) <= 0);
atomic_fetch_sub(&value, 1);
mutex.release();
}
size_t give() { return std::atomic_fetch_add(&value, 1); }
};
TIM_HandleTypeDef timerInstance;
Semaphore s;
void task(void* p) {
while (1) {
s.take();
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
}
}
void initTimer() {
// TIM2 Update Event (Hz) @ 1 Hz
__TIM2_CLK_ENABLE();
timerInstance.Instance = TIM2 ;
timerInstance.Init.Period = 83999;
timerInstance.Init.Prescaler = 999;
timerInstance.Init.CounterMode = TIM_COUNTERMODE_UP;
timerInstance.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
timerInstance.Init.RepetitionCounter = 0;
HAL_TIM_Base_Init(&timerInstance);
HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
HAL_TIM_Base_Start_IT(&timerInstance);
}
extern "C" void TIM2_IRQHandler() { HAL_TIM_IRQHandler(&timerInstance); }
extern "C" void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { s.give(); }
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
initTimer();
xTaskCreate(task, "task", 2048, NULL, 1, NULL);
vTaskStartScheduler();
}
void loop() { }