I have a ADC interrupt that occurs every 17ms and which copies the samples into a global static array, after which GivesFromISR to a binary semaphore so that the samples may be processed with a thread in the foreground. However, if I use xSemaphoreTake instead of xSemaphoreTakeFromISR in the thread the scheduler seems to stop. The strange part is that this only started happening after incorporating a 3rd party function call that uses the global static array modified by the ISR (closed source binary that was linked in the final binary..it does some CMSIS-DSP arm math calcs). Also, the ISR I mentioned is actually a function that gets called from the actual ISR and it is not the ISR it self (sorry for the formatting below)
Some code to better illustrate:
void app_drv_tasks_init(void){
m_sem_samples_event_ready = xSemaphoreCreateBinary(); //static var already declared
if (NULL == m_sem_samples_event_ready)
{
APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
}
if (pdPASS != xTaskCreate(saadc_sample_done_event_thread,
"SAMPLES", 256, NULL, 1,
&m_saadc_sample_done_thread))
{
APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
}
/** SAADC Interrupt handler */
void saadc_callback(nrf_drv_saadc_evt_t const * p_event){
if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
{
ret_code_t err_code;
err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLE_COUNT);
APP_ERROR_CHECK(err_code);
for (int i = 0; i < SAMPLE_COUNT; i++)
{
m_app_buffer[i] = p_event->data.done.p_buffer[i];
}
saadc_sample_done_event_signal();
}
}
uint32_t saadc_sample_done_event_signal(void){
BaseType_t yield_req = pdFALSE;
xSemaphoreGiveFromISR(m_sem_samples_event_ready, &yield_req);
portYIELD_FROM_ISR(yield_req);
return NRF_SUCCESS;
}
void saadc_sample_done_event_thread(void * arg){
uint8_t i;
uint8_t result;
adc_init(); // generates interrupts, but started after scheduler
three_party_code_init();
for(;;)
{
// Need to figure out why *FromISR fixes the crash
while (pdFALSE == xSemaphoreTakeFromISR(m_sem_samples_event_ready, portMAX_DELAY))
{
}
// If this line is removed xSemaphoreTake works fine
three_party_code(m_app_buffer, &result);
}
}
int main(void){
app_drv_tasks_init();
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
vTaskStartScheduler();
while (true)
{
APP_ERROR_HANDLER(NRF_ERROR_FORBIDDEN);
}
}