lww2zamndqc6401883227.png
4 a3 `9 S* ], \0 d( T" @+ c. r D8 E- o
在Cortex-M内核中,系统节拍由Systick时钟提供,当配置好系统滴答时钟后,每次时钟中断就会触发中断处理数xPortSysTickHandler()。* t. D: J! _( r/ ?" P6 @2 N: S
void xPortSysTickHandler( void ){ /* The SysTick runs at the lowest interrupt priority, so when this interrupt * executes all interrupts must be unmasked. There is therefore no need to * save and then restore the interrupt mask value as its value is already * known - therefore the slightly faster vPortRaiseBASEPRI() function is used * in place of portSET_INTERRUPT_MASK_FROM_ISR(). */ vPortRaiseBASEPRI();//屏蔽归属FreeRTOS的中断优先级 { /* Increment the RTOS tick. */ if( xTaskIncrementTick() != pdFALSE )//时钟计数处理 { /* A context switch is required. Context switching is performed in * the PendSV interrupt. Pend the PendSV interrupt. */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;//如果需要切换上下文操作,PendSV标记置位 } }
) O# \" D2 Q, t( c$ G4 C vPortClearBASEPRIFromISR();}
% v. H. ~3 X) x- f: g$ @$ \这部分主要是依靠 xTaskIncrementTick(),来判断任务切换是否在此次系统时钟中断时被需要。如果是,则PendSV标记置位,等待触发PendSV中断。来看看 xTaskIncrementTick()。BaseType_t xTaskIncrementTick( void ){ TCB_t * pxTCB; TickType_t xItemValue; BaseType_t xSwitchRequired = pdFALSE;& ?. ~( V2 k! E. b2 S6 F
/* Called by the portable layer each time a tick interrupt occurs. * Increments the tick then checks to see if the new tick value will cause any * tasks to be unblocked. */ traceTASK_INCREMENT_TICK( xTickCount );
2 h2 M0 [/ N& Y! M if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) //调度是否被挂起,默认为否 { /* Minor optimisation. The tick count cannot change in this * block. */ const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1;+ n$ Y6 w. G3 ~( L: l& F4 v$ w" V
/* Increment the RTOS tick, switching the delayed and overflowed * delayed lists if it wraps to 0. */ xTickCount = xConstTickCount;
0 g: Z, g% s; {$ `) L" a6 U if( xConstTickCount == ( TickType_t ) 0U ) /*lint !e774 'if' does not always evaluate to false as it is looking for an overflow. 如果xConstTickCount为0,说明溢出了*/ { taskSWITCH_DELAYED_LISTS();/*切换延迟列表*/ } else { mtCOVERAGE_TEST_MARKER(); }
3 v5 i1 k6 ~! [, Q1 ` /* See if this tick has made a timeout expire. Tasks are stored in * the queue in the order of their wake time - meaning once one task * has been found whose block time has not expired there is no need to * look any further down the list. */ if( xConstTickCount >= xNextTaskUnblockTime ) { for( ; ; ) { if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) { /* The delayed list is empty. Set xNextTaskUnblockTime * to the maximum possible value so it is extremely * unlikely that the * if( xTickCount >= xNextTaskUnblockTime ) test will pass * next time through. */ xNextTaskUnblockTime = portMAX_DELAY; /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ break; } else { /* The delayed list is not empty, get the value of the * item at the head of the delayed list. This is the time * at which the task at the head of the delayed list must * be removed from the Blocked state. */ pxTCB = listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ) );
3 @+ V, e3 p% b' c; a. j关键问题是,这个函数使用到了 pxDelayedTaskList, 这定义在本文件
# D4 t$ q. X9 ?. v4 rPRIVILEGED_DATA static List_t * volatile pxDelayedTaskList;
6 M j* z( h3 l# b4 E b' \该变量初始化为0,该变量正常初始化位置在创建 Task 对象等的函数中, 也就是说,如果在Tick中断到来时,如果还没有任务被创建,就会导致不可预期的结果,中断服务函数会使用这个野指针,执行任务切换。这会导致触发栈溢出钩子函数,或者是直接Hardfault。有些硬件初始化需要借助delay功能,不得不在初始化之前配置SysTick。而又不希望在硬件初始化阶段触发这个Bug。所以在配置SysTick之前,先创建一个初始化任务,初始化 pxDelayedTaskList 这个指针,在初始化任务里配置SysTick,和其他初始化,这样能够避免此类问题。或者是在配置SysTick的时候屏蔽中断,一切准备就绪后,开启中断。执行vTaskStartScheduler()默认创建一个空闲任务。==========
( o* E/ r0 e: J往期回顾:
1 Z3 ^1 W0 B4 `3 @4 z3 Istrlen和sizeof的异同/ O1 f7 S. Z/ B b# L! N
STM32CubeMx的串口DMA收发数据; b1 r! y8 a- w* @" t p# M- X
好看的PCB也是产品的优势
$ L; G* a1 M# c/ N1 K+ |STM32的DMA的五大问题
. Z' U" h" Q) X5 l, R单片机的各个通信协议的波特率
5 ?4 A+ V. n, Y% e Q3 G==========5 D6 e' c5 U2 h5 W3 ~! G$ z
原文链接:点击阅读原文
; }: ~& Z1 [0 m; J平台:博客园# N- {/ A: h& Q$ z1 S
作者:ficusdxx2 N. p4 A2 U6 q& Q, |: M
2vvnohsyebn6401883327.png
4 u6 H2 [% R Y* [9 s! M% x% U, ^* W1 F2 C6 n3 D. Q: ]( t
5uzxtnehbn26401883428.png
! t# U3 j& e+ c4 T- c% ?+ ?# m) P' W. _) c9 o
fqwb1bevkbq6401883528.png
|