当前位置:   article > 正文

vxworks源码_【RT-Thread源码学习】1.线程管理

rt thread wxwork

嵌入式系统学习中,时常会接触到实时操作系统。在此之前,本人学习过Vxworks并接触过FreeRTOS和RTThread,最近一段时间突发奇想,想要了解一下RTOS内部具体是工作的,怎样运行的,遂开始学习RTOS源代码。众所周知Vxworks并未开源且价格高昂,并且几乎所有实时操作系统的使用和设计思想都大同小异,所以本人选择了RT-Thread来进行学习,一是此操作系统最近在社会上影响越来越大,可谓国产操作系统之光,二是它的资料齐全且代码相对于FreeRTOS更加清晰明了,对于初学者较为友好。所以,综上所述,选择RT-Thread来进行学习。

RT-Thread,全称是 Real Time-Thread,顾名思义,它是一个嵌入式实时多线程操作系统,基本属性 之一是支持多任务,允许多个任务同时运行并不意味着处理器在同一时刻真地执行了多个任务。事实上, 一个处理器核心在某一时刻只能运行一个任务,由于每次对一个任务的执行时间很短、任务与任务之间通 过任务调度器进行非常快速地切换(调度器根据优先级决定此刻该执行的任务),给人造成多个任务在一个 时刻同时运行的错觉。在 RT-Thread 系统中,任务通过线程实现的,RT-Thread 中的线程调度器也就是 以上提到的任务调度器。

此次学习之旅根据RT-Thread官方文档《RT-THREAD 编程指南》目录进行,同时参考其中内容。在源码解读方面采用直接在源代码中做注释的方式,这样既有开发者的官方注释,又有自己的思考,想法,更加清晰明了。

其中注释/**/中为官方注释,注释//为本人自己的想法。


线程管理

在 RT-Thread 中,子任务对应的程序实体就是线程,线程是实现任务的载体,它是 RT-Thread 中最基本的调度单位,它描述了一个任务执行的运行环境,也描述了这个任务所处的优先等级,重要的任 务可设置相对较高的优先级,非重要的任务可以设置较低的优先级,不同的任务还可以设置相同的优先级, 轮流运行。 当线程运行时,它会认为自己是以独占 CPU 的方式在运行,线程执行时的运行环境称为上下文,具 体来说就是各个变量和数据,包括所有的寄存器变量、堆栈、内存信息等。

RT-Thread 线程管理的主要功能是对线程进行管理和调度,系统中总共存在两类线程,分别是系统线 程和用户线程,系统线程是由 RT-Thread 内核创建的线程,用户线程是由应用程序创建的线程,这两类线 程都会从内核对象容器中分配线程对象,当线程被删除时,也会被从对象容器中删除,如下图所示,每 个线程都有重要的属性,如线程控制块、线程栈、入口函数等。

78a41bc3fd0b1c63eedfa5e36b943c99.png

RT-Thread 提供一系列的操作系统调用接口,使得线程的状态在以下这五个状态之间来回切换。

28d3fa5356c0113331a0f41817de128a.png

有关线程管理接口,包括线程初始化/创建,脱离/删除函数,以及一些延时函数均定义在thread.c中(rt_threadrt-threadsrc)。

thread.c中包含以下接口:

void rt_thread_exit(void)

rt_err_t rt_thread_init(……)

rt_thread_t rt_thread_self(void)

rt_err_t rt_thread_startup(rt_thread_t thread)

rt_err_t rt_thread_detach(rt_thread_t thread)

rt_thread_t rt_thread_create(……)

rt_err_t rt_thread_delete(rt_thread_t thread)

rt_err_t rt_thread_sleep(rt_tick_t tick)

rt_err_t rt_thread_delay(rt_tick_t tick)

rt_err_t rt_thread_mdelay(rt_int32_t ms)

rt_err_t rt_thread_control(rt_thread_t thread, int cmd, void *arg)

rt_err_t rt_thread_suspend(rt_thread_t thread)

rt_err_t rt_thread_resume(rt_thread_t thread)

void rt_thread_timeout(void *parameter)

rt_thread_t rt_thread_find(char *name)

  1. //此文件为源码学习版本------cyh2020/03/23
  2. //thread.c文件学习是学习rtthread源码的第一步
  3. //thread.c文件主要进行内核管理操作,例如线程初始化/创建和删除/脱离
  4. //
  5. /*
  6. * Copyright (c) 2006-2018, RT-Thread Development Team
  7. *
  8. * SPDX-License-Identifier: Apache-2.0
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2006-03-28 Bernard first version
  13. * 2006-04-29 Bernard implement thread timer
  14. * 2006-04-30 Bernard added THREAD_DEBUG
  15. * 2006-05-27 Bernard fixed the rt_thread_yield bug
  16. * 2006-06-03 Bernard fixed the thread timer init bug
  17. * 2006-08-10 Bernard fixed the timer bug in thread_sleep
  18. * 2006-09-03 Bernard changed rt_timer_delete to rt_timer_detach
  19. * 2006-09-03 Bernard implement rt_thread_detach
  20. * 2008-02-16 Bernard fixed the rt_thread_timeout bug
  21. * 2010-03-21 Bernard change the errno of rt_thread_delay/sleep to
  22. * RT_EOK.
  23. * 2010-11-10 Bernard add cleanup callback function in thread exit.
  24. * 2011-09-01 Bernard fixed rt_thread_exit issue when the current
  25. * thread preempted, which reported by Jiaxing Lee.
  26. * 2011-09-08 Bernard fixed the scheduling issue in rt_thread_startup.
  27. * 2012-12-29 Bernard fixed compiling warning.
  28. * 2016-08-09 ArdaFu add thread suspend and resume hook.
  29. * 2017-04-10 armink fixed the rt_thread_delete and rt_thread_detach
  30. * bug when thread has not startup.
  31. * 2018-11-22 Jesven yield is same to rt_schedule
  32. * add support for tasks bound to cpu
  33. */
  34. #include <rthw.h>
  35. #include <rtthread.h>
  36. extern rt_list_t rt_thread_defunct;
  37. //声明线程操作的钩子函数(函数指针)
  38. //条件编译,如果使用HOOK时,编译此部分
  39. //RT_USING_HOOK声明在rtconfig.h中
  40. #ifdef RT_USING_HOOK
  41. static void (*rt_thread_suspend_hook)(rt_thread_t thread);
  42. static void (*rt_thread_resume_hook) (rt_thread_t thread);
  43. static void (*rt_thread_inited_hook) (rt_thread_t thread);
  44. /**
  45. * @ingroup Hook
  46. * This function sets a hook function when the system suspend a thread.
  47. *
  48. * @param hook the specified hook function
  49. *
  50. * @note the hook function must be simple and never be blocked or suspend.
  51. */
  52. void rt_thread_suspend_sethook(void (*hook)(rt_thread_t thread))
  53. {
  54. rt_thread_suspend_hook = hook;
  55. }
  56. /**
  57. * @ingroup Hook
  58. * This function sets a hook function when the system resume a thread.
  59. *
  60. * @param hook the specified hook function
  61. *
  62. * @note the hook function must be simple and never be blocked or suspend.
  63. */
  64. void rt_thread_resume_sethook(void (*hook)(rt_thread_t thread))
  65. {
  66. rt_thread_resume_hook = hook;
  67. }
  68. /**
  69. * @ingroup Hook
  70. * This function sets a hook function when a thread is initialized.
  71. *
  72. * @param hook the specified hook function
  73. */
  74. void rt_thread_inited_sethook(void (*hook)(rt_thread_t thread))
  75. {
  76. rt_thread_inited_hook = hook;
  77. }
  78. #endif
  79. //通过调用此接口使线程从运行状态到关闭状态
  80. void rt_thread_exit(void)
  81. {
  82. struct rt_thread *thread;
  83. register rt_base_t level;
  84. /* get current thread */
  85. thread = rt_thread_self();
  86. /* disable interrupt */
  87. level = rt_hw_interrupt_disable();
  88. /* remove from schedule */
  89. rt_schedule_remove_thread(thread);
  90. /* change stat */
  91. thread->stat = RT_THREAD_CLOSE; //改变线程状态为关闭状态
  92. /* remove it from timer list */
  93. rt_timer_detach(&thread->thread_timer);
  94. if ((rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) &&
  95. thread->cleanup == RT_NULL)
  96. {
  97. rt_object_detach((rt_object_t)thread);
  98. }
  99. else
  100. {
  101. /* insert to defunct thread list */
  102. rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));
  103. }
  104. /* enable interrupt */
  105. rt_hw_interrupt_enable(level);
  106. /* switch to next task */
  107. rt_schedule();
  108. }
  109. //初始化线程,静态线程初始化
  110. static rt_err_t _rt_thread_init(struct rt_thread *thread,
  111. const char *name,
  112. void (*entry)(void *parameter),
  113. void *parameter,
  114. void *stack_start,
  115. rt_uint32_t stack_size,
  116. rt_uint8_t priority,
  117. rt_uint32_t tick)
  118. {
  119. /* init thread list */
  120. rt_list_init(&(thread->tlist));
  121. thread->entry = (void *)entry; //设置线程入口函数
  122. thread->parameter = parameter; //入口函数中所带的参数
  123. /* stack init */
  124. thread->stack_addr = stack_start;
  125. thread->stack_size = stack_size;
  126. /* init thread stack */
  127. rt_memset(thread->stack_addr, '#', thread->stack_size);
  128. //条件编译,条件为栈是否由顶向下增长
  129. //设置堆栈指针sp位置
  130. #ifdef ARCH_CPU_STACK_GROWS_UPWARD
  131. thread->sp = (void *)rt_hw_stack_init(thread->entry, thread->parameter,
  132. (void *)((char *)thread->stack_addr),
  133. (void *)rt_thread_exit);
  134. #else
  135. thread->sp = (void *)rt_hw_stack_init(thread->entry, thread->parameter,
  136. (void *)((char *)thread->stack_addr + thread->stack_size - sizeof(rt_ubase_t)),
  137. (void *)rt_thread_exit);
  138. #endif
  139. /* priority init */
  140. //断言:线程优先级须小于优先级最大值logic
  141. RT_ASSERT(priority < RT_THREAD_PRIORITY_MAX);
  142. thread->init_priority = priority;
  143. thread->current_priority = priority;
  144. thread->number_mask = 0;
  145. #if RT_THREAD_PRIORITY_MAX > 32
  146. thread->number = 0;
  147. thread->high_mask = 0;
  148. #endif
  149. /* tick init */
  150. thread->init_tick = tick;
  151. thread->remaining_tick = tick;
  152. /* error and flags */
  153. thread->error = RT_EOK;
  154. thread->stat = RT_THREAD_INIT;
  155. #ifdef RT_USING_SMP
  156. /* not bind on any cpu */
  157. thread->bind_cpu = RT_CPUS_NR;
  158. thread->oncpu = RT_CPU_DETACHED;
  159. /* lock init */
  160. thread->scheduler_lock_nest = 0;
  161. thread->cpus_lock_nest = 0;
  162. #endif /*RT_USING_SMP*/
  163. /* initialize cleanup function and user data */
  164. thread->cleanup = 0;
  165. thread->user_data = 0;
  166. /* init thread timer */
  167. rt_timer_init(&(thread->thread_timer),
  168. thread->name,
  169. rt_thread_timeout,
  170. thread,
  171. 0,
  172. RT_TIMER_FLAG_ONE_SHOT);
  173. /* initialize signal */
  174. #ifdef RT_USING_SIGNALS
  175. thread->sig_mask = 0x00;
  176. thread->sig_pending = 0x00;
  177. #ifndef RT_USING_SMP
  178. thread->sig_ret = RT_NULL;
  179. #endif
  180. thread->sig_vectors = RT_NULL;
  181. thread->si_list = RT_NULL;
  182. #endif
  183. #ifdef RT_USING_LWP
  184. thread->lwp = RT_NULL;
  185. #endif
  186. //调用钩子函数
  187. RT_OBJECT_HOOK_CALL(rt_thread_inited_hook, (thread));
  188. return RT_EOK;
  189. }
  190. /**
  191. * @addtogroup Thread
  192. */
  193. /**@{*/
  194. /**
  195. * This function will initialize a thread, normally it's used to initialize a
  196. * static thread object.
  197. *
  198. * @param thread the static thread object
  199. * @param name the name of thread, which shall be unique
  200. * @param entry the entry function of thread
  201. * @param parameter the parameter of thread enter function
  202. * @param stack_start the start address of thread stack
  203. * @param stack_size the size of thread stack
  204. * @param priority the priority of thread
  205. * @param tick the time slice if there are same priority thread
  206. *
  207. * @return the operation status, RT_EOK on OK, -RT_ERROR on error
  208. */
  209. rt_err_t rt_thread_init(struct rt_thread *thread,
  210. const char *name,
  211. void (*entry)(void *parameter),
  212. void *parameter,
  213. void *stack_start,
  214. rt_uint32_t stack_size,
  215. rt_uint8_t priority,
  216. rt_uint32_t tick)
  217. {
  218. /* thread check */
  219. RT_ASSERT(thread != RT_NULL);
  220. RT_ASSERT(stack_start != RT_NULL);
  221. /* init thread object */
  222. rt_object_init((rt_object_t)thread, RT_Object_Class_Thread, name);
  223. return _rt_thread_init(thread,
  224. name,
  225. entry,
  226. parameter,
  227. stack_start,
  228. stack_size,
  229. priority,
  230. tick);
  231. }
  232. RTM_EXPORT(rt_thread_init);
  233. /**
  234. * This function will return self thread object
  235. *
  236. * @return the self thread object
  237. */
  238. rt_thread_t rt_thread_self(void)
  239. {
  240. #ifdef RT_USING_SMP
  241. rt_base_t lock;
  242. rt_thread_t self;
  243. lock = rt_hw_local_irq_disable();
  244. self = rt_cpu_self()->current_thread; //cpu当前执行的线程结构体
  245. rt_hw_local_irq_enable(lock);
  246. return self;
  247. #else
  248. extern rt_thread_t rt_current_thread;
  249. return rt_current_thread;
  250. #endif
  251. }
  252. RTM_EXPORT(rt_thread_self);
  253. /**
  254. * This function will start a thread and put it to system ready queue
  255. *
  256. * @param thread the thread to be started
  257. *
  258. * @return the operation status, RT_EOK on OK, -RT_ERROR on error
  259. */
  260. //启动线程
  261. //当线程初始化/创建成功后调用函数使线程从初始状态变更为就绪态
  262. //放入相应的优先级队列中等待调度
  263. rt_err_t rt_thread_startup(rt_thread_t thread)
  264. {
  265. /* thread check */
  266. RT_ASSERT(thread != RT_NULL);
  267. RT_ASSERT((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_INIT);
  268. RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
  269. /* set current priority to init priority */
  270. thread->current_priority = thread->init_priority;
  271. /* calculate priority attribute */
  272. //优先级是否大于3232=2^5
  273. #if RT_THREAD_PRIORITY_MAX > 32
  274. thread->number = thread->current_priority >> 3; /* 5bit */
  275. thread->number_mask = 1L << thread->number;
  276. thread->high_mask = 1L << (thread->current_priority & 0x07); /* 3bit */
  277. #else
  278. thread->number_mask = 1L << thread->current_priority;
  279. #endif
  280. RT_DEBUG_LOG(RT_DEBUG_THREAD, ("startup a thread:%s with priority:%dn",
  281. thread->name, thread->init_priority));
  282. /* change thread stat */
  283. thread->stat = RT_THREAD_SUSPEND; //先挂起线程,等待调度
  284. /* then resume it */
  285. rt_thread_resume(thread);
  286. if (rt_thread_self() != RT_NULL)
  287. {
  288. /* do a scheduling */
  289. rt_schedule();
  290. }
  291. return RT_EOK;
  292. }
  293. RTM_EXPORT(rt_thread_startup);
  294. /**
  295. * This function will detach a thread. The thread object will be removed from
  296. * thread queue and detached/deleted from system object management.
  297. *
  298. * @param thread the thread to be deleted
  299. *
  300. * @return the operation status, RT_EOK on OK, -RT_ERROR on error
  301. */
  302. //静态线程脱离
  303. //脱离后内存不清理
  304. rt_err_t rt_thread_detach(rt_thread_t thread)
  305. {
  306. rt_base_t lock;
  307. /* thread check */
  308. RT_ASSERT(thread != RT_NULL);
  309. RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
  310. RT_ASSERT(rt_object_is_systemobject((rt_object_t)thread));
  311. if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_INIT)
  312. {
  313. /* remove from schedule */
  314. rt_schedule_remove_thread(thread);
  315. }
  316. /* release thread timer */
  317. rt_timer_detach(&(thread->thread_timer));
  318. /* change stat */
  319. thread->stat = RT_THREAD_CLOSE;
  320. if ((rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) &&
  321. thread->cleanup == RT_NULL)
  322. {
  323. rt_object_detach((rt_object_t)thread);
  324. }
  325. else
  326. {
  327. /* disable interrupt */
  328. lock = rt_hw_interrupt_disable();
  329. /* insert to defunct thread list */
  330. rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));
  331. /* enable interrupt */
  332. rt_hw_interrupt_enable(lock);
  333. }
  334. return RT_EOK;
  335. }
  336. RTM_EXPORT(rt_thread_detach);
  337. #ifdef RT_USING_HEAP
  338. /**
  339. * This function will create a thread object and allocate thread object memory
  340. * and stack.
  341. *
  342. * @param name the name of thread, which shall be unique
  343. * @param entry the entry function of thread
  344. * @param parameter the parameter of thread enter function
  345. * @param stack_size the size of thread stack
  346. * @param priority the priority of thread
  347. * @param tick the time slice if there are same priority thread
  348. *
  349. * @return the created thread object
  350. */
  351. //创建一个动态线程
  352. //需要分配堆内存 allocate
  353. rt_thread_t rt_thread_create(const char *name,
  354. void (*entry)(void *parameter),
  355. void *parameter,
  356. rt_uint32_t stack_size,
  357. rt_uint8_t priority,
  358. rt_uint32_t tick)
  359. {
  360. struct rt_thread *thread;
  361. void *stack_start;
  362. thread = (struct rt_thread *)rt_object_allocate(RT_Object_Class_Thread,
  363. name); //分配线程对象内存
  364. if (thread == RT_NULL)
  365. return RT_NULL;
  366. stack_start = (void *)RT_KERNEL_MALLOC(stack_size); //堆栈指针分配内存
  367. if (stack_start == RT_NULL)
  368. {
  369. /* allocate stack failure */
  370. rt_object_delete((rt_object_t)thread);
  371. return RT_NULL;
  372. }
  373. _rt_thread_init(thread,
  374. name,
  375. entry,
  376. parameter,
  377. stack_start,
  378. stack_size,
  379. priority,
  380. tick);
  381. return thread;
  382. }
  383. RTM_EXPORT(rt_thread_create);
  384. /**
  385. * This function will delete a thread. The thread object will be removed from
  386. * thread queue and deleted from system object management in the idle thread.
  387. *
  388. * @param thread the thread to be deleted
  389. *
  390. * @return the operation status, RT_EOK on OK, -RT_ERROR on error
  391. */
  392. //删除动态线程
  393. //内存同时释放
  394. rt_err_t rt_thread_delete(rt_thread_t thread)
  395. {
  396. rt_base_t lock;
  397. /* thread check */
  398. RT_ASSERT(thread != RT_NULL);
  399. RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
  400. RT_ASSERT(rt_object_is_systemobject((rt_object_t)thread) == RT_FALSE);
  401. if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_INIT)
  402. {
  403. /* remove from schedule */
  404. rt_schedule_remove_thread(thread); //一旦线程被删除,则它不再在调度之内logic
  405. }
  406. /* release thread timer */
  407. rt_timer_detach(&(thread->thread_timer));
  408. /* change stat */
  409. thread->stat = RT_THREAD_CLOSE;
  410. /* disable interrupt */
  411. lock = rt_hw_interrupt_disable();
  412. /* insert to defunct thread list */
  413. rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));
  414. /* enable interrupt */
  415. rt_hw_interrupt_enable(lock);
  416. return RT_EOK;
  417. }
  418. RTM_EXPORT(rt_thread_delete);
  419. #endif
  420. /**
  421. * This function will let current thread yield processor, and scheduler will
  422. * choose a highest thread to run. After yield processor, the current thread
  423. * is still in READY state.
  424. *
  425. * @return RT_EOK
  426. */
  427. rt_err_t rt_thread_yield(void)
  428. {
  429. rt_schedule();
  430. return RT_EOK;
  431. }
  432. RTM_EXPORT(rt_thread_yield);
  433. /**
  434. * This function will let current thread sleep for some ticks.
  435. *
  436. * @param tick the sleep ticks
  437. *
  438. * @return RT_EOK
  439. */
  440. rt_err_t rt_thread_sleep(rt_tick_t tick)
  441. {
  442. register rt_base_t temp;
  443. struct rt_thread *thread;
  444. /* set to current thread */
  445. thread = rt_thread_self();
  446. RT_ASSERT(thread != RT_NULL);
  447. RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
  448. /* disable interrupt */
  449. temp = rt_hw_interrupt_disable();
  450. /* suspend thread */
  451. rt_thread_suspend(thread);
  452. /* reset the timeout of thread timer and start it */
  453. rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &tick);
  454. rt_timer_start(&(thread->thread_timer));
  455. /* enable interrupt */
  456. rt_hw_interrupt_enable(temp);
  457. rt_schedule();
  458. /* clear error number of this thread to RT_EOK */
  459. if (thread->error == -RT_ETIMEOUT)
  460. thread->error = RT_EOK;
  461. return RT_EOK;
  462. }
  463. /**
  464. * This function will let current thread delay for some ticks.
  465. *
  466. * @param tick the delay ticks
  467. *
  468. * @return RT_EOK
  469. */
  470. //tick表示时间片,线程延时
  471. rt_err_t rt_thread_delay(rt_tick_t tick)
  472. {
  473. return rt_thread_sleep(tick);
  474. }
  475. RTM_EXPORT(rt_thread_delay);
  476. /**
  477. * This function will let current thread delay for some milliseconds.
  478. *
  479. * @param tick the delay time
  480. *
  481. * @return RT_EOK
  482. */
  483. rt_err_t rt_thread_mdelay(rt_int32_t ms)
  484. {
  485. rt_tick_t tick;
  486. tick = rt_tick_from_millisecond(ms);
  487. return rt_thread_sleep(tick);
  488. }
  489. RTM_EXPORT(rt_thread_mdelay);
  490. /**
  491. * This function will control thread behaviors according to control command.
  492. *
  493. * @param thread the specified thread to be controlled
  494. * @param cmd the control command, which includes
  495. * RT_THREAD_CTRL_CHANGE_PRIORITY for changing priority level of thread;
  496. * RT_THREAD_CTRL_STARTUP for starting a thread;
  497. * RT_THREAD_CTRL_CLOSE for delete a thread;
  498. * RT_THREAD_CTRL_BIND_CPU for bind the thread to a CPU.
  499. * @param arg the argument of control command
  500. *
  501. * @return RT_EOK
  502. */
  503. //当需要对线程进行一些其他控制时,例如动态更改线程的优先级,可以调用以下接口
  504. rt_err_t rt_thread_control(rt_thread_t thread, int cmd, void *arg)
  505. {
  506. register rt_base_t temp;
  507. /* thread check */
  508. RT_ASSERT(thread != RT_NULL);
  509. RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
  510. switch (cmd)
  511. {
  512. case RT_THREAD_CTRL_CHANGE_PRIORITY:
  513. /* disable interrupt */
  514. temp = rt_hw_interrupt_disable();
  515. /* for ready thread, change queue */
  516. if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_READY)
  517. {
  518. /* remove thread from schedule queue first */
  519. rt_schedule_remove_thread(thread);
  520. /* change thread priority */
  521. thread->current_priority = *(rt_uint8_t *)arg; //这里arg为新的优先级
  522. /* recalculate priority attribute */
  523. #if RT_THREAD_PRIORITY_MAX > 32
  524. thread->number = thread->current_priority >> 3; /* 5bit */
  525. thread->number_mask = 1 << thread->number;
  526. thread->high_mask = 1 << (thread->current_priority & 0x07); /* 3bit */
  527. #else
  528. thread->number_mask = 1 << thread->current_priority;
  529. #endif
  530. /* insert thread to schedule queue again */
  531. rt_schedule_insert_thread(thread);
  532. }
  533. else
  534. {
  535. thread->current_priority = *(rt_uint8_t *)arg;
  536. /* recalculate priority attribute */
  537. #if RT_THREAD_PRIORITY_MAX > 32
  538. thread->number = thread->current_priority >> 3; /* 5bit */
  539. thread->number_mask = 1 << thread->number;
  540. thread->high_mask = 1 << (thread->current_priority & 0x07); /* 3bit */
  541. #else
  542. thread->number_mask = 1 << thread->current_priority;
  543. #endif
  544. }
  545. /* enable interrupt */
  546. rt_hw_interrupt_enable(temp);
  547. break;
  548. case RT_THREAD_CTRL_STARTUP:
  549. return rt_thread_startup(thread);
  550. #ifdef RT_USING_HEAP
  551. case RT_THREAD_CTRL_CLOSE:
  552. return rt_thread_delete(thread); //此时关闭线程即为删除线程
  553. #endif
  554. #ifdef RT_USING_SMP
  555. case RT_THREAD_CTRL_BIND_CPU:
  556. {
  557. rt_uint8_t cpu;
  558. if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_INIT)
  559. {
  560. /* we only support bind cpu before started phase. */
  561. return RT_ERROR;
  562. }
  563. cpu = (rt_uint8_t)(size_t)arg;
  564. thread->bind_cpu = cpu > RT_CPUS_NR? RT_CPUS_NR : cpu;
  565. break;
  566. }
  567. #endif /*RT_USING_SMP*/
  568. default:
  569. break;
  570. }
  571. return RT_EOK;
  572. }
  573. RTM_EXPORT(rt_thread_control);
  574. /**
  575. * This function will suspend the specified thread.
  576. *
  577. * @param thread the thread to be suspended
  578. *
  579. * @return the operation status, RT_EOK on OK, -RT_ERROR on error
  580. *
  581. * @note if suspend self thread, after this function call, the
  582. * rt_schedule() must be invoked.
  583. */
  584. //线程挂起
  585. //通过调用此接口,线程从就绪状态转移到挂起状态
  586. rt_err_t rt_thread_suspend(rt_thread_t thread)
  587. {
  588. register rt_base_t stat;
  589. register rt_base_t temp;
  590. /* thread check */
  591. RT_ASSERT(thread != RT_NULL);
  592. RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
  593. RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread suspend: %sn", thread->name));
  594. stat = thread->stat & RT_THREAD_STAT_MASK; //得到当前线程状态,只有当线程在就绪或运行状态才可调用接口
  595. if ((stat != RT_THREAD_READY) && (stat != RT_THREAD_RUNNING))
  596. {
  597. RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread suspend: thread disorder, 0x%2xn",
  598. thread->stat));
  599. return -RT_ERROR;
  600. }
  601. /* disable interrupt */
  602. temp = rt_hw_interrupt_disable();
  603. if (stat == RT_THREAD_RUNNING)
  604. {
  605. /* not suspend running status thread on other core */
  606. RT_ASSERT(thread == rt_thread_self());
  607. }
  608. /* change thread stat */
  609. rt_schedule_remove_thread(thread);
  610. thread->stat = RT_THREAD_SUSPEND | (thread->stat & ~RT_THREAD_STAT_MASK);
  611. /* stop thread timer anyway */
  612. rt_timer_stop(&(thread->thread_timer));
  613. /* enable interrupt */
  614. rt_hw_interrupt_enable(temp);
  615. RT_OBJECT_HOOK_CALL(rt_thread_suspend_hook, (thread));
  616. return RT_EOK;
  617. }
  618. RTM_EXPORT(rt_thread_suspend);
  619. /**
  620. * This function will resume a thread and put it to system ready queue.
  621. *
  622. * @param thread the thread to be resumed
  623. *
  624. * @return the operation status, RT_EOK on OK, -RT_ERROR on error
  625. */
  626. rt_err_t rt_thread_resume(rt_thread_t thread)
  627. {
  628. register rt_base_t temp;
  629. /* thread check */
  630. RT_ASSERT(thread != RT_NULL);
  631. RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
  632. RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread resume: %sn", thread->name));
  633. if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_SUSPEND)
  634. {
  635. RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread resume: thread disorder, %dn",
  636. thread->stat));
  637. return -RT_ERROR;
  638. }
  639. /* disable interrupt */
  640. temp = rt_hw_interrupt_disable();
  641. /* remove from suspend list */
  642. rt_list_remove(&(thread->tlist));
  643. rt_timer_stop(&thread->thread_timer);
  644. /* enable interrupt */
  645. rt_hw_interrupt_enable(temp);
  646. /* insert to schedule ready list */
  647. rt_schedule_insert_thread(thread);
  648. RT_OBJECT_HOOK_CALL(rt_thread_resume_hook, (thread));
  649. return RT_EOK;
  650. }
  651. RTM_EXPORT(rt_thread_resume);
  652. /**
  653. * This function is the timeout function for thread, normally which is invoked
  654. * when thread is timeout to wait some resource.
  655. *
  656. * @param parameter the parameter of thread timeout function
  657. */
  658. //线程超时
  659. //在就绪状态停留一定时间后执行超时函数
  660. //形参*parameter是函数指针,超时时执行的超时函数
  661. void rt_thread_timeout(void *parameter)
  662. {
  663. struct rt_thread *thread;
  664. thread = (struct rt_thread *)parameter;
  665. /* thread check */
  666. RT_ASSERT(thread != RT_NULL);
  667. RT_ASSERT((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND);
  668. RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);
  669. /* set error number */
  670. thread->error = -RT_ETIMEOUT;
  671. /* remove from suspend list */
  672. rt_list_remove(&(thread->tlist));
  673. /* insert to schedule ready list */
  674. rt_schedule_insert_thread(thread);
  675. /* do schedule */
  676. rt_schedule();
  677. }
  678. RTM_EXPORT(rt_thread_timeout);
  679. /**
  680. * This function will find the specified thread.
  681. *
  682. * @param name the name of thread finding
  683. *
  684. * @return the found thread
  685. *
  686. * @note please don't invoke this function in interrupt status.
  687. */
  688. //通过线程名字找到对应的线程
  689. //返回所找到的线程结构体
  690. rt_thread_t rt_thread_find(char *name)
  691. {
  692. struct rt_object_information *information;
  693. struct rt_object *object;
  694. struct rt_list_node *node;
  695. /* enter critical */
  696. if (rt_thread_self() != RT_NULL)
  697. rt_enter_critical();
  698. /* try to find device object */
  699. information = rt_object_get_information(RT_Object_Class_Thread);
  700. RT_ASSERT(information != RT_NULL);
  701. //在线程对象链表中遍历,直到找到对应的线程
  702. for (node = information->object_list.next;
  703. node != &(information->object_list);
  704. node = node->next)
  705. {
  706. object = rt_list_entry(node, struct rt_object, list);
  707. if (rt_strncmp(object->name, name, RT_NAME_MAX) == 0)
  708. {
  709. /* leave critical */
  710. if (rt_thread_self() != RT_NULL)
  711. rt_exit_critical();
  712. return (rt_thread_t)object;
  713. }
  714. }
  715. /* leave critical */
  716. if (rt_thread_self() != RT_NULL)
  717. rt_exit_critical();
  718. /* not found */
  719. return RT_NULL;
  720. }
  721. RTM_EXPORT(rt_thread_find);
  722. /**@}*/

总结:

1.在判断条件是否满足时可以多用断言语句assert代替if……else……语句,简洁明了;

2.函数指针的作用,当函数指针带参数时,可以在使用它的接口函数中加入;

3.使用条件编译,可以使用#define ……来声明条件,移植性更强;

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/67345
推荐阅读
相关标签
  

闽ICP备14008679号