TencentOS-tiny task communication (IV) - semaphore

First, the inter-task communication

1, the semaphore

Outline

Semaphore is a mechanism to achieve synchronization between tasks, generally for limited competition for resources among multiple tasks access.

Typically, a semaphore value in a plastic holder, to indicate the number of available resources. When the number of a semaphore resources available is greater than 0, the task attempts to acquire the semaphore is successful, the number of available resource semaphore minus one; when the number of available resources, a semaphore is equal to 0, the task attempts to acquire the semaphore failed or into blocking state. Semaphore this mode, when the number of available resources is 1, can be used for mutually exclusive access to resources; or solve the producer - consumer issues in resource production - consumption problem. Programming Examples chapter will demonstrate the producer - consumer problem solving paradigm.

API to explain

Programming Example

1, in tos_config.h, the switch assembly arranged semaphore TOS_CFG_SEM_EN:

#define TOS_CFG_SEM_EN 1u

2, preparation of the sample code main.c:

/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "cmsis_os.h" 
#include "stdio.h"

#include "tos_k.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define STK_SIZE_TASK_PRODUCER      512
#define STK_SIZE_TASK_CONSUMER      512

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
k_stack_t stack_task_producer[STK_SIZE_TASK_PRODUCER];
k_stack_t stack_task_consumer[STK_SIZE_TASK_CONSUMER];

k_task_t task_producer;
k_task_t task_consumer;

extern void entry_task_producer(void *arg);
extern void entry_task_consumer(void *arg);

k_mutex_t buffer_locker;
k_sem_t full;
k_sem_t empty;

#define RESOURCE_COUNT_MAX      3

struct resource_st {
    int cursor;
    uint32_t buffer[RESOURCE_COUNT_MAX];
} resource = { 0, {0} };

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
static void produce_item(int salt)
{
    printf("produce item:\n");

    printf("%d", salt);
    resource.buffer[resource.cursor++] = salt;
    printf("\n");
}

void entry_task_producer(void *arg)
{
    size_t salt = 0;
    k_err_t err;

    while (K_TRUE) {
        err = tos_sem_pend(&empty, TOS_TIME_FOREVER);
        if (err != K_ERR_NONE) {
            continue;
        }
        err = tos_mutex_pend(&buffer_locker);
        if (err != K_ERR_NONE) {
            continue;
        }

        produce_item(salt);

        tos_mutex_post(&buffer_locker);
        tos_sem_post(&full);
        tos_task_delay(1000);
        ++salt;
    }
}

static void consume_item(void)
{
    printf("cosume item:\n");
    printf("%d\t", resource.buffer[--resource.cursor]);
    printf("\n");
}

void entry_task_consumer(void *arg)
{
    k_err_t err;

    while (K_TRUE) {
        err = tos_sem_pend(&full, TOS_TIME_FOREVER);
        if (err != K_ERR_NONE) {
            continue;
        }
        tos_mutex_pend(&buffer_locker);
        if (err != K_ERR_NONE) {
            continue;
        }

        consume_item();

        tos_mutex_post(&buffer_locker);
        tos_sem_post(&empty);
        tos_task_delay(2000);
    }
}

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	
	tos_knl_init();
	tos_mutex_create(&buffer_locker);
	tos_sem_create(&full, 0);
	tos_sem_create(&empty, RESOURCE_COUNT_MAX);
	(void)tos_task_create(&task_producer, "producer", entry_task_producer, NULL,
													4, stack_task_producer, STK_SIZE_TASK_PRODUCER, 0);
	(void)tos_task_create(&task_consumer, "consumer", entry_task_consumer, NULL,
													4, stack_task_consumer, STK_SIZE_TASK_CONSUMER, 0);
	tos_knl_start();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		
  }
  /* USER CODE END 3 */
}

3, the effect of travel:

Source link

Published 51 original articles · won praise 72 · views 720 000 +

Guess you like

Origin blog.csdn.net/qq_36075612/article/details/105070651