Цитата(Forger @ Jun 2 2018, 16:30)
На всякий случай посмотрите, останавливается ли счет таймера (TIM10 вроде) в режиме отладки? Есть битик для этой цели.
Из-за этого возможно, пока идете по шагам, заново входите в прерывание таймер, не успев попасть PendSV.
Я даже уже перед выполнением:
Код
xSemaphoreGiveFromISR(xSem1ms, &xHigherPriorityTaskWoken);
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
Отключаю прерывания TIM10
Вот весь проект, убрал все лишнее и переименовал задачи, номер задачи соответствует приоритету, а то я и сам уже начал путаться.
CODE
xSemaphoreHandle xSem1ms;
void Task1(void *pParams);
void Task2(void *pParams);
void TIM10_IRQHandler(void)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
if(TIM_GetFlagStatus(TIM10, TIM_FLAG_Update) != RESET)
{
NVIC->ICER[TIM10_IRQn >> 0x05] = (uint32_t)0x01 << (TIM10_IRQn & (uint8_t)0x1F);
xSemaphoreGiveFromISR(xSem1ms, &xHigherPriorityTaskWoken);
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
}
int main(void)
{
NVIC_InitTypeDef NVIC_InitStruct;
RCC_HSICmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);
RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
RCC_HSEConfig(RCC_HSE_OFF);
while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET);
SystemCoreClockUpdate();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
NVIC_InitStruct.NVIC_IRQChannel = TIM10_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 14;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStruct);
xTaskCreate(Task1, "Task1-handler", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
vTaskStartScheduler();
}
void Task1(void *pParams)
{
xTaskCreate(Task2, "Task2-handler", configMINIMAL_STACK_SIZE, NULL, 2, NULL);
while(1);
}
void Task2(void *pParams)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
vSemaphoreCreateBinary(xSem1ms);
xSemaphoreTake(xSem1ms, 0);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10, ENABLE);
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period = 16000 - 1;
TIM_TimeBaseInitStruct.TIM_Prescaler = 0;
TIM_TimeBaseInit(TIM10, &TIM_TimeBaseInitStruct);
TIM_ClearFlag(TIM10, TIM_FLAG_Update);
TIM_ITConfig(TIM10, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM10, ENABLE);
xSemaphoreTake(xSem1ms, 100);
vTaskDelete(NULL);
}
И на всякий случай заново опишу ситуацию.
Со строчки portEND_SWITCHING_ISR(xHigherPriorityTaskWoken) если шагами, попадаем в Task1 - цикл while(1);
А если через Run, то попадаем в Task2 на строку vTaskDelete(NULL);
P.S.
И напоследок. Проверил свое убеждение, что командами Step отладчик не попадает в прерывание, а Run попадает. Проверил на том же TIM10. Включил его, сразу установил флаг прерывания - если пройти его шагами, программа дальше пойдет не попадая в прерывания. А если через Run, то в прерывания попадает.
Возможно 9 листов "ереси" того стоило?
Уверен что не каждый, тем более начинающий об этом знает. И шагая по программе нужно учитывать что в это время могло произойти прерывание и жизнь пошла бы по другому.
Сообщение отредактировал maxntf - Jun 2 2018, 14:15