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.

HeapBuf and MessageQ's on Concerto

Other Parts Discussed in Thread: SYSBIOS

Hello e2e-Community,

I am currently using BIOS v.6-32-05-54, IPC v.1-24-02-27 and CCS v. 5.2.0.00070.

I am very happy that I got my Concerto running from Flash, and communicating with a MessageQ from C28 to M3 and the other way. I got the MessageQ-Example running from flash, and that's about the state of my code.

First problem:

Now I want to open another, bigger MessageQ in addition to the existing one, but when I try this the same way I do it with the first one, I always get: 

ti.sysbios.heaps.HeapBuf: line 225: requested size is too big: handle=0x20002a20, size=232 
MessageQ_alloc failed

I went down with the heapbuf sizes in my C code from 1024 -> 512 -> 256 bytes ...

So it seems to me, that my Heap is too small. Then I tried various things, I set BIOS.HeapSize to a bigger value (4096) => no effect. I tried some code snippet I found somewhere with HeapMem etc, but then my Concerto would not even startup anymore :(

How can I increase my heap? I have this #define HEAPID 0 from the example project - Do I have to create another Heap to do what I want?

Second Problem:

Is it possible do use a MessageQ only in ONE WAY? I tried it, but the Concerto always resettet itself (Probably because of the fact that the C28 had some kind of reset/abort).

I do it like this (pseudo code style)

M3-side: 

buf = Memory_alloc(0, numBlocks * blockSize, 0, NULL);

heapHandle = HeapBuf_create(&hbparams, NULL); // with blocksize = 256

MessageQ_registerHeap((IHeap_Handle)(heapHandle), HEAPID);

messageQ = MessageQ_create(M3_C28toM3, NULL); // create the local queue here, do not open a remote queue

while(1)

{ status = MessageQ_get(messageQ, (MessageQ_Msg *)&msg, MessageQ_FOREVER); }

C28-side

buf = Memory_alloc(0, numBlocks * blockSize, 0, NULL);

heapHandle = HeapBuf_create(&hbparams, NULL); // with blocksize = 256

MessageQ_registerHeap((IHeap_Handle)(heapHandle), HEAPID);

status = MessageQ_open(M3_C28Debug, &remoteQueueId); // only open remote queue, dont open a local one

while(1)

{ /*.. do something ..*/ status = MessageQ_put(remoteQueueId, (MessageQ_Msg)msg);  /*... do something else ... */}

As always, I am looking forward to your answers, and a big thanks in advance!!

- Philipp

  • Philipp,

    For #1, can you post the contents of your configuration (.cfg) file?

    For #2, I’ll look for an example…

    Scott

  • Scott,

    I think I figured out #1 by myself: I allocated the same heap twice, and with different parameters/sizes etc .. so this clearly can't work. 

    Now I am first initializing my (one) heap, and then I create my (two) MsgQ's on it - works very well.

    For #2, I would really appreciate an example, or some tips/hints!

    And last but not least, a quick question: I am looking for a decent/easy way to get a debug console running on both cores. At the moment, I got it working on the m3 that System_printf() is printed out via UART on the console. For c28, my plan is to send the debug information via MsgQ to the m3, and print it there with the exisiting solution.. I'm just wondering whether this is a good way to do it, or if there is anything easier/better .. Important to me is, that it runs from flash and prints out to the UART, without the need of a debugger or anything.

    Quick thought: Could I place SysMin's buffer in the shared memory, so that both cores can write, and every second or so, I flush it from the m3 with my existing UART-function?

    As always, thanks for your support,

    Philipp

  • Philipp,

    In your MessageQ_create() and MessageQ_open() calls, are the strings values for “M3_C28toM3” and “M3_C28Debug” the same?

    Also, you should add some checks of the MessageQ API return values.  For example, don’t call MessageQ_get() if the MessageQ_create() failed and returned a NULL handle.  And don’t call MessageQ_put() unless the MessageQ_open() returned success.  These checks should catch routine errors before they turn into aborts.

    Scott

  • Philipp,

    I checked internally and we don’t have any UART output mechanism to send you.  We may in another month or so, but nothing at the moment. 

    I don’t think having a single SysMin output buffer will work, as there is no buffer management/synchronization between the two processors.

    You can send the data from the C28 and have it output by the M3.  Or you could maybe output the data to a separate UART from the C28 side.  Either seems doable, but which is better will depend on your application.  From previous posts it sounded like C28 performance was key, so maybe letting the M3 handle the UART would be best?

    Scott

  • Scott,

    Okay, from what you said, I also think sending Debug information to the m3 and flush it from there sounds best.

    But, I am still working at this MsgQ-thing, and I'm at the brink of despair .. :S

    I simplified my project, made an example from it, and attached it here. Would you mind having a look at it?

    Quick explanantion: 

    On the m3 side, I initialize my DebugUART. Then, I create a MsgQ like in the GenericExample, but I only create the local queue, I dont open a remote one. Then, I just wait for messages.

    On the c28 side, I open the m3 queue, and write to it. Everything goes fine (I checked with the debugger) until the MessageQ_put() call - there, something goes wrong in the Transport module (dont know really what, my CCS seems not to find the correct source files, so I dont really see what it does..)

    In the end, I want to send a custom message (is already included in my example, just commented out - you'll see), but it does not even work with the standard MessageQ_Msg data type.

    The processor just keeps resetting itsself - I dont get any error messages, I cant figure out anything with the debugger ...

    Hoping for help,

    Philipp

    8551.myTestMsgQ.zip

  • Philipp,

    I’ve been swamped and haven’t been able to look at this for you.  I will as soon as I can…

    Scott

  • Scott,

    I'm still stuck at this one .. If your schedule is not all that full this week, would you mind having a look at my example?

    Thank you very much in advance!

    Philipp

    PS.: I had one thought concerning this problem: Is it perhaps not even possible, to do MessageQ's only in one way? Perhaps, because of some system mechanism, there always has to be another queue to reply to? That it is impossible to have seperated "listener" and "writer" threads?

  • Philipp,

    Yes, I looked at it a bit today.  I rebuilt both apps and am also seeing a crash on the C28 side (the CPU ends up in the boot ROM).  I'll get back to debugging it tomorrow morning…

    Scott

  • I'm really curious about your results ..  :)

    It's a tricky problem, isn't it..?

  • Hi Philipp,

    Yes, it is.  I’ve asked for help from the IPC team on this one.

    To clarify... it looks from your projects that you’ve updated to SYS/BIOS 6.33.05.46 and XDCtools 3.23.05.53.  Are these the versions you are running now?

    Also, one answer to the question in your .c file:

        // Question: Do I have to allocate the memory here in the receiving thread?
        msg = MessageQ_alloc(HEAPID, sizeof(MessageQ_MsgHeader));
        if (msg == NULL) System_abort("MessageQ_alloc failed\n" );

    The answer is “no”, you do not need to do the allocation because Messageq_get() returns a pointer to a message, and you don’t need to allocate a header for it.

    We’ll keep you posted as we figure this out…

    Scott

  • Hi Philipp,

    I modified your example and got it to work.

    1. M3.cfg: I used the MtoC memory

    //IpcMgr.readAddr  = 0x20016000;
    //IpcMgr.writeAddr = 0x20014000;
    //IpcMgr.messageQSize = 512;
    IpcMgr.readAddr  = 0x2007F000;
    IpcMgr.writeAddr = 0x2007F800;

    2. c28.cfg: I used the CtoM memory

    //IpcMgr.readAddr  = ...
    //IpcMgr.writeAddr = ...
    //IpcMgr.messageQSize = 512;
    IpcMgr.readAddr  = 0x3FC00;
    IpcMgr.writeAddr = 0x3F800;

    3. I changed the System provider to SysStd to rule out your UART send function. (I tried keeping SysMin and just removing the SysMin.outputFxn = "&UARTSend"; and it worked also).

    Can you try these to see if it helps (along with the removal of allocating a message on the M3 side)?

    Todd

  • Hi Scott and Todd,

    First of all: Yes, I am using SYS/BIOS 6.33.05.46, XDCtools 3.23.03.53 and IPC 1.24.02.27. That should be the newest versions, right?

    But it still isn't working on my device .. Todd, did you make _any_ other changes than the 3 steps you described to get it to work? Because I changed (even copied!!) the read/write addresses for both cores and commented out the MessageQsize-statement, removed the UARTsend-function on m3-side and commented out the following two lines on m3-side:

    msg = MessageQ_alloc(HEAPID, sizeof(MessageQ_MsgHeader));
    if (msg == NULL) System_abort("MessageQ_alloc failed\n");
    // or do I have to comment out more lines to remove the message allocation on m3 side?

    That's what I did - nothing more, nothing less, but ... still the same problem as before.

    When I just flash the code onto the device, it keeps resetting itsself. When I single-step in the C-code, it also runs into reset. Only one time, I single-stepped in ASM-mode, and then it worked one time - strange, isn't it? Did you get it to work in "free-run" mode, or also just in singlestep mode? I even tried another Concerto-ControlCard to rule out hardware issues..

    And then I still have one general question: why should it not work in the normal shared RAM, why do I have to use the (smaller) MessageRAM?

    Thanks to you both for your great support,

    Philipp

  • Hi Philipp,

    Sorry, I did do one more thing that I did not mention. I removed the bootC28 = true line from the m3.cfg. This allowed me to load and run the m3 from CCS. Then load and run the C28 from CCS.

    Since the System_flush was still being called in the Task you created, I was able to see the System_printf output in the console. I would see the console output every 2 seconds and it appeared that it would ran forever (I only ran it for a minute or so).

    I also did remove the MessageQ_alloc from the M3 code (in case that was not clear in my response).

    Todd

  • Hi Todd,

    I can't test it right now with the bootC28 = true line, but it is very important to me that the device runs perfectly from flash and without CCS - is this still the case after removing this boot-flag?

    If yes, and if it also works on my desk ;) - then my problem might be solved in the end .. :) I'll keep you informed when I have the chance to test it - tomorrow or the day after..

    Philipp

  • Okay guys,

    after some try and error (including locking myself out of the concerto's security module..), I finally tracked the problem down - I guess.

    I don't know anymore what it all was that I changed; in the end, I think, nearly nothing, but it seems that it depends on the target configuration if it works or not.

    I attached my current project again, and in there you find the two target configs (in the m3 project) that I use to flash and debug: "DebugFlash" and "F28M35H52C1".

    In "DebugFlash", I deleted the c28 gel-File, so when I start debugging in CCS, the system acts just like when it boots from flash without CCS. (like described in here: http://processors.wiki.ti.com/index.php/Concerto_Dual_Core_Boot ) With this startup mode (== flash startup), it does not work and resets itsself all the time.

    The other config File, "F28M35H52C1", is the standard target config, where also the c28 gel file is being executed. When I start up from this target configuration, it actually WORKS!

    But ... how do I get it to work from my "DebugFlash" config file - which would be the same as running from flash? What "extra stuff" does the c28 startup gel-File, and how can I do this when directly running from flash?

    Philipp

    /edit: about this bootC28 = true line: I tried it, but then the device would (of course) not start up from flash any more.. by the way: I always try to run my applications from flash, so my boot-switches on the concerto controlCard are always put on "boot from flash" (all switches down)

    8306.myTestMsgQ2.zip

  • Philipp,

    I can think of one thing that might be happening… in a CCS debug environment (using that GEL file) some of the C28-side memory banks get “initialized” at startup, meaning their ECC or parity bits get established.  (The regions that aren’t automatically initialized by the C28 boot ROM, that need to be initialized via a GEL or by the application are: M1, CtoM, L0, L1, L2, and L3.)  If one of these regions is not initialized first, and a particular memory location is read before being written, then a reset can occur.  I ran into this a month or so ago when booting from Flash, and copying code from Flash to RAM and executing it.  The copied code was fine, but the C28 CPU was doing some prefetching that caused a read of one of the memory locations beyond the code that had been copied, causing a reset back to the boot ROM.  In previous testing I'd not seen this because any memory location that was read had been explicitly written first.

    We’ve recently enhanced the ti.catalog.arm.cortexm3.concertoInit.Boot module to initialize these C28 RAM regions prior to booting the C28 application.  We also added support for initializing M3 and C28 Flash controllers, and setting appropriate wait states.  This is in an XDCtools release (3.23.04) that is in the final stages of release.  It will be posted to this site within the next few days: http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/rtsc/index.html

    If you upgrade to this new release I’m thinking that it may resolve the issue and your app will be able to boot from Flash…

    Hope this helps.

    Scott

  • Scott,

    That sounds like a logical explanation to my problem. I already tried a veeeery simple approach and put some thousand wait-"nop"s in a startup-function, but it did not really help. I guess that a more intelligent solution is needed - hopefully the new XDCtools release does the trick.

    Could you tell me the release date? Or at least if it'll come this week, or next, or even later? I'm kind of waiting for it, because I can't really continue my project without some working inter-processor-communication ;)

    When it's there, I'll post again if it helped, and if yes, I will of course mark your suggested answer as "verified" / "solved the problem" :)

    Philipp

  • Philipp,

    The new XDCtools isn’t released yet.  I think it should be within the next day, but I can't say for sure.  I know it is very close.  I’ll post a message pointing you to it when it is available…

    Scott

  • Scott,

    Just tried the new XDCtools release. It's working perfectly! You guys did a great job on this startup-initialization-module!

    Thanks for your great support again!

    Philipp

  • Philipp,

    OK, great, I’m very glad to hear it resolved the issues!  

    For others who may find this thread on the forum… the new XDCtools release with Flash controller initialization for Concerto devices is posted here: http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/rtsc/3_23_04_60/index_FDS.html

    Scott