PXROS-HR Multi-Core

The same programming model as described in the chapters above can be used for PXROS-HR Multi-Core systems. The tasks can be spread across several cores and can communicate with messages and events between the cores.
If events are used between tasks on different cores, an internal communication object will be allocated and sent to the corresponding core. Therefore events across cores can not be signaled by handlers and the signaling of events by tasks can fail due to object shortage.

On each core one instance of the PXROS-HR micro-kernel is running performing local administration (scheduling, object and memory management, system services, etc.) and are responsible for the inter-core communication.

Typically local memory is used for PXROS-HR and the tasks running on that core.

Tasks and other PXROS-HR objects have internal identifiers that are unique on all cores. As a result, it is not required to have any knowledge about the core assignment of the receiver task of a communication object (message or event).

Initialisation

As there is a micro-kernel running on each core, the PXROS-HR initialisation structure has to be defined per core, as well.

const PxInitSpec_T InitSpec_CORE0 =
    {
        .is_sysmc_type      = PXMcVarsizedAligned,
        .is_sysmc_size      = 8,
        .is_sysmc_blk       = Sysmem0,
        .is_sysmc_blksize   = SYSMEMSIZE_CORE0,

        .is_objmc_type      = PXMcVarsizedAligned,
        .is_objlmc_size     = 8,
        .is_objmc_blk       = PxObjmem_CPU0_,
        .is_objmc_blksize   = (PxSize_t)PX_OBJMEMSIZE_CPU0_,

        .is_obj_number      = NUM_OF_PXOBJS_CORE0,
        .is_obj_namelength  = PXROS_NAMESIZE,

        .is_taskmc_type     = PXMcVarsizedAdjusted,
        .is_taskmc_size     = 8,
        .is_taskmc_blk      = Taskmem_Core0,
        .is_taskmc_blksize  = TASKMEMSIZE_CORE0,

        .is_inittask        = &InitTaskSpec_CORE0,

        .is_core_start      = (unsigned int)_start,

         /* the system stack */
        .is_system_stack = PXROS_SYSTEM_STACK_BEGIN_CPU0_,
        .is_system_stack_size = (PxUInt_t)PXROS_SYSTEM_STACK_SIZE_CPU0_,

        /* all objects are global accessible */
        .is_global_obj_number = 0,

        /* the protection definition */
        .is_sys_code = &_cpu0_sys_code_protection,
        .is_sys_data = &_cpu0_sys_data_protection,
        .is_task_code = &_cpu0_task_code_protection,
    };
const PxInitSpec_T InitSpec_CORE1 =
    {
        .is_sysmc_type      = PXMcVarsizedAligned,
        .is_sysmc_size      = 8,
        .is_sysmc_blk       = Sysmem1,
        .is_sysmc_blksize   = SYSMEMSIZE_CORE1,

        .is_objmc_type      = PXMcVarsizedAligned,
        .is_objlmc_size     = 8,
        .is_objmc_blk       = PxObjmem_CPU1_,
        .is_objmc_blksize   = (PxSize_t)PX_OBJMEMSIZE_CPU1_,

        .is_obj_number      = NUM_OF_PXOBJS_CORE1,
        .is_obj_namelength  = PXROS_NAMESIZE,

        .is_taskmc_type     = PXMcVarsizedAdjusted,
        .is_taskmc_size     = 8,
        .is_taskmc_blk      = Taskmem_Core1,
        .is_taskmc_blksize  = TASKMEMSIZE_CORE1,

        .is_inittask        = &InitTaskSpec_CORE1,

        .is_core_start      = (unsigned int)_start,

         /* the system stack */
        .is_system_stack = PXROS_SYSTEM_STACK_BEGIN_CPU1_,
        .is_system_stack_size = (PxUInt_t)PXROS_SYSTEM_STACK_SIZE_CPU1_,

        /* all objects are global accessible */
        .is_global_obj_number = 0,

        /* the protection definition */
        .is_sys_code = &_cpu1_sys_code_protection,
        .is_sys_data = &_cpu1_sys_data_protection,
        .is_task_code = &_cpu1_task_code_protection,
    };
const PxInitSpec_T InitSpec_CORE2 =
    {
        ...
    };
const PxInitSpec_T InitSpec_CORE3 =
    {
        ...
    };
const PxInitSpec_T InitSpec_CORE4 =
    {
        ...
    };
const PxInitSpec_T InitSpec_CORE5 =
    {
        ...
    };


static const PxInitSpecsArray_t InitSpecsArray[] =
{
    &InitSpec_CORE0,
    &InitSpec_CORE1,
    &InitSpec_CORE2,
    &InitSpec_CORE3,
    &InitSpec_CORE4,
    &InitSpec_CORE5
};

The array containing all core specific initialisation structures is passed to PxInit() to initialize and start the PXROS-HR system.

The Inittask may call the function PxGetCoreId() to determine on which core it is running and can perform core specific functions or create core specific task:

PxUInt_t id = PxGetCoreId ();

/* insert your own Application,  e.g. initialise other tasks etc */
switch (id)
{
  case CORE_0:
      /*
       * Do core 0 specific stuff and
       * create core 0 tasks here
       */
       break;
  case CORE_1:
      /*
       * Do core 1 specific stuff and
       * create core 1 tasks here
       */
       break;
  case CORE_2:
      /*
       * Do core 2 specific stuff and
       * create core 2 tasks here
       */
       break;
}