当前位置:   article > 正文

RT-Thread系列二 认识线程_rt-thread 判断有哪些线程

rt-thread 判断有哪些线程

什么是线程

在裸机系统开发中,系统的主体就是在main函数里面顺序执行的无限循环,在这个无限循环中,CPU按照顺序完成各种操作。在多线程系统中,根据功能的不同,把整个系统分割成一个个独立的且无法返回的函数,这个函数就成为线程,也可以称其为任务。

线程创建

定义线程栈

栈是单片机RAM里的一段连续的内存空间,栈的大小一般在启动文件或者链接脚本中指定,最后由C库函数__main进行初始化。

在多线程系统中,每个线程都是独立的、互不干扰的,所以要为每个线程都分配独立的栈空间。这个栈空间通常是一个预先定义好的全局数组,也可以是动态分配的一段内存空间。无论是哪种情况,栈空间都存在于RAM中。

定义线程栈的示例代码如下:

  1. ALIGN(RT_ALIGN_SIZE)
  2. rt_uint8_t thread1_stack[512];
  3. rt_uint8_t thread2_stack[1024];

定义线程函数

线程是一个独立的函数,函数主体无限循环且不能返回。如下代码所示:

  1. void thread1_entry(void *arg)
  2. {
  3. while(1)
  4. {
  5. flag1 = 1;
  6. delay(100);
  7. flag1 = 0;
  8. delay(100);
  9. }
  10. }
  11. void thread2_entry(void *arg)
  12. {
  13. while(1)
  14. {
  15. flag2 = 0;
  16. delay(100);
  17. flag2 = 1;
  18. delay(100);
  19. }
  20. }

定义线程控制块

在裸机系统中,程序的主体是CPU按照顺序执行的;而在多线程系统中,线程的执行则是由系统调度的。系统为了顺利地调度线程,会为每个线程单独定义一个线程控制块,这个线程控制块相当于线程的“身份证”,里边存有线程的所有信息。有了线程控制块这个“identifier”,系统以后对线程的全部操作都由其来实现。线程控制块在rtdef.h中声明,使用它可以为每个线程都定义一个线程控制块实体,代码如下所示:

  1. /**
  2. * Thread structure
  3. */
  4. struct rt_thread
  5. {
  6. /* rt object */
  7. char name[RT_NAME_MAX]; /**< the name of thread */
  8. rt_uint8_t type; /**< type of object */
  9. rt_uint8_t flags; /**< thread's flags */
  10. #ifdef RT_USING_MODULE
  11. void *module_id; /**< id of application module */
  12. #endif
  13. rt_list_t list; /**< the object list */
  14. rt_list_t tlist; /**< the thread list */
  15. /* stack point and entry */
  16. void *sp; /**< stack point */
  17. void *entry; /**< entry */
  18. void *parameter; /**< parameter */
  19. void *stack_addr; /**< stack address */
  20. rt_uint32_t stack_size; /**< stack size */
  21. /* error code */
  22. rt_err_t error; /**< error code */
  23. rt_uint8_t stat; /**< thread status */
  24. #ifdef RT_USING_SMP
  25. rt_uint8_t bind_cpu; /**< thread is bind to cpu */
  26. rt_uint8_t oncpu; /**< process on cpu */
  27. rt_uint16_t scheduler_lock_nest; /**< scheduler lock count */
  28. rt_uint16_t cpus_lock_nest; /**< cpus lock count */
  29. rt_uint16_t critical_lock_nest; /**< critical lock count */
  30. #endif /*RT_USING_SMP*/
  31. /* priority */
  32. rt_uint8_t current_priority; /**< current priority */
  33. #if RT_THREAD_PRIORITY_MAX > 32
  34. rt_uint8_t number;
  35. rt_uint8_t high_mask;
  36. #endif
  37. rt_uint32_t number_mask;
  38. #if defined(RT_USING_EVENT)
  39. /* thread event */
  40. rt_uint32_t event_set;
  41. rt_uint8_t event_info;
  42. #endif
  43. #if defined(RT_USING_SIGNALS)
  44. rt_sigset_t sig_pending; /**< the pending signals */
  45. rt_sigset_t sig_mask; /**< the mask bits of signal */
  46. #ifndef RT_USING_SMP
  47. void *sig_ret; /**< the return stack pointer from signal */
  48. #endif
  49. rt_sighandler_t *sig_vectors; /**< vectors of signal handler */
  50. void *si_list; /**< the signal infor list */
  51. #endif
  52. rt_ubase_t init_tick; /**< thread's initialized tick */
  53. rt_ubase_t remaining_tick; /**< remaining tick */
  54. #ifdef RT_USING_CPU_USAGE
  55. rt_uint64_t duration_tick; /**< cpu usage tick */
  56. #endif
  57. struct rt_timer thread_timer; /**< built-in thread timer */
  58. void (*cleanup)(struct rt_thread *tid); /**< cleanup function when thread exit */
  59. /* light weight process if present */
  60. #ifdef RT_USING_LWP
  61. void *lwp;
  62. #endif
  63. rt_ubase_t user_data; /**< private user data beyond this thread */
  64. };
  65. typedef struct rt_thread *rt_thread_t;

定义线程控制块的代码如下所示:

  1. struct rt_thread thread1;
  2. struct rt_thread thread2;

实现线程创建函数

线程的栈、函数实体和线程控制块最终需要联系起来才能由系统进行统一调度,这个联系的工作就由线程初始化函数rt_thread_init函数来实现。rt_thread_init函数在thread.c(src\thread.c)中实现,在thread.h(include\rtthread.h)中声明。函数实现代码如下所示:

  1. static rt_err_t _thread_init(struct rt_thread *thread,
  2. const char *name,
  3. void (*entry)(void *parameter),
  4. void *parameter,
  5. void *stack_start,
  6. rt_uint32_t stack_size,
  7. rt_uint8_t priority,
  8. rt_uint32_t tick)
  9. {
  10. /* init thread list */
  11. rt_list_init(&(thread->tlist));
  12. thread->entry = (void *)entry;
  13. thread->parameter = parameter;
  14. /* stack init */
  15. thread->stack_addr = stack_start;
  16. thread->stack_size = stack_size;
  17. /* init thread stack */
  18. rt_memset(thread->stack_addr, '#', thread->stack_size);
  19. #ifdef ARCH_CPU_STACK_GROWS_UPWARD
  20. thread->sp = (void *)rt_hw_stack_init(thread->entry, thread->parameter,
  21. (void *)((char *)thread->stack_addr),
  22. (void *)_thread_exit);
  23. #else
  24. thread->sp = (void *)rt_hw_stack_init(thread->entry, thread->parameter,
  25. (rt_uint8_t *)((char *)thread->stack_addr + thread->stack_size - sizeof(rt_ubase_t)),
  26. (void *)_thread_exit);
  27. #endif /* ARCH_CPU_STACK_GROWS_UPWARD */
  28. /* priority init */
  29. RT_ASSERT(priority < RT_THREAD_PRIORITY_MAX);
  30. thread->current_priority = priority;
  31. thread->number_mask = 0;
  32. #ifdef RT_USING_EVENT
  33. thread->event_set = 0;
  34. thread->event_info = 0;
  35. #endif
  36. #if RT_THREAD_PRIORITY_MAX > 32
  37. thread->number = 0;
  38. thread->high_mask = 0;
  39. #endif /* RT_THREAD_PRIORITY_MAX > 32 */
  40. /* tick init */
  41. thread->init_tick = tick;
  42. thread->remaining_tick = tick;
  43. /* error and flags */
  44. thread->error = RT_EOK;
  45. thread->stat = RT_THREAD_INIT;
  46. #ifdef RT_USING_SMP
  47. /* not bind on any cpu */
  48. thread->bind_cpu = RT_CPUS_NR;
  49. thread->oncpu = RT_CPU_DETACHED;
  50. /* lock init */
  51. thread->scheduler_lock_nest = 0;
  52. thread->cpus_lock_nest = 0;
  53. thread->critical_lock_nest = 0;
  54. #endif /* RT_USING_SMP */
  55. /* initialize cleanup function and user data */
  56. thread->cleanup = 0;
  57. thread->user_data = 0;
  58. /* initialize thread timer */
  59. rt_timer_init(&(thread->thread_timer),
  60. thread->name,
  61. _thread_timeout,
  62. thread,
  63. 0,
  64. RT_TIMER_FLAG_ONE_SHOT);
  65. /* initialize signal */
  66. #ifdef RT_USING_SIGNALS
  67. thread->sig_mask = 0x00;
  68. thread->sig_pending = 0x00;
  69. #ifndef RT_USING_SMP
  70. thread->sig_ret = RT_NULL;
  71. #endif /* RT_USING_SMP */
  72. thread->sig_vectors = RT_NULL;
  73. thread->si_list = RT_NULL;
  74. #endif /* RT_USING_SIGNALS */
  75. #ifdef RT_USING_LWP
  76. thread->lwp = RT_NULL;
  77. #endif /* RT_USING_LWP */
  78. #ifdef RT_USING_CPU_USAGE
  79. thread->duration_tick = 0;
  80. #endif
  81. #ifdef RT_USING_MODULE
  82. thread->module_id = 0;
  83. #endif
  84. thread->user_data = 0;
  85. RT_OBJECT_HOOK_CALL(rt_thread_inited_hook, (thread));
  86. return RT_EOK;
  87. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/67310
推荐阅读
相关标签
  

闽ICP备14008679号