semaphore_static.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*
  2. * 程序清单:静态信号量
  3. *
  4. * 这个例子中将创建一个静态信号量(初始值为0 )及一个静态线程,在这个静态线程中
  5. * 将试图采用超时方式去持有信号量,应该超时返回。然后这个线程释放一次信号量,并
  6. * 在后面继续采用永久等待方式去持有信号量, 成功获得信号量后返回。
  7. */
  8. #include <rtthread.h>
  9. #include "tc_comm.h"
  10. /* 线程控制块及栈 */
  11. static struct rt_thread thread;
  12. static rt_uint8_t thread_stack[THREAD_STACK_SIZE];
  13. /* 信号量控制块 */
  14. static struct rt_semaphore sem;
  15. /* 线程入口 */
  16. static void thread_entry(void* parameter)
  17. {
  18. rt_err_t result;
  19. rt_tick_t tick;
  20. /* 获得当前的OS Tick */
  21. tick = rt_tick_get();
  22. /* 试图持有信号量,最大等待10个OS Tick后返回 */
  23. result = rt_sem_take(&sem, 10);
  24. if (result == -RT_ETIMEOUT)
  25. {
  26. rt_tick_t new_tick = rt_tick_get();
  27. /* 可以有两个 tick 的误差 */
  28. if (new_tick - tick >= 12)
  29. {
  30. rt_kprintf("tick error to large: expect: 10, get %d\n",
  31. new_tick - tick);
  32. tc_done(TC_STAT_FAILED);
  33. rt_sem_detach(&sem);
  34. return;
  35. }
  36. rt_kprintf("take semaphore timeout\n");
  37. }
  38. else
  39. {
  40. /* 因为没有其他地方是否信号量,所以不应该成功持有信号量,否则测试失败 */
  41. tc_done(TC_STAT_FAILED);
  42. rt_sem_detach(&sem);
  43. return;
  44. }
  45. /* 释放一次信号量 */
  46. rt_sem_release(&sem);
  47. /* 永久等待方式持有信号量 */
  48. result = rt_sem_take(&sem, RT_WAITING_FOREVER);
  49. if (result != RT_EOK)
  50. {
  51. /* 不成功则测试失败 */
  52. tc_done(TC_STAT_FAILED);
  53. rt_sem_detach(&sem);
  54. return;
  55. }
  56. /* 测试通过 */
  57. tc_done(TC_STAT_PASSED);
  58. /* 脱离信号量对象 */
  59. rt_sem_detach(&sem);
  60. }
  61. int semaphore_static_init(void)
  62. {
  63. rt_err_t result;
  64. /* 初始化信号量,初始值是0 */
  65. result = rt_sem_init(&sem, "sem", 0, RT_IPC_FLAG_FIFO);
  66. if (result != RT_EOK)
  67. {
  68. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  69. return 0;
  70. }
  71. /* 初始化线程1 */
  72. result = rt_thread_init(&thread, "thread", /* 线程名:thread */
  73. thread_entry, RT_NULL, /* 线程的入口是thread_entry,入口参数是RT_NULL*/
  74. &thread_stack[0], sizeof(thread_stack), /* 线程栈是thread_stack */
  75. THREAD_PRIORITY, 10);
  76. if (result == RT_EOK) /* 如果返回正确,启动线程1 */
  77. rt_thread_startup(&thread);
  78. else
  79. tc_stat(TC_STAT_END | TC_STAT_FAILED);
  80. return 0;
  81. }
  82. #ifdef RT_USING_TC
  83. static void _tc_cleanup(void)
  84. {
  85. /* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
  86. rt_enter_critical();
  87. /* 执行线程脱离 */
  88. if (thread.stat != RT_THREAD_CLOSE)
  89. {
  90. rt_thread_detach(&thread);
  91. /* 执行信号量对象脱离 */
  92. rt_sem_detach(&sem);
  93. }
  94. /* 调度器解锁 */
  95. rt_exit_critical();
  96. /* 设置TestCase状态 */
  97. tc_done(TC_STAT_PASSED);
  98. }
  99. int _tc_semaphore_static(void)
  100. {
  101. /* 设置TestCase清理回调函数 */
  102. tc_cleanup(_tc_cleanup);
  103. semaphore_static_init();
  104. /* 返回TestCase运行的最长时间 */
  105. return 100;
  106. }
  107. /* 输出函数命令到finsh shell中 */
  108. FINSH_FUNCTION_EXPORT(_tc_semaphore_static, a static semaphore example);
  109. #else
  110. /* 用户应用入口 */
  111. int rt_application_init(void)
  112. {
  113. semaphore_static_init();
  114. return 0;
  115. }
  116. #endif