Untitled

mail@pastecode.io avatar
unknown
plain_text
a month ago
10 kB
3
Indexable
Never
#include <stdio.h>
#include <stdlib.h>
#include "diag/trace.h"
#include <stdint.h>
#include <limits.h>
#include "led.h"

/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "timers.h"
#include "semphr.h"

#define CCM_RAM __attribute__((section(".ccmram")))
#define FIXED_Receiver_Time pdMS_TO_TICKS(100)

// LED-related definitions
#define BLINK_PORT_NUMBER         (3)
#define BLINK_PIN_NUMBER_GREEN    (12)
#define BLINK_PIN_NUMBER_ORANGE   (13)
#define BLINK_PIN_NUMBER_RED      (14)
#define BLINK_PIN_NUMBER_BLUE     (15)
#define BLINK_ACTIVE_LOW          (false)

struct led blinkLeds[4];

static void prvOneShotTimerCallback(TimerHandle_t xTimer);
static void prvAutoReloadTimerCallback(TimerHandle_t xTimer);

// Timer handles
static TimerHandle_t xTimerOneShot = NULL;
static TimerHandle_t xTimerAutoReload = NULL;
BaseType_t xTimer1Started, xTimer2Started;

// Task and Queue handles
QueueHandle_t xQueue;
SemaphoreHandle_t xSemaphoreSender1, xSemaphoreSender2, xSemaphoreSender3, xSemaphoreReceiver;

int Tsender1, Tsender2, Tsender3, Treceiver;
int lower_arr[6] = {50, 80, 110, 140, 170, 200};
int upper_arr[6] = {150, 200, 250, 300, 350, 400};
int sent1, sent2, sent3, block1, block2, block3;
int received_message, total_number_of_blocked_messages, total_number_of_successfully_sent_messages, upper, lower;
int iteration = -1;

// Uniform distribution function
int uniform_dist(int lower, int upper) {
    return rand() % (upper - lower + 1) ;
}

// Sender task functions
void static Sender1(void *parameters) {
    char ivaluetosend[50];
    BaseType_t xStatus;

    while (1) {
        if (xSemaphoreTake(xSemaphoreSender1, portMAX_DELAY) == pdPASS) {
            snprintf(ivaluetosend, sizeof(ivaluetosend), "Time is %lu", xTaskGetTickCount());
            xStatus = xQueueSend(xQueue, ivaluetosend, 0);
            if (xStatus == pdPASS) {
                sent1++;
            } else {
                block1++;
            }
        }
    }
}

void static Sender2(void *parameters) {
    char ivaluetosend[50];
    BaseType_t xStatus;

    while (1) {
        if (xSemaphoreTake(xSemaphoreSender2, portMAX_DELAY) == pdPASS) {
            snprintf(ivaluetosend, sizeof(ivaluetosend), "Time is %lu", xTaskGetTickCount());
            xStatus = xQueueSend(xQueue, ivaluetosend, 0);
            if (xStatus == pdPASS) {
                sent2++;
            } else {
                block2++;
            }
        }
    }
}

void static Sender3(void *parameters) {
    char ivaluetosend[50];
    BaseType_t xStatus;
    xStatus = xSemaphoreTake(xSemaphoreSender3, portMAX_DELAY);
    while (1) {
        // Wait until the semaphore is given
        if (xSemaphoreTake(xSemaphoreSender3, portMAX_DELAY) == pdPASS) {
            // Format the message to be sent to the queue
            snprintf(ivaluetosend, sizeof(ivaluetosend), "Time is %lu", xTaskGetTickCount());

            // Trace print the message before sending it
         //   trace_printf("Sender3: Sending message: %s\n", ivaluetosend);

            // Try to send the message to the queue
            xStatus = xQueueSend(xQueue, ivaluetosend, 0);

            // Update the counters based on whether the message was sent or blocked
            if (xStatus == pdPASS) {
                sent3++;
            } else {
                block3++;
            }
        }
    }
}


// Receiver task function
static void Receiver(void *parameters) {
    char receivedValue[20];
    BaseType_t xStatus;
    const TickType_t ticksToWait = pdMS_TO_TICKS(100);

    while (1) {
        xStatus = xQueueReceive(xQueue, &receivedValue, ticksToWait);
        if (xStatus == pdPASS) {
            received_message++;
        }

        if (received_message == 250) {
            Reset();
        }
    }
}

// Timer callback functions
void vSender1TimerCallback(TimerHandle_t xTimer) {
    xSemaphoreGive(xSemaphoreSender1);
}

void vSender2TimerCallback(TimerHandle_t xTimer) {
    xSemaphoreGive(xSemaphoreSender2);
}

void vSender3TimerCallback(TimerHandle_t xTimer) {
	//   trace_printf("hello callback3");
    xSemaphoreGive(xSemaphoreSender3);

}

void vReceiverTimerCallback(TimerHandle_t xTimer) {
    xSemaphoreGive(xSemaphoreReceiver);
}

// Reset function
void Reset() {
    if (iteration == -1) { // Initial start
        received_message = 0;
        iteration++;
        upper = upper_arr[iteration];
        lower = lower_arr[iteration];
        Tsender1 = uniform_dist(lower, upper);
        Tsender2 = uniform_dist(lower, upper);
        Tsender3 = uniform_dist(lower, upper);
    } else if (iteration <= 5) {
        total_number_of_successfully_sent_messages = sent1 + sent2 + sent3;
        total_number_of_blocked_messages = block1 + block2 + block3;

        printf("Total Successful Messages: %d\n", total_number_of_successfully_sent_messages);
        printf("Total blocked Messages: %d\n", total_number_of_blocked_messages);
        printf("Statistics for highest priority:\n");
        printf("  Total Successful Messages: %d\n", sent1);
        printf("  Total Blocked Messages: %d\n", block1);
        printf("Statistics for first lower priority:\n");
        printf("  Total Successful Messages: %d\n", sent2);
        printf("  Total Blocked Messages: %d\n", block2);
        printf("Statistics for second lower priority:\n");
        printf("  Total Successful Messages: %d\n", sent3);
        printf("  Total Blocked Messages: %d\n", block3);
        printf("  Avg Tsender : %d\n", (Tsender1+Tsender2+Tsender3)/iteration);
        printf("   Tsender3 : %d\n", Tsender3);

        iteration++;
        upper = upper_arr[iteration];
        lower = lower_arr[iteration];
    } else {
        printf("Game Over\n");
        exit(0);
        vTaskEndScheduler();
        return;
    }

    // Reset counters
    total_number_of_successfully_sent_messages = 0;
    total_number_of_blocked_messages = 0;
    received_message = 0;
    sent1 = 0;
    sent2 = 0;
    sent3 = 0;
    block1 = 0;
    block2 = 0;
    block3 = 0;

    xQueueReset(xQueue);
}

int main() {
    xQueue = xQueueCreate(3, sizeof(char[50]));

    if (iteration == -1) {
        Reset();
    }

    xSemaphoreSender1 = xSemaphoreCreateBinary();
    xSemaphoreSender2 = xSemaphoreCreateBinary();
    xSemaphoreSender3 = xSemaphoreCreateBinary();
    xSemaphoreReceiver = xSemaphoreCreateBinary();

    TaskHandle_t xSender1Handle, xSender2Handle, xSender3Handle, xReceiverHandle;

    xTaskCreate(Sender1, "Sender1", 2500, NULL, 1, &xSender1Handle);
    xTaskCreate(Sender2, "Sender2", 2500, NULL, 1, &xSender2Handle);
    xTaskCreate(Sender3, "Sender3", 2500, NULL, 2, &xSender3Handle);
    xTaskCreate(Receiver, "Receiver", 2500, NULL, 3, &xReceiverHandle);

    TimerHandle_t xTimer1 = xTimerCreate("Tsender1",Tsender1 , pdTRUE, (void *)1, vSender1TimerCallback);
    TimerHandle_t xTimer2 = xTimerCreate("Tsender2", Tsender2, pdTRUE, (void *)2, vSender2TimerCallback);
    TimerHandle_t xTimer3 = xTimerCreate("Tsender3", Tsender3, pdTRUE, (void *)3, vSender3TimerCallback);
    TimerHandle_t xTimer4 = xTimerCreate("Treceiver", FIXED_Receiver_Time, pdTRUE, (void *)4, vReceiverTimerCallback);

    xTimerStart(xTimer1, 0);
    xTimerStart(xTimer2, 0);
    xTimerStart(xTimer3, 0);
    xTimerStart(xTimer4, 0);

    // LED setup
    blinkLeds[0] = createLed(BLINK_PORT_NUMBER, BLINK_PIN_NUMBER_GREEN, BLINK_ACTIVE_LOW);
    blinkLeds[1] = createLed(BLINK_PORT_NUMBER, BLINK_PIN_NUMBER_ORANGE, BLINK_ACTIVE_LOW);
    blinkLeds[2] = createLed(BLINK_PORT_NUMBER, BLINK_PIN_NUMBER_RED, BLINK_ACTIVE_LOW);
    blinkLeds[3] = createLed(BLINK_PORT_NUMBER, BLINK_PIN_NUMBER_BLUE, BLINK_ACTIVE_LOW);

    for (int i = 0; i < 4; i++) {
        power_up(&blinkLeds[i]);
    }

    xTimerOneShot = xTimerCreate("Timer1", pdMS_TO_TICKS(2000), pdFALSE, (void *)0, prvOneShotTimerCallback);
    xTimerAutoReload = xTimerCreate("Timer2", pdMS_TO_TICKS(1000), pdTRUE, (void *)1, prvAutoReloadTimerCallback);

    if (xTimerOneShot != NULL && xTimerAutoReload != NULL) {
        xTimer1Started = xTimerStart(xTimerOneShot, 0);
        xTimer2Started = xTimerStart(xTimerAutoReload, 0);
    }

    if (xTimer1Started == pdPASS && xTimer2Started == pdPASS) {
        vTaskStartScheduler();
    }

    return 0;
}

#pragma GCC diagnostic pop

// Timer callback implementations
static void prvOneShotTimerCallback(TimerHandle_t xTimer) {
    trace_puts("One-shot timer callback executing");
    turn_on(&blinkLeds[1]);
}

static void prvAutoReloadTimerCallback(TimerHandle_t xTimer) {
    trace_puts("Auto-Reload timer callback executing");

    if (isOn(blinkLeds[0])) {
        turn_off(&blinkLeds[0]);
    } else {
        turn_on(&blinkLeds[0]);
    }
}

// FreeRTOS hook functions
void vApplicationMallocFailedHook(void) {
    for (;;);
}

void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName) {
    (void)pcTaskName;
    (void)pxTask;
    for (;;);
}

void vApplicationIdleHook(void) {
    volatile size_t xFreeStackSpace = xPortGetFreeHeapSize();
    if (xFreeStackSpace > 100) {
        // Adjust heap size if needed
    }
}

void vApplicationTickHook(void) {}

StaticTask_t xIdleTaskTCB CCM_RAM;
StackType_t uxIdleTaskStack[configMINIMAL_STACK_SIZE] CCM_RAM;

void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) {
    *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
    *ppxIdleTaskStackBuffer = uxIdleTaskStack;
    *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}

StaticTask_t xTimerTaskTCB CCM_RAM;
StackType_t uxTimerTaskStack[configTIMER_TASK_STACK_DEPTH] CCM_RAM;

void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize) {
    *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
    *ppxTimerTaskStackBuffer = uxTimerTaskStack;
    *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}
Leave a Comment