semaphore_sample.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*
  2. * Copyright (c) 2006-2018, 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/thread-sync/thread-sync/#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. ALIGN(RT_ALIGN_SIZE)
  26. static char thread1_stack[1024];
  27. static struct rt_thread thread1;
  28. static void rt_thread1_entry(void *parameter)
  29. {
  30. static rt_uint8_t count = 0;
  31. while (1)
  32. {
  33. if (count <= 100)
  34. {
  35. count++;
  36. }
  37. else
  38. return;
  39. /* count release semaphore every 10 counts */
  40. if (0 == (count % 10))
  41. {
  42. rt_kprintf("thread1 release a dynamic semaphore.\n");
  43. rt_sem_release(dynamic_sem);
  44. }
  45. }
  46. }
  47. ALIGN(RT_ALIGN_SIZE)
  48. static char thread2_stack[1024];
  49. static struct rt_thread thread2;
  50. static void rt_thread2_entry(void *parameter)
  51. {
  52. static rt_err_t result;
  53. static rt_uint8_t number = 0;
  54. while (1)
  55. {
  56. /* permanently wait for the semaphore; once obtain the semaphore, perform the number self-add operation */
  57. result = rt_sem_take(dynamic_sem, RT_WAITING_FOREVER);
  58. if (result != RT_EOK)
  59. {
  60. rt_kprintf("thread2 take a dynamic semaphore, failed.\n");
  61. rt_sem_delete(dynamic_sem);
  62. return;
  63. }
  64. else
  65. {
  66. number++;
  67. rt_kprintf("thread2 take a dynamic semaphore. number = %d\n", number);
  68. }
  69. }
  70. }
  71. int semaphore_sample()
  72. {
  73. /* create semaphtore and its initial value is 0 */
  74. dynamic_sem = rt_sem_create("dsem", 0, RT_IPC_FLAG_FIFO);
  75. if (dynamic_sem == RT_NULL)
  76. {
  77. rt_kprintf("create dynamic semaphore failed.\n");
  78. return -1;
  79. }
  80. else
  81. {
  82. rt_kprintf("create done. dynamic semaphore value = 0.\n");
  83. }
  84. rt_thread_init(&thread1,
  85. "thread1",
  86. rt_thread1_entry,
  87. RT_NULL,
  88. &thread1_stack[0],
  89. sizeof(thread1_stack),
  90. THREAD_PRIORITY, THREAD_TIMESLICE);
  91. rt_thread_startup(&thread1);
  92. rt_thread_init(&thread2,
  93. "thread2",
  94. rt_thread2_entry,
  95. RT_NULL,
  96. &thread2_stack[0],
  97. sizeof(thread2_stack),
  98. THREAD_PRIORITY - 1, THREAD_TIMESLICE);
  99. rt_thread_startup(&thread2);
  100. return 0;
  101. }
  102. /* export the msh command */
  103. MSH_CMD_EXPORT(semaphore_sample, semaphore sample);