RT-Thread RTOS 1.2.0
An open source embedded real-time operating system
载入中...
搜索中...
未找到
idle.c
浏览该文件的文档.
1/*
2 * Copyright (c) 2006-2022, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2006-03-23 Bernard the first version
9 * 2010-11-10 Bernard add cleanup callback function in thread exit.
10 * 2012-12-29 Bernard fix compiling warning.
11 * 2013-12-21 Grissiom let rt_thread_idle_excute loop until there is no
12 * dead thread.
13 * 2016-08-09 ArdaFu add method to get the handler of the idle thread.
14 * 2018-02-07 Bernard lock scheduler to protect tid->cleanup.
15 * 2018-07-14 armink add idle hook list
16 * 2018-11-22 Jesven add per cpu idle task
17 * combine the code of primary and secondary cpu
18 * 2021-11-15 THEWON Remove duplicate work between idle and _thread_exit
19 * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable
20 * 2023-11-07 xqyjlj fix thread exit
21 * 2023-12-10 xqyjlj add _hook_spinlock
22 */
23
24#include <rthw.h>
25#include <rtthread.h>
26
27#ifdef RT_USING_MODULE
28#include <dlmodule.h>
29#endif /* RT_USING_MODULE */
30
31#ifdef RT_USING_HOOK
32#ifndef RT_USING_IDLE_HOOK
33#define RT_USING_IDLE_HOOK
34#endif /* RT_USING_IDLE_HOOK */
35#endif /* RT_USING_HOOK */
36
37#ifndef IDLE_THREAD_STACK_SIZE
38#if defined (RT_USING_IDLE_HOOK) || defined(RT_USING_HEAP)
39#define IDLE_THREAD_STACK_SIZE 256
40#else
41#define IDLE_THREAD_STACK_SIZE 128
42#endif /* (RT_USING_IDLE_HOOK) || defined(RT_USING_HEAP) */
43#endif /* IDLE_THREAD_STACK_SIZE */
44
45#define _CPUS_NR RT_CPUS_NR
46
47static struct rt_thread idle_thread[_CPUS_NR];
48rt_align(RT_ALIGN_SIZE)
49static rt_uint8_t idle_thread_stack[_CPUS_NR][IDLE_THREAD_STACK_SIZE];
50
51#ifdef RT_USING_IDLE_HOOK
52#ifndef RT_IDLE_HOOK_LIST_SIZE
53#define RT_IDLE_HOOK_LIST_SIZE 4
54#endif /* RT_IDLE_HOOK_LIST_SIZE */
55
56static void (*idle_hook_list[RT_IDLE_HOOK_LIST_SIZE])(void);
57static struct rt_spinlock _hook_spinlock;
58
70rt_err_t rt_thread_idle_sethook(void (*hook)(void))
71{
72 rt_size_t i;
73 rt_err_t ret = -RT_EFULL;
74 rt_base_t level;
75
76 level = rt_spin_lock_irqsave(&_hook_spinlock);
77
78 for (i = 0; i < RT_IDLE_HOOK_LIST_SIZE; i++)
79 {
80 if (idle_hook_list[i] == RT_NULL)
81 {
82 idle_hook_list[i] = hook;
83 ret = RT_EOK;
84 break;
85 }
86 }
87
88 rt_spin_unlock_irqrestore(&_hook_spinlock, level);
89
90 return ret;
91}
92
102{
103 rt_size_t i;
104 rt_err_t ret = -RT_ENOSYS;
105 rt_base_t level;
106
107 level = rt_spin_lock_irqsave(&_hook_spinlock);
108
109 for (i = 0; i < RT_IDLE_HOOK_LIST_SIZE; i++)
110 {
111 if (idle_hook_list[i] == hook)
112 {
113 idle_hook_list[i] = RT_NULL;
114 ret = RT_EOK;
115 break;
116 }
117 }
118
119 rt_spin_unlock_irqrestore(&_hook_spinlock, level);
120
121 return ret;
122}
123
124#endif /* RT_USING_IDLE_HOOK */
125
126static void idle_thread_entry(void *parameter)
127{
128 RT_UNUSED(parameter);
129#ifdef RT_USING_SMP
130 if (rt_cpu_get_id() != 0)
131 {
132 while (1)
133 {
134 rt_hw_secondary_cpu_idle_exec();
135 }
136 }
137#endif /* RT_USING_SMP */
138
139 while (1)
140 {
141#ifdef RT_USING_IDLE_HOOK
142 rt_size_t i;
143 void (*idle_hook)(void);
144
145 for (i = 0; i < RT_IDLE_HOOK_LIST_SIZE; i++)
146 {
147 idle_hook = idle_hook_list[i];
148 if (idle_hook != RT_NULL)
149 {
150 idle_hook();
151 }
152 }
153#endif /* RT_USING_IDLE_HOOK */
154
155#if !defined(RT_USING_SMP) && !defined(RT_USING_SMART)
157#endif
158
159#ifdef RT_USING_PM
160 void rt_system_power_manager(void);
161 rt_system_power_manager();
162#endif /* RT_USING_PM */
163 }
164}
165
172{
173 rt_ubase_t i;
174#if RT_NAME_MAX > 0
175 char idle_thread_name[RT_NAME_MAX];
176#endif /* RT_NAME_MAX > 0 */
177
178#ifdef RT_USING_IDLE_HOOK
179 rt_spin_lock_init(&_hook_spinlock);
180#endif
181
182 for (i = 0; i < _CPUS_NR; i++)
183 {
184#if RT_NAME_MAX > 0
185 rt_snprintf(idle_thread_name, RT_NAME_MAX, "tidle%d", i);
186#endif /* RT_NAME_MAX > 0 */
187 rt_thread_init(&idle_thread[i],
188#if RT_NAME_MAX > 0
189 idle_thread_name,
190#else
191 "tidle",
192#endif /* RT_NAME_MAX > 0 */
193 idle_thread_entry,
194 RT_NULL,
195 &idle_thread_stack[i][0],
196 sizeof(idle_thread_stack[i]),
197 RT_THREAD_PRIORITY_MAX - 1,
198 32);
199#ifdef RT_USING_SMP
200 rt_thread_control(&idle_thread[i], RT_THREAD_CTRL_BIND_CPU, (void*)i);
201#endif /* RT_USING_SMP */
202
203 /* update */
204 rt_cpu_index(i)->idle_thread = &idle_thread[i];
205
206 /* startup */
207 rt_thread_startup(&idle_thread[i]);
208 }
209}
210
215{
216 int id = rt_cpu_get_id();
217
218 return (rt_thread_t)(&idle_thread[id]);
219}
struct rt_cpu * rt_cpu_index(int index)
This fucntion will return the cpu object corresponding to index.
void rt_defunct_execute(void)
This function will perform system background job when system idle.
rt_base_t rt_spin_lock_irqsave(struct rt_spinlock *lock)
This function will disable the local interrupt and then lock the spinlock, will lock the thread sched...
void rt_spin_lock_init(struct rt_spinlock *lock)
Initialize a static spinlock object.
void rt_spin_unlock_irqrestore(struct rt_spinlock *lock, rt_base_t level)
This function will unlock the spinlock and then restore current cpu interrupt status,...
rt_err_t rt_thread_startup(rt_thread_t thread)
This function will start a thread and put it to system ready queue.
#define RT_THREAD_CTRL_BIND_CPU
rt_err_t rt_thread_control(rt_thread_t thread, int cmd, void *arg)
This function will control thread behaviors according to control command.
rt_err_t rt_thread_idle_sethook(void(*hook)(void))
rt_err_t rt_thread_init(struct rt_thread *thread, const char *name, void(*entry)(void *parameter), void *parameter, void *stack_start, rt_uint32_t stack_size, rt_uint8_t priority, rt_uint32_t tick)
This function will initialize a thread. It's used to initialize a static thread object.
struct rt_thread * rt_thread_t
rt_thread_t rt_thread_idle_gethandler(void)
This function will get the handler of the idle thread.
定义 idle.c:214
void rt_thread_idle_init(void)
This function will initialize idle thread, then start it.
定义 idle.c:171
rt_err_t rt_thread_idle_delhook(void(*hook)(void))
delete the idle hook on hook list.
定义 idle.c:101
rt_align(RT_ALIGN_SIZE)
This function sets a hook function to idle thread loop. When the system performs idle loop,...
定义 idle.c:48
#define RT_IDLE_HOOK_LIST_SIZE
#define _CPUS_NR
定义 idle.c:45
#define IDLE_THREAD_STACK_SIZE
定义 idle.c:39
#define RT_UNUSED(x)
#define rt_cpu_get_id()
rt_int32_t rt_base_t
rt_base_t rt_err_t
unsigned char rt_uint8_t
rt_ubase_t rt_size_t
rt_uint32_t rt_ubase_t
#define RT_NULL
struct rt_thread * idle_thread