test_semaphore_counting_dynamic.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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. */
  10. /*
  11. * Demo: semaphore
  12. * This demo creates one counting semaphore dynamically
  13. * It creates two tasks:
  14. * 1) task #1: take the semaphore until its value reaches 0
  15. * 2) task #2: give the semaphore until its value reaches maximum
  16. *
  17. */
  18. #include <FreeRTOS.h>
  19. #include <semphr.h>
  20. #include <task.h>
  21. #define TASK_PRIORITY (FINSH_THREAD_PRIORITY + 1)
  22. /* Semaphore handle */
  23. static SemaphoreHandle_t dynamic_sem = NULL;
  24. static TaskHandle_t TaskHandle1 = NULL;
  25. static TaskHandle_t TaskHandle2 = NULL;
  26. static void vTask1Code(void *pvParameters)
  27. {
  28. static BaseType_t result;
  29. static BaseType_t number = 0;
  30. while (1)
  31. {
  32. /* Task1 starts when task2 is delayed. Semaphore value is 5. Should take it successfully for five times */
  33. for (number = 0; number < 5; number++)
  34. {
  35. result = xSemaphoreTake(dynamic_sem, portMAX_DELAY);
  36. if (result != pdPASS)
  37. {
  38. rt_kprintf("task1 take a dynamic semaphore, failed.\n");
  39. return;
  40. }
  41. else
  42. {
  43. rt_kprintf("task1 take a dynamic semaphore. number = %d\n", number);
  44. }
  45. }
  46. /* Cannot take the semaphore for the sixth time because the value is 0 */
  47. result = xSemaphoreTake(dynamic_sem, 0);
  48. if (result != errQUEUE_EMPTY)
  49. {
  50. rt_kprintf("task1 take a dynamic semaphore. number = %d. Should not succeed.\n", number);
  51. }
  52. vTaskDelay(pdMS_TO_TICKS(5000));
  53. }
  54. }
  55. static void vTask2Code(void * pvParameters)
  56. {
  57. static BaseType_t result;
  58. static BaseType_t number = 0;
  59. while (1)
  60. {
  61. /* Task2 runs before task1. The semaphore value is 0. Should give the semaphore 5 times successfully */
  62. for (number = 0; number < 5; number++)
  63. {
  64. result = xSemaphoreGive(dynamic_sem);
  65. if (result != pdPASS)
  66. {
  67. rt_kprintf("task2 release a dynamic semaphore, failed.\n");
  68. return;
  69. }
  70. else
  71. {
  72. rt_kprintf("task2 release a dynamic semaphore. number = %d\n", number);
  73. }
  74. }
  75. /* Cannot give the semaphore for the sixth time because the max value is reached */
  76. result = xSemaphoreGive(dynamic_sem);
  77. if (result != errQUEUE_FULL)
  78. {
  79. rt_kprintf("task2 release a dynamic semaphore. number = %d. Should not succeed.\n", number);
  80. }
  81. vTaskDelay(pdMS_TO_TICKS(5000));
  82. }
  83. }
  84. int semaphore_counting_dynamic()
  85. {
  86. /* Create a counting semaphore dynamically. Max value is 5. Initial value is 0. */
  87. dynamic_sem = xSemaphoreCreateCounting(5, 0);
  88. if (dynamic_sem == NULL)
  89. {
  90. rt_kprintf("create dynamic semaphore failed.\n");
  91. return -1;
  92. }
  93. xTaskCreate( vTask2Code, "Task2", configMINIMAL_STACK_SIZE, NULL, TASK_PRIORITY + 1, &TaskHandle2 );
  94. if (TaskHandle2 == NULL)
  95. {
  96. rt_kprintf("Create task 2 failed\n");
  97. return -1;
  98. }
  99. xTaskCreate( vTask1Code, "Task1", configMINIMAL_STACK_SIZE, NULL, TASK_PRIORITY, &TaskHandle1 );
  100. if (TaskHandle1 == NULL)
  101. {
  102. rt_kprintf("Create task 1 failed\n");
  103. return -1;
  104. }
  105. return 0;
  106. }
  107. MSH_CMD_EXPORT(semaphore_counting_dynamic, semaphore sample);