Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. ATL / WTL / STL
  4. Advice on interdependent asynchronous functions and task queuing?

Advice on interdependent asynchronous functions and task queuing?

Scheduled Pinned Locked Moved ATL / WTL / STL
hardwarequestion
2 Posts 1 Posters 11 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    arnold_w
    wrote on last edited by
    #1

    I am working with embedded programming in standard C and there are 2 microcontrollers communicating with each other using a home-made SPI-protocol. In addition, microcontroller 2 has a CAN-bus that should also (indirectly) be fully accessible from microcontroller 1. The scheduler and task queues are also home-made so no realtime operating system is used. My tasks look like this:

    void (*task_t)(uint8_t* taskData, uint16_t sizeOfTaskDataInBytes);

    My functions to add 1 or 2 tasks look like this:

    typedef enum {
    TASK_IN_WAIT_PHASE = 0,
    TASK_FINISHED = 1
    } taskStatus_e;

    typedef taskStatus_e (*getTaskStatusCallback_t)(uint8_t* data, uint16_t dataSizeBytes);

    Bool_t queueTask(taskQueueSelector_e, task_t, uint8_t* data, uint16_t dataSizeBytes, getTaskStatusCallback_t);
    Bool_t queue2Tasks(taskQueueSelector_e, task_t task1, uint8_t* data1, uint16_t data1SizeBytes, getTaskStatusCallback_t getTaskStatusCallback1, task_t task2, uint8_t* data2, uint16_t data2SizeBytes, getTaskStatusCallback_t getTaskStatusCallback2);

    When microcontroller 1 wants to read from microcontroller 2 over SPI, the following code is used:

    struct SPI_secretData_s {
    volatile Bool_t accessInProgress;
    volatile int8_t numRetriesLeft;
    };

    #define PLEASE_SEE_NUM_REGS_TO_ACCESS_PARAMETER (1)

    struct SPI_readRegsTaskParams_s {
    struct SPI_secretData_s secretData;
    volatile uint32_t startAddr;
    volatile uint16_t numRegsToAccess;
    volatile SPI_readStatus_e readStatus;
    volatile uint16_t readBuffer[PLEASE_SEE_NUM_REGS_TO_ACCESS_PARAMETER];
    };

    queue2Tasks(SPI_QUEUE_SELECTOR, SPI_readRegs, (uint8_t*)&SPI_readRegsTaskParams, sizeof(SPI_readRegsTaskParams), SPI_getTaskStatusCallback, SPI_handleReadIsFinished, NULL, 0, NULL);

    taskStatus_e SPI_getTaskStatusCallback(uint8_t* data, uint16_t dataSizeBytes) {
    struct SPI_readRegsTaskParams_s* SPI_readRegsTaskParams = (struct SPI_readRegsTaskParams_s*)data;
    return (SPI_readRegsTaskParams->secretData.accessInProgress) ? TASK_IN_WAIT_PHASE : TASK_FINISHED;
    }

    uint32_t SPI_handleReadIsFinished(uint8_t* notUsed, uint16_t sizeOfNotUsedInBytes) {
    struct SPI_readRegsTaskParams_s* SPI_readRegsTaskParams = (struct SPI_readRegsTaskParams_s*)getPreviousTaskData();
    //... Do what you need to do with the read data...
    }

    When microcontroller 2 wants to read from the CAN-bu

    A 1 Reply Last reply
    0
    • A arnold_w

      I am working with embedded programming in standard C and there are 2 microcontrollers communicating with each other using a home-made SPI-protocol. In addition, microcontroller 2 has a CAN-bus that should also (indirectly) be fully accessible from microcontroller 1. The scheduler and task queues are also home-made so no realtime operating system is used. My tasks look like this:

      void (*task_t)(uint8_t* taskData, uint16_t sizeOfTaskDataInBytes);

      My functions to add 1 or 2 tasks look like this:

      typedef enum {
      TASK_IN_WAIT_PHASE = 0,
      TASK_FINISHED = 1
      } taskStatus_e;

      typedef taskStatus_e (*getTaskStatusCallback_t)(uint8_t* data, uint16_t dataSizeBytes);

      Bool_t queueTask(taskQueueSelector_e, task_t, uint8_t* data, uint16_t dataSizeBytes, getTaskStatusCallback_t);
      Bool_t queue2Tasks(taskQueueSelector_e, task_t task1, uint8_t* data1, uint16_t data1SizeBytes, getTaskStatusCallback_t getTaskStatusCallback1, task_t task2, uint8_t* data2, uint16_t data2SizeBytes, getTaskStatusCallback_t getTaskStatusCallback2);

      When microcontroller 1 wants to read from microcontroller 2 over SPI, the following code is used:

      struct SPI_secretData_s {
      volatile Bool_t accessInProgress;
      volatile int8_t numRetriesLeft;
      };

      #define PLEASE_SEE_NUM_REGS_TO_ACCESS_PARAMETER (1)

      struct SPI_readRegsTaskParams_s {
      struct SPI_secretData_s secretData;
      volatile uint32_t startAddr;
      volatile uint16_t numRegsToAccess;
      volatile SPI_readStatus_e readStatus;
      volatile uint16_t readBuffer[PLEASE_SEE_NUM_REGS_TO_ACCESS_PARAMETER];
      };

      queue2Tasks(SPI_QUEUE_SELECTOR, SPI_readRegs, (uint8_t*)&SPI_readRegsTaskParams, sizeof(SPI_readRegsTaskParams), SPI_getTaskStatusCallback, SPI_handleReadIsFinished, NULL, 0, NULL);

      taskStatus_e SPI_getTaskStatusCallback(uint8_t* data, uint16_t dataSizeBytes) {
      struct SPI_readRegsTaskParams_s* SPI_readRegsTaskParams = (struct SPI_readRegsTaskParams_s*)data;
      return (SPI_readRegsTaskParams->secretData.accessInProgress) ? TASK_IN_WAIT_PHASE : TASK_FINISHED;
      }

      uint32_t SPI_handleReadIsFinished(uint8_t* notUsed, uint16_t sizeOfNotUsedInBytes) {
      struct SPI_readRegsTaskParams_s* SPI_readRegsTaskParams = (struct SPI_readRegsTaskParams_s*)getPreviousTaskData();
      //... Do what you need to do with the read data...
      }

      When microcontroller 2 wants to read from the CAN-bu

      A Offline
      A Offline
      arnold_w
      wrote on last edited by
      #2

      Just like I have a secretData_s struct as part of the task data, maybe I should also have a postTaskInfo_s section:

      #define PLEASE_SEE_SIZE_OF_POST_TASK_DATA_PARAMETER (1)

      struct postTaskInfo_s {
      task_t postTask;
      taskQueueSelector_e postTaskQueueSelector;
      uint16_t sizeOfPostTaskData;
      uint8_t postTaskData[PLEASE_SEE_SIZE_OF_POST_TASK_DATA_PARAMETER]
      };

      Then if postTaskInfo->postTask is not null then the CAN_readRegs-task will queue the postTask just before it's finished. Can someone think of something better?

      1 Reply Last reply
      0
      Reply
      • Reply as topic
      Log in to reply
      • Oldest to Newest
      • Newest to Oldest
      • Most Votes


      • Login

      • Don't have an account? Register

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • World
      • Users
      • Groups