This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C2000 Concerto M3 RTOS communication via ipc with C28 Non-RTOS

Other Parts Discussed in Thread: SYSBIOS
Hi Guys,
I have established in recent days and weeks communication via IPC between the M3 side and the side of a C28 F28M35x Concerto controller.
 Since I Need various peripheral that  not yet implemented RTOS for C28 Subsystem , I'll have to drive C28-Core without RTOS.
How can I establish a communication between the two cores without having the same library´s ?
Communication with MessageQ or Notify (RTOS on M3) and IPC-Lite / Main IPC Drivers (C28 without rtos)  - how does it work ??
thank´s for any hlep
Holger
  • We don't have an out-of-the box solution for this use case. Is there a reason you cannot use the RTOS on the C28 side? You should be able to add peripheral support on the C28 that works with the RTOS.
  • Hallo Karl,

    Thanks Four your reply.

    i Need Gpio, Aic, ePwm and Spi . In my Opinion it is faster too get iPc Running without rtos instead of get 4  open Cases with periphial Problems :)

    Which  way seems too bee the netter was in your opinion and can you give me please some sample-Code

    Thank you

    Holger

  • Hi guys,
    I've tried many things over the holidays, but have brought nothing really to run.
    I tried out examples of lines of code to build a C28 RTOS project
    I have tried to install Vissim lines of code
    but without success

    Is anyone here in the forum can help me to get a little further or
    has someone done communication via IPC between C28 NonRTOS code  and  a M3 RTOS program  ?
    for your help, I thank you in advance
    holger
  • Holger,

    As Karl mentioned, we do not have have an use case of using IPC with non-RTOS core. Our suggestion would be to go with RTOS solution on C28 which has IPC examples to communicate with M3 core. You may need to port some drivers to add peripheral support that you need on C28. Some of the peripheral drivers for GPIO, SPI are available for M3 core. You can use them as reference for your drivers.

    Have a look at the "demo" concerto example in TI-RTOS for C2000.

    Vikram
  • In my Ressource Explorer i habe more than one " Demo" but all of them habe this in the readme.txt

    "Example Summary
    ----------------
    Refer to the Demo [M3] demo_readme.txt file for a description.

    Peripherals Exercised
    ---------------------
    N/A. TI-RTOS does not support peripherals on the C28"


    this is the demo i use and expand for my experiments

    /*
    * Copyright (c) 2012, Texas Instruments Incorporated
    * All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions
    * are met:
    *
    * * Redistributions of source code must retain the above copyright
    * notice, this list of conditions and the following disclaimer.
    *
    * * Redistributions in binary form must reproduce the above copyright
    * notice, this list of conditions and the following disclaimer in the
    * documentation and/or other materials provided with the distribution.
    *
    * * Neither the name of Texas Instruments Incorporated nor the names of
    * its contributors may be used to endorse or promote products derived
    * from this software without specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
    * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
    * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    */

    /*
    * ======== demo_c28.c ========
    */

    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/IHeap.h>
    #include <xdc/runtime/Memory.h>
    #include <xdc/runtime/System.h>

    /* IPC Header files */
    #include <ti/ipc/MessageQ.h>
    #include <ti/ipc/MultiProc.h>

    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/heaps/HeapBuf.h>
    #include <ti/sysbios/knl/Task.h>

    #include <string.h>

    #include "demo.h"
    #include "DSP28x_Project.h"



    // Prototype statements for functions found within this file.
    void InitEPwm1Example(void);
    void InitEPwm2Example(void);
    void InitEPwm3Example(void);
    // Global variables used in this example
    Uint32 EPwm1TimerIntCount;
    Uint32 EPwm2TimerIntCount;
    Uint32 EPwm3TimerIntCount;
    Uint16 EPwm1_DB_Direction;
    Uint16 EPwm2_DB_Direction;
    Uint16 EPwm3_DB_Direction;

    // Maximum Dead Band values
    #define EPWM1_MAX_DB 0x03FF
    #define EPWM2_MAX_DB 0x03FF
    #define EPWM3_MAX_DB 0x03FF

    #define EPWM1_MIN_DB 0
    #define EPWM2_MIN_DB 0
    #define EPWM3_MIN_DB 0

    // To keep track of which way the Dead Band is moving
    #define DB_UP 1
    #define DB_DOWN 0


    int Timer_counter = 0;

    /*
    * ======== tsk0_func ========
    * Allocates a message and ping-pongs the message around the processors.
    * A local message queue is created and a remote message queue is opened.
    * Messages are sent to the remote message queue and retrieved from the
    * local MessageQ.
    */
    Void tsk0_func(UArg arg0, UArg arg1)
    {
    MessageQ_Msg msg;
    MessageQ_Handle messageQ;
    MessageQ_QueueId remoteQueueId;
    Int status;
    UInt16 msgId = 0;
    Ptr buf;
    HeapBuf_Handle heapHandle;
    HeapBuf_Params hbparams;
    SizeT blockSize;
    UInt numBlocks;
    Error_Block eb;

    /* Compute the blockSize & numBlocks for the HeapBuf */
    numBlocks = 2;
    //blockSize = sizeof(TempMsg);
    blockSize = 64;

    /* Alloc a buffer from the default heap */
    buf = Memory_alloc(0, numBlocks * blockSize, 0, NULL);

    /*
    * Create the heap that is used for allocating MessageQ messages.
    */
    Error_init(&eb);
    HeapBuf_Params_init(&hbparams);
    hbparams.align = 0;
    hbparams.numBlocks = numBlocks;
    hbparams.blockSize = blockSize;
    hbparams.bufSize = numBlocks * blockSize;
    hbparams.buf = buf;
    heapHandle = HeapBuf_create(&hbparams, &eb);
    if (heapHandle == NULL) {
    System_abort("HeapBuf_create failed\n" );
    }

    /* Register default system heap with MessageQ */
    MessageQ_registerHeap((IHeap_Handle)(heapHandle), HEAPID);

    /* Create the local message queue */
    messageQ = MessageQ_create(C28QUEUENAME, NULL);
    if (messageQ == NULL) {
    System_abort("MessageQ_create failed\n" );
    }

    /* Open the remote message queue. Spin until it is ready. */
    do {
    status = MessageQ_open(M3QUEUENAME, &remoteQueueId);
    /*
    * Sleep for 1 clock tick to avoid inundating remote processor
    * with interrupts if open failed
    */
    if (status < 0) {
    Task_sleep(1);
    }
    } while (status < 0);

    /*
    * Wait for a message from the M3 processor and
    * send it back after converting to Fahrenheit.
    */
    while (TRUE) {
    /* Get a message */
    status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER);
    if (status < 0) {
    System_abort("This should not happen since timeout is forever\n");
    }
    /* Get the message id */
    msgId = MessageQ_getMsgId(msg);

    if (msgId == TEMPERATURE_CONVERSION) {
    ((TempMsg *)msg)->temperatureF = ((TempMsg *)msg)->temperatureC * 1.8 + 32;
    }

    if (msgId == FLOAT_VALUE){

    int i =0;
    for(i=0; i < LENGTH_FLOAT_ARRAY; i++)
    {
    ((TempMsg *)msg)->FloatValues[i] = ((TempMsg *)msg)->FloatValues[i] + (10.2 * i);
    }

    /*((TempMsg *)msg)->float_0 = ((TempMsg *)msg)->float_0 +0.10;
    ((TempMsg *)msg)->float_1 = ((TempMsg *)msg)->float_1 +10.20;
    ((TempMsg *)msg)->float_2 = ((TempMsg *)msg)->float_2 +20.30;
    ((TempMsg *)msg)->float_3 = ((TempMsg *)msg)->float_3 +30.40;
    ((TempMsg *)msg)->float_4 = ((TempMsg *)msg)->float_4 +40.50;*/
    }

    if (msgId == SHORT_VALUE){
    int i =0;
    for(i=0; i <LENGTH_INT_ARRAY;i++)
    {
    MessageQ_setMsgId(msg, SHORT_VALUE);
    ((TempMsg *)msg)->Integer_Values[i] = ((TempMsg *)msg)->Integer_Values[i] + (10 * i);
    }
    /*((TempMsg *)msg)->int_0 = ((TempMsg *)msg)->int_0 + 10;
    ((TempMsg *)msg)->int_1 = ((TempMsg *)msg)->int_1 + 20;
    ((TempMsg *)msg)->int_2 = ((TempMsg *)msg)->int_2 + 30;
    ((TempMsg *)msg)->int_3 = ((TempMsg *)msg)->int_3 + 40;
    ((TempMsg *)msg)->int_4 = ((TempMsg *)msg)->int_4 + 50;*/
    }


    ((TempMsg *)msg)->interruptValue = Timer_counter;

    /* send the message to the remote processor */
    status = MessageQ_put(remoteQueueId, msg);
    if (status < 0) {
    System_abort("MessageQ_put had a failure/error\n");
    }
    }

    }




    Void copy()
    {
    //Timer_counter++;
    }


    Void startAdcSeq()
    {
    Timer_counter++;
    }


    Void readAdc(){}




    void InitEPwm1Example()
    {


    EPwm1Regs.TBPRD = 6000; // Set timer period
    EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0
    EPwm1Regs.TBCTR = 0x0000; // Clear counter

    // Setup TBCLK
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV4; // Clock ratio to SYSCLKOUT
    EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV4;

    EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

    // Setup compare
    EPwm1Regs.CMPA.half.CMPA = 3000;

    // Set actions
    EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on Zero
    EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;

    EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR; // Set PWM1A on Zero
    EPwm1Regs.AQCTLB.bit.CAD = AQ_SET;

    // Active Low PWMs - Setup Deadband
    EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
    EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_LO;
    EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;
    EPwm1Regs.DBRED = EPWM1_MIN_DB;
    EPwm1Regs.DBFED = EPWM1_MIN_DB;
    EPwm1_DB_Direction = DB_UP;

    // Interrupt where we will change the Deadband
    //EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
    //EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT
    //EPwm1Regs.ETPS.bit.INTPRD = ET_3RD; // Generate INT on 3rd event


    }
    // _InitEP



    /*
    * ======== main ========
    */
    Int main(Int argc, Char* argv[])
    {

    // InitSysCtrl();
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    EDIS;

    InitEPwm1Gpio();

    //InitPieCtrl();
    //InitPieVectTable();
    InitEPwm1Example();





    BIOS_start();

    return (0);
    }




    Am I one of just a very few people who are trying to Concerto RTOS on the C28 side or am I just the only one beeing not able too port peripherie too RTOS ? let me not die stupid