上一篇点这里
上一篇开了个头,简单解读了调度器和线程管理相关的源码
这一篇开始解读各个组件 😃
目录
- ThreadX定时器
- 系统内部定时器结构体TX_TIMER_INTERNAL
- 定时器结构体TX_TIMER
- 定时器相关的重要变量
- volatile ULONG _tx_timer_system_clock
- UINT _tx_timer_expired_time_slice
- TX_TIMER_INTERNAL *_tx_timer_list[TX_TIMER_ENTRIES]
- TX_TIMER_INTERNAL **_tx_timer_list_start
- TX_TIMER_INTERNAL **_tx_timer_list_end
- TX_TIMER_INTERNAL **_tx_timer_current_ptr
- UINT _tx_timer_expired
- TX_TIMER *_tx_timer_created_ptr
- ULONG _tx_timer_created_count
- TX_TIMER_INTERNAL *_tx_timer_expired_timer_ptr
- TX_THREAD _tx_timer_thread
- VOID *_tx_timer_stack_start
- ULONG _tx_timer_stack_size
- UINT _tx_timer_priority
- ULONG _tx_timer_thread_stack_area[(((UINT) TX_TIMER_THREAD_STACK_SIZE)+((sizeof(ULONG))- ((UINT) 1)))/(sizeof(ULONG))]
- ULONG _tx_timer_time_slice
- 系统定时器功能初始化
- tx_timer_interrupt.S文件分析
ThreadX定时器
定时器分为系统内部定时器TX_TIMER_INTERNAL和系统定时器TX_TIMER
真正起作用的结构体是TX_TIMER_INTERNAL
在Systick中断里面,ThreadX会处理定时器相关的操作,如果去看tx_timer_interrupt.S,里面写了很多个汇编函数,似乎是处理定时器相关的操作的,需要重点关注~~ 😃
系统内部定时器结构体TX_TIMER_INTERNAL
typedef struct TX_TIMER_INTERNAL_STRUCT
{
/* 定义剩下的Tick值和重新初始化的Tick值 */
ULONG tx_timer_internal_remaining_ticks;
ULONG tx_timer_internal_re_initialize_ticks;
/* 定义超时回调函数和超时回调函数指针 Define the timeout function and timeout function parameter. */
VOID (*tx_timer_internal_timeout_function)(ULONG id);
ULONG tx_timer_internal_timeout_param;
/* 定义下一个,上一个定时器指针*/
struct TX_TIMER_INTERNAL_STRUCT
*tx_timer_internal_active_next,
*tx_timer_internal_active_previous;
/* 定义链表头用于追踪
Keep track of the pointer to the head of this list as well. */
struct TX_TIMER_INTERNAL_STRUCT
**tx_timer_internal_list_head;
/* Define optional extension to internal timer control block. */
TX_TIMER_INTERNAL_EXTENSION
} TX_TIMER_INTERNAL;
定时器结构体TX_TIMER
typedef struct TX_TIMER_STRUCT
{
/* 定时器这个组件的ID */
ULONG tx_timer_id;
/*定时器的名字 */
CHAR *tx_timer_name;
/* 定时器实际的内核 */
TX_TIMER_INTERNAL tx_timer_internal;
/* 已创建定时器的链表指针 */
struct TX_TIMER_STRUCT
*tx_timer_created_next,
*tx_timer_created_previous;
/* Define optional extension to timer control block. */
TX_TIMER_EXTENSION
} TX_TIMER;
定时器相关的重要变量
volatile ULONG _tx_timer_system_clock
定时器中断周期性递增的系统时钟值
UINT _tx_timer_expired_time_slice
时间片失效标志,表明时间片曾经发生过
TX_TIMER_INTERNAL *_tx_timer_list[TX_TIMER_ENTRIES]
定义线程和定时器的入口
TX_TIMER_INTERNAL **_tx_timer_list_start
定时器链表的开头【二级指针】
TX_TIMER_INTERNAL **_tx_timer_list_end
定时器链表的结尾【二级指针】
TX_TIMER_INTERNAL **_tx_timer_current_ptr
定义当前运行的定时器在定时器链表中的位置,在定时器中断里面顺序移动
UINT _tx_timer_expired
定义定时器失效标志,标记定时器已经失效
TX_TIMER *_tx_timer_created_ptr
定义已创建的定时器的头指针
ULONG _tx_timer_created_count
定义已创建的定时器的个数
TX_TIMER_INTERNAL *_tx_timer_expired_timer_ptr
定义已经失效并正在处理的定时器指针
TX_THREAD _tx_timer_thread
定义定时器线程的控制块
VOID *_tx_timer_stack_start
定义定时器线程的栈顶
ULONG _tx_timer_stack_size
定义定时器线程的栈大小
UINT _tx_timer_priority
定义定时器线程的优先级
ULONG _tx_timer_thread_stack_area[(((UINT) TX_TIMER_THREAD_STACK_SIZE)+((sizeof(ULONG))- ((UINT) 1)))/(sizeof(ULONG))]
定义定时器的线程用的堆栈
ULONG _tx_timer_time_slice
定义当前时间片的值,如果非0,说明时间片是启动了,否则没有启动
系统定时器功能初始化
_tx_timer_initialize函数,里面主要的功能是初始化定时器功能相关的重要变量和创建系统定时器线程
ThreadX在初始化完毕以后会默认创建一个系统定时器线程System Timer Thread,优先级是0【最高】
VOID _tx_timer_initialize(VOID)
{
UINT status;
/* Initialize the system clock to 0. */
_tx_timer_system_clock = ((ULONG) 0);
/* Initialize the time-slice value to 0 to make sure it is disabled. */
_tx_timer_time_slice = ((ULONG) 0);
/* Clear the expired flags. */
_tx_timer_expired_time_slice = TX_FALSE;
_tx_timer_expired = TX_FALSE;
/* Set the currently expired timer being processed pointer to NULL. */
_tx_timer_expired_timer_ptr = TX_NULL;
/* Initialize the thread and application timer management control structures. */
/* First, initialize the timer list. */
TX_MEMSET(&_tx_timer_list[0], 0, (sizeof(_tx_timer_list)));
/* Initialize all of the list pointers. */
_tx_timer_list_start = &_tx_timer_list[0];
_tx_timer_current_ptr = &_tx_timer_list[0];
/* Set the timer list end pointer to one past the actual timer list. This is done
to make the timer interrupt handling in assembly language a little easier. */
_tx_timer_list_end = &_tx_timer_list[TX_TIMER_ENTRIES-((ULONG) 1)];
_tx_timer_list_end = TX_TIMER_POINTER_ADD(_tx_timer_list_end, ((ULONG) 1));
/* Setup the variables associated with the system timer thread's stack and
priority. */
_tx_timer_stack_start = (VOID *) &_tx_timer_thread_stack_area[0];
_tx_timer_stack_size = ((ULONG) TX_TIMER_THREAD_STACK_SIZE);
_tx_timer_priority = ((UINT) TX_TIMER_THREAD_PRIORITY);
/* Create the system timer thread. This thread processes all of the timer
expirations and reschedules. Its stack and priority are defined in the
low-level initialization component. */
do
{
/* Create the system timer thread. */
status = _tx_thread_create(&_tx_timer_thread,
TX_CONST_CHAR_TO_CHAR_POINTER_CONVERT("System Timer Thread"),
_tx_timer_thread_entry,
((ULONG) TX_TIMER_ID),
_tx_timer_stack_start, _tx_timer_stack_size,
_tx_timer_priority, _tx_timer_priority, TX_NO_TIME_SLICE, TX_DONT_START);
/* Define timer initialize extension. */
TX_TIMER_INITIALIZE_EXTENSION(status)
} while (status != TX_SUCCESS);
/* Initialize the head pointer of the created application timer list. */
_tx_timer_created_ptr = TX_NULL;
/* Set the created count to zero. */
_tx_timer_created_count = TX_EMPTY;
}
下面重点分析这个线程对应的函数
_tx_timer_thread_entry
VOID _tx_timer_thread_entry(ULONG timer_thread_input)
{
TX_INTERRUPT_SAVE_AREA
TX_TIMER_INTERNAL *expired_timers;
TX_TIMER_INTERNAL *reactivate_timer;
TX_TIMER_INTERNAL *next_timer;
TX_TIMER_INTERNAL *previous_timer;
TX_TIMER_INTERNAL *current_timer;
VOID (*timeout_function)(ULONG id);
ULONG timeout_param = ((ULONG) 0);
TX_THREAD *thread_ptr;
/* Make sure the timer input is correct. This also gets rid of the
silly compiler warnings. */
if (timer_thread_input == TX_TIMER_ID)
{
/* Yes, valid thread entry, proceed... */
/* Now go into an infinite loop to process timer expirations. */
while (TX_LOOP_FOREVER)
{
/* First, move the current list pointer and clear the timer
expired value. This allows the interrupt handling portion
to continue looking for timer expirations. */
TX_DISABLE
/* 保存当前定时器指针指向的定时器地址 到失效定时器指针 Save the current timer expiration list pointer. */
expired_timers = *_tx_timer_current_ptr;
/*
如果定时器只有一个【当前定时器指针指向的定时器地址!=NULL】,修改链表中的头指针指向的第一个定时器
Modify the head pointer in the first timer in the list, if there is one!
*/
if (expired_timers != TX_NULL)
{
expired_timers -> tx_timer_internal_list_head = &expired_timers;
}
/* 设置当前链表指针指向的定时器地址为空 Set the current list pointer to NULL. */
*_tx_timer_current_ptr = TX_NULL;
/* 向后移动当前链表指针4*/
/* Move the current pointer up one timer entry wrap if we get to
the end of the list. */
_tx_timer_current_ptr = TX_TIMER_POINTER_ADD(_tx_timer_current_ptr, 1);
//如果头和尾是一样的
if (_tx_timer_current_ptr == _tx_timer_list_end)
{
//那么当前指针指向头
_tx_timer_current_ptr = _tx_timer_list_start;
}
/* 清除失效标识 Clear the expired flag. */
_tx_timer_expired = TX_FALSE;
/* Restore interrupts temporarily. */
TX_RESTORE
/* Disable interrupts again. */
TX_DISABLE
/* 再当前时间片下处理对应定时器的失效
Next, process the expiration of the associated timers at this
time slot. */
while (expired_timers != TX_NULL)
{
/* 移除它,处理失效 Something is on the list. Remove it and process the expiration. */
current_timer = expired_timers;
/* 取出下一个有效的定时器 Pickup the next timer. */
next_timer = expired_timers -> tx_timer_internal_active_next;
/* 设置重新启动的定时器为NULL Set the reactivate_timer to NULL. */
reactivate_timer = TX_NULL;
/* 判断是不是只有这一个定时器 Determine if this is the only timer. */
if (current_timer == next_timer)
{
/* Yes, this is the only timer in the list. */
/* 设置头指针为NULL,没有要失效的 Set the head pointer to NULL. */
expired_timers = TX_NULL;
}
else
{
/* 并不是唯一的失效定时器 No, not the only expired timer. */
/* 从失效定时器链表中移除 Remove this timer from the expired list. */
previous_timer = current_timer -> tx_timer_internal_active_previous;
next_timer -> tx_timer_internal_active_previous = previous_timer;
previous_timer -> tx_timer_internal_active_next = next_timer;
/* Modify the next timer's list head to point at the current list head. */
next_timer -> tx_timer_internal_list_head = &expired_timers;
/* Set the list head pointer. */
expired_timers = next_timer;
}
/* In any case, the timer is now off of the expired list. */
/* 判断当前操作的定时器是不是失效了 或者确实是一个定时大的定时器
它需要再次放到链表里
Determine if the timer has expired or if it is just a really
big timer that needs to be placed in the list again. */
if (current_timer -> tx_timer_internal_remaining_ticks > TX_TIMER_ENTRIES)
{
/* Timer is bigger than the timer entries and must be
rescheduled. */
/* 定时器的剩余tick递减*/
current_timer -> tx_timer_internal_remaining_ticks =
current_timer -> tx_timer_internal_remaining_ticks - TX_TIMER_ENTRIES;
/* 设置超时回调函数为NULL,为了跳过失效检查 */
timeout_function = TX_NULL;
/* 使计时器看起来在中断启用时仍处于活动状态,这将允许从中断中正确处理计时器停用*/
current_timer -> tx_timer_internal_list_head = &reactivate_timer;
current_timer -> tx_timer_internal_active_next = current_timer;
/* 设置临时定时器链表头 */
reactivate_timer = current_timer;
}
else
{
/* 定时器失效了 Timer did expire. */
/* 拷贝回调函数和参数到局部变量里,待会要去中断了Copy the calling function and ID into local variables before interrupts
are re-enabled. */
timeout_function = current_timer -> tx_timer_internal_timeout_function;
timeout_param = current_timer -> tx_timer_internal_timeout_param;
/* Copy the reinitialize ticks into the remaining ticks. */
current_timer -> tx_timer_internal_remaining_ticks = current_timer -> tx_timer_internal_re_initialize_ticks;
/* 判断定时器是不是要重新激活 Determine if the timer should be reactivated. */
if (current_timer -> tx_timer_internal_remaining_ticks != ((ULONG) 0))
{
/* 使计时器看起来在中断启用时仍处于活动状态,这将允许从中断中正确处理计时器停用*/
current_timer -> tx_timer_internal_list_head = &reactivate_timer;
current_timer -> tx_timer_internal_active_next = current_timer;
/* Setup the temporary timer list head pointer. */
reactivate_timer = current_timer;
}
else
{
/*设置这个定时器的链表头为空,这个表示这个定时器不再有效了 Set the list pointer of this timer to NULL. This is used to indicate
the timer is no longer active. */
current_timer -> tx_timer_internal_list_head = TX_NULL;
}
}
/* 设置已经失效的定时器指针指向当前处理了的定时器 Set pointer to indicate the expired timer that is currently being processed. */
_tx_timer_expired_timer_ptr = current_timer;
/* Restore interrupts for timer expiration call. */
TX_RESTORE
/* 调用定时器回调函数 */
if (timeout_function != TX_NULL)
{
(timeout_function) (timeout_param);
}
/* Lockout interrupts again. */
TX_DISABLE
/* Clear expired timer pointer. */
_tx_timer_expired_timer_ptr = TX_NULL;
/* Determine if the timer needs to be reactivated. */
if (reactivate_timer == current_timer)
{
/* Reactivate the timer. */
/* Reactivate through the timer activate function. */
/* 清除链表头种子很 Clear the list head for the timer activate call. */
current_timer -> tx_timer_internal_list_head = TX_NULL;
/* 激活当前操作的定时器 */
_tx_timer_system_activate(current_timer);
}
/* Restore interrupts. */
TX_RESTORE
/* Lockout interrupts again. */
TX_DISABLE
}
/* Finally, suspend this thread and wait for the next expiration. */
/* Determine if another expiration took place while we were in this
thread. If so, process another expiration. */
if (_tx_timer_expired == TX_FALSE)
{
/* Otherwise, no timer expiration, so suspend the thread. */
/* Build pointer to the timer thread. */
thread_ptr = &_tx_timer_thread;
/* Set the status to suspending, in order to indicate the
suspension is in progress. */
thread_ptr -> tx_thread_state = TX_SUSPENDED;
/* 设置挂起标志 */
thread_ptr -> tx_thread_suspending = TX_TRUE;
/*在挂起之前递增抢占禁止计数 */
_tx_thread_preempt_disable++;
/* Restore interrupts. */
TX_RESTORE
/* Call actual thread suspension routine. */
_tx_thread_system_suspend(thread_ptr);
}
else
{
/* Restore interrupts. */
TX_RESTORE
}
}
}
}
tx_timer_interrupt.S文件分析
这个汇编函数【_tx_timer_interrupt】会被Sys tick中断函数调用,这个汇编函数会调用其他函数,这个函数用来维护定时器相关的指针和变量。
_tx_timer_interrupt
__tx_timer_no_time_slice
__tx_timer_done
_tx_timer_expiration_process
_tx_thread_time_slice