Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /********* Pleasedontcode.com **********
- Pleasedontcode thanks you for automatic code generation! Enjoy your code!
- - Terms and Conditions:
- You have a non-exclusive, revocable, worldwide, royalty-free license
- for personal and commercial use. Attribution is optional; modifications
- are allowed, but you're responsible for code maintenance. We're not
- liable for any loss or damage. For full terms,
- please visit pleasedontcode.com/termsandconditions.
- - Project: "Button Management"
- - Source Code NOT compiled for: Arduino Uno
- - Source Code created on: 2025-04-18 05:41:53
- ********* Pleasedontcode.com **********/
- /****** SYSTEM REQUIREMENTS *****/
- /****** SYSTEM REQUIREMENT 1 *****/
- /* Each resource is represented by an RGB LED: Green */
- /* = free Red = locked Yellow = waiting Tasks try */
- /* to lock resources in opposite order, */
- /* causingdeadlock if both run simultaneously. */
- /* system detects deadlock and recovers by forcing */
- /* one task to release */
- /****** END SYSTEM REQUIREMENTS *****/
- /* START CODE */
- /****** DEFINITION OF LIBRARIES *****/
- #include <EasyButton.h> //https://github.com/evert-arias/EasyButton
- /****** FUNCTION PROTOTYPES *****/
- void setup(void);
- void loop(void);
- /***** DEFINITION OF DIGITAL INPUT PINS *****/
- const uint8_t push_button_PushButton_PIN_D2 = 2;
- const uint8_t push_button_PushButton_PIN_D3 = 3;
- // RGB LED pins for Resource A
- const int resA_R = 8;
- const int resA_G = 9;
- const int resA_B = 10;
- // RGB LED pins for Resource B
- const int resB_R = 11;
- const int resB_G = 12;
- const int resB_B = 13;
- /***** DEFINITION OF DIGITAL OUTPUT PINS *****/
- // Task states
- enum TaskState {IDLE, LOCK_RES1, WAIT_RES2, LOCK_RES2, WORKING, RELEASE_RES2, RELEASE_RES1};
- enum Resource {FREE, LOCKED};
- struct ResourceMutex {
- volatile Resource state;
- int lockedBy; // -1 if free, else task ID
- };
- ResourceMutex resourceA = {FREE, -1};
- ResourceMutex resourceB = {FREE, -1};
- // Task variables
- TaskState task1State = IDLE;
- TaskState task2State = IDLE;
- unsigned long lastMillis = 0;
- const unsigned long taskInterval = 100; // ms
- // Task IDs
- const int TASK1 = 1;
- const int TASK2 = 2;
- // Button states
- bool button1Pressed = false;
- bool button2Pressed = false;
- // Timing for simulated work
- unsigned long task1Timer = 0;
- unsigned long task2Timer = 0;
- const unsigned long workDuration = 2000; // 2 seconds
- // Deadlock detection timer
- unsigned long deadlockCheckTimer = 0;
- const unsigned long deadlockCheckInterval = 1000; // 1 sec
- // Helper function to set RGB LED color
- void setRGB(int rPin, int gPin, int bPin, int rVal, int gVal, int bVal) {
- analogWrite(rPin, rVal);
- analogWrite(gPin, gVal);
- analogWrite(bPin, bVal);
- }
- // Set resource LED based on state
- void updateResourceLED(ResourceMutex &res, int rPin, int gPin, int bPin) {
- if (res.state == FREE) {
- // Green
- setRGB(rPin, gPin, bPin, 0, 255, 0);
- } else {
- // Red
- setRGB(rPin, gPin, bPin, 255, 0, 0);
- }
- }
- // Set resource LED to yellow (waiting)
- void setResourceWaiting(int rPin, int gPin, int bPin) {
- setRGB(rPin, gPin, bPin, 255, 255, 0);
- }
- // Attempt to lock a resource
- bool tryLockResource(ResourceMutex &res, int taskID) {
- if (res.state == FREE) {
- res.state = LOCKED;
- res.lockedBy = taskID;
- return true;
- }
- return false;
- }
- // Release a resource
- void releaseResource(ResourceMutex &res, int taskID) {
- if (res.lockedBy == taskID) {
- res.state = FREE;
- res.lockedBy = -1;
- }
- }
- // Deadlock detection: if both tasks are waiting for each other's resource
- bool detectDeadlock() {
- if (task1State == WAIT_RES2 && resourceA.lockedBy == TASK1 &&
- task2State == WAIT_RES2 && resourceB.lockedBy == TASK2) {
- return true;
- }
- return false;
- }
- // Deadlock recovery: force Task 2 to release resources and reset
- void recoverDeadlock() {
- Serial.println("Deadlock detected! Recovering by resetting Task 2...");
- releaseResource(resourceB, TASK2);
- releaseResource(resourceA, TASK2);
- task2State = IDLE;
- }
- void setup(void)
- {
- // put your setup code here, to run once:
- pinMode(push_button_PushButton_PIN_D2, INPUT_PULLUP);
- pinMode(push_button_PushButton_PIN_D3, INPUT_PULLUP);
- // Setup RGB LED pins as outputs
- int rgbPins[] = {resA_R, resA_G, resA_B, resB_R, resB_G, resB_B};
- for (int i = 0; i < 6; i++) {
- pinMode(rgbPins[i], OUTPUT);
- }
- // Initialize LEDs to green (free)
- updateResourceLED(resourceA, resA_R, resA_G, resA_B);
- updateResourceLED(resourceB, resB_R, resB_G, resB_B);
- }
- void loop(void)
- {
- // put your main code here, to run repeatedly:
- unsigned long currentMillis = millis();
- // Read buttons (active HIGH assumed)
- button1Pressed = digitalRead(push_button_PushButton_PIN_D2) == HIGH; // Use defined pin
- button2Pressed = digitalRead(push_button_PushButton_PIN_D3) == HIGH; // Use defined pin
- // Run tasks every taskInterval ms (cooperative multitasking)
- if (currentMillis - lastMillis >= taskInterval) {
- lastMillis = currentMillis;
- // --- Task 1 ---
- switch (task1State) {
- case IDLE:
- if (button1Pressed) {
- Serial.println("Task 1 started");
- task1State = LOCK_RES1;
- }
- break;
- case LOCK_RES1:
- if (tryLockResource(resourceA, TASK1)) {
- Serial.println("Task 1 locked Resource A");
- updateResourceLED(resourceA, resA_R, resA_G, resA_B);
- task1State = WAIT_RES2;
- } else {
- Serial.println("Task 1 waiting for Resource A");
- setResourceWaiting(resA_R, resA_G, resA_B);
- }
- break;
- case WAIT_RES2:
- if (tryLockResource(resourceB, TASK1)) {
- Serial.println("Task 1 locked Resource B");
- updateResourceLED(resourceB, resB_R, resB_G, resB_B);
- task1State = WORKING;
- task1Timer = currentMillis;
- } else {
- Serial.println("Task 1 waiting for Resource B");
- setResourceWaiting(resB_R, resB_G, resB_B);
- }
- break;
- case WORKING:
- if (currentMillis - task1Timer >= workDuration) {
- Serial.println("Task 1 finished work, releasing resources");
- task1State = RELEASE_RES2;
- }
- break;
- case RELEASE_RES2:
- releaseResource(resourceB, TASK1);
- updateResourceLED(resourceB, resB_R, resB_G, resB_B);
- task1State = RELEASE_RES1;
- break;
- case RELEASE_RES1:
- releaseResource(resourceA, TASK1);
- updateResourceLED(resourceA, resA_R, resA_G, resA_B);
- task1State = IDLE;
- break;
- }
- // --- Task 2 ---
- switch (task2State) {
- case IDLE:
- if (button2Pressed) {
- Serial.println("Task 2 started");
- task2State = LOCK_RES1;
- }
- break;
- case LOCK_RES1:
- if (tryLockResource(resourceB, TASK2)) { // Note reversed order for deadlock
- Serial.println("Task 2 locked Resource B");
- updateResourceLED(resourceB, resB_R, resB_G, resB_B);
- task2State = WAIT_RES2;
- } else {
- Serial.println("Task 2 waiting for Resource B");
- setResourceWaiting(resB_R, resB_G, resB_B);
- }
- break;
- case WAIT_RES2:
- if (tryLockResource(resourceA, TASK2)) {
- Serial.println("Task 2 locked Resource A");
- updateResourceLED(resourceA, resA_R, resA_G, resA_B);
- task2State = WORKING;
- task2Timer = currentMillis;
- } else {
- Serial.println("Task 2 waiting for Resource A");
- setResourceWaiting(resA_R, resA_G, resA_B);
- }
- break;
- case WORKING:
- if (currentMillis - task2Timer >= workDuration) {
- Serial.println("Task 2 finished work, releasing resources");
- task2State = RELEASE_RES2;
- }
- break;
- case RELEASE_RES2:
- releaseResource(resourceA, TASK2);
- updateResourceLED(resourceA, resA_R, resA_G, resA_B);
- task2State = RELEASE_RES1;
- break;
- case RELEASE_RES1:
- releaseResource(resourceB, TASK2);
- updateResourceLED(resourceB, resB_R, resB_G, resB_B);
- task2State = IDLE;
- break;
- }
- // Deadlock detection every deadlockCheckInterval
- if (currentMillis - deadlockCheckTimer >= deadlockCheckInterval) {
- deadlockCheckTimer = currentMillis;
- if (detectDeadlock()) {
- recoverDeadlock();
- }
- }
- }
- }
- /* END CODE */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement