semaphore_sample.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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. * 2018-08-24 yangjie the first version
  9. * 2020-10-17 Meco Man translate to English comment
  10. */
  11. /*
  12. * Demo: semaphore
  13. * This demo creates one semaphore and two threads:
  14. * 1) thread #1: release the semaphore
  15. * 2) thread #2: receive the semaphore
  16. *
  17. * read more:
  18. * https://www.rt-thread.io/document/site/programming-manual/ipc1/ipc1/#semaphores
  19. */
  20. #include <rtthread.h>
  21. #define THREAD_PRIORITY 25
  22. #define THREAD_TIMESLICE 5
  23. /* semaphore handler */
  24. static rt_sem_t dynamic_sem = RT_NULL;
  25. #ifdef rt_align
  26. rt_align(RT_ALIGN_SIZE)
  27. #else
  28. ALIGN(RT_ALIGN_SIZE)
  29. #endif
  30. static char thread1_stack[1024];
  31. static struct rt_thread thread1;
  32. static void rt_thread1_entry(void *parameter)
  33. {
  34. static rt_uint8_t count = 0;
  35. while (1)
  36. {
  37. if (count <= 100)
  38. {
  39. count++;
  40. }
  41. else
  42. return;
  43. /* count release semaphore every 10 counts */
  44. if (0 == (count % 10))
  45. {
  46. rt_kprintf("thread1 release a dynamic semaphore.\n");
  47. rt_sem_release(dynamic_sem);
  48. }
  49. }
  50. }
  51. #ifdef rt_align
  52. rt_align(RT_ALIGN_SIZE)
  53. #else
  54. ALIGN(RT_ALIGN_SIZE)
  55. #endif
  56. static char thread2_stack[1024];
  57. static struct rt_thread thread2;
  58. static void rt_thread2_entry(void *parameter)
  59. {
  60. static rt_err_t result;
  61. static rt_uint8_t number = 0;
  62. while (1)
  63. {
  64. /* permanently wait for the semaphore; once obtain the semaphore, perform the number self-add operation */
  65. result = rt_sem_take(dynamic_sem, RT_WAITING_FOREVER);
  66. if (result != RT_EOK)
  67. {
  68. rt_kprintf("thread2 take a dynamic semaphore, failed.\n");
  69. rt_sem_delete(dynamic_sem);
  70. return;
  71. }
  72. else
  73. {
  74. number++;
  75. rt_kprintf("thread2 take a dynamic semaphore. number = %d\n", number);
  76. }
  77. }
  78. }
  79. int semaphore_sample()
  80. {
  81. /* create semaphtore and its initial value is 0 */
  82. dynamic_sem = rt_sem_create("dsem", 0, RT_IPC_FLAG_PRIO);
  83. if (dynamic_sem == RT_NULL)
  84. {
  85. rt_kprintf("create dynamic semaphore failed.\n");
  86. return -1;
  87. }
  88. else
  89. {
  90. rt_kprintf("create done. dynamic semaphore value = 0.\n");
  91. }
  92. rt_thread_init(&thread1,
  93. "thread1",
  94. rt_thread1_entry,
  95. RT_NULL,
  96. &thread1_stack[0],
  97. sizeof(thread1_stack),
  98. THREAD_PRIORITY, THREAD_TIMESLICE);
  99. #ifdef RT_USING_SMP
  100. /* Bind threads to the same core to avoid messy log output when multiple cores are enabled */
  101. rt_thread_control(&thread1, RT_THREAD_CTRL_BIND_CPU, (void*)0);
  102. #endif
  103. rt_thread_startup(&thread1);
  104. rt_thread_init(&thread2,
  105. "thread2",
  106. rt_thread2_entry,
  107. RT_NULL,
  108. &thread2_stack[0],
  109. sizeof(thread2_stack),
  110. THREAD_PRIORITY - 1, THREAD_TIMESLICE);
  111. #ifdef RT_USING_SMP
  112. /* Bind threads to the same core to avoid messy log output when multiple cores are enabled */
  113. rt_thread_control(&thread2, RT_THREAD_CTRL_BIND_CPU, (void*)0);
  114. #endif
  115. rt_thread_startup(&thread2);
  116. return 0;
  117. }
  118. /* export the msh command */
  119. MSH_CMD_EXPORT(semaphore_sample, semaphore sample);