1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
#include "FreeRTOS.h"
#define TASK_STACK_SIZE (configMINIMAL_STACK_SIZE + 1000)
//#define USE_RX_ENVENT // permet de synchroniser les taches TX et RX
#define IGNORE_DUPPLICATE_EVENT // permet d'ignorer les évènements suppliqués (data->flags == 0)
typedef struct {
int taskId;
int val; // compteur pour debug
unsigned int flags;
SemaphoreHandle_t mutex;
SemaphoreHandle_t txEvent;
#ifdef USE_RX_ENVENT
SemaphoreHandle_t rxEvent;
#endif // USE_RX_ENVENT
} STRUCT_DATA;
static STRUCT_DATA local_data;
typedef struct {
int taskId;
STRUCT_DATA * data;
} STRUCT_TASK_INFO;
void sendTask(void *param){
STRUCT_TASK_INFO * context = (STRUCT_TASK_INFO*)param;
STRUCT_DATA * data = (STRUCT_DATA*)context->data;
while(1){
#ifdef USE_RX_ENVENT
// Wait Event
xSemaphoreTake(data->rxEvent, portMAX_DELAY);
#endif // USE_RX_ENVENT
int flagIsSet;
xSemaphoreTake(data->mutex, portMAX_DELAY);
data->taskId = context->taskId;
data->val++;
unsigned int bitmask = 1 << context->taskId;
if(data->flags & bitmask){
// Le précédent event n'a pas encore été traité par receiveTask()
// => pas besoin de renvoyer l'event
flagIsSet = 0;
} else {
data->flags |= bitmask;
flagIsSet = 1;
}
xSemaphoreGive(data->mutex);
if(flagIsSet){
// Send Event
xSemaphoreGive(data->txEvent);
}
}
}
void receiveTask(void *param){
STRUCT_DATA * data = (STRUCT_DATA*)param;
#ifdef USE_RX_ENVENT
// Send Event : task is ready
xSemaphoreGive(data->rxEvent);
#endif // USE_RX_ENVENT
while(1){
// Wait Event
xSemaphoreTake(data->txEvent, portMAX_DELAY);
xSemaphoreTake(data->mutex, portMAX_DELAY);
#ifdef IGNORE_DUPPLICATE_EVENT
if(data->flags){
#endif // IGNORE_DUPPLICATE_EVENT
int flag0 = (data->flags & 0x01 ? 1 : 0);
int flag1 = (data->flags & 0x02 ? 1 : 0);
int flag2 = (data->flags & 0x04 ? 1 : 0);
printf("[Task task%i] val %i, flag0:%i, flag1:%i, flag2:%i [flags count %i]\r\n",
data->taskId, data->val,
flag0, flag1, flag2,
flag0+flag1+flag2
);
if(data->flags == 0){
printf(" => [DUPPLICATE EVENT] flags = 0\r\n");
}
data->flags = 0; // clear flags
#ifdef IGNORE_DUPPLICATE_EVENT
}
#endif // IGNORE_DUPPLICATE_EVENT
xSemaphoreGive(data->mutex);
#ifdef USE_RX_ENVENT
// Send Event
xSemaphoreGive(data->rxEvent);
#endif // USE_RX_ENVENT
}
}
void app_init(void){
local_data.mutex = xSemaphoreCreateMutex();
local_data.txEvent = xSemaphoreCreateBinary();
#ifdef USE_RX_ENVENT
local_data.rxEvent = xSemaphoreCreateBinary();
#endif // USE_RX_ENVENT
static STRUCT_TASK_INFO task1Context;
task1Context.data = &local_data;
task1Context.taskId = 0;
static STRUCT_TASK_INFO task2Context;
task2Context.data = &local_data;
task2Context.taskId = 1;
static STRUCT_TASK_INFO task3Context;
task3Context.data = &local_data;
task3Context.taskId = 2;
xTaskCreate((TaskFunction_t) &receiveTask, "receiveTask", TASK_STACK_SIZE, &local_data, tskIDLE_PRIORITY+1, NULL);
xTaskCreate((TaskFunction_t) &sendTask, "task0", TASK_STACK_SIZE, &task1Context, tskIDLE_PRIORITY+1, NULL);
xTaskCreate((TaskFunction_t) &sendTask, "task1", TASK_STACK_SIZE, &task2Context, tskIDLE_PRIORITY+1, NULL);
xTaskCreate((TaskFunction_t) &sendTask, "task2", TASK_STACK_SIZE, &task3Context, tskIDLE_PRIORITY+1, NULL);
}
void main(void){
app_init();
vTaskStartScheduler();
} |
Partager