• Join
  • Sign In with my.TI Login
Texas Instruments
  • Products
  • Applications
  • Tools & Software
  • Support & Community
  • Sample & Buy
  • About TI
Sample & Purchase Cart Sample & Purchase Cart
  • Search
  • Advanced
TI E2E™ Community
  • Support Forums
  • Blogs
  • Groups
  • Videos
  • 简体中文
  • More ...
TI Home » TI E2E Community » Support Forums » Embedded Software » BIOS » BIOS forum » SYS/BIOS IOM Adapter and Streams
Share
BIOS
  • Forum
  • Announcements
Options
  • Subscribe via RSS

SYS/BIOS IOM Adapter and Streams

SYS/BIOS IOM Adapter and Streams

This question is answered
Marshall Schiring
Posted by Marshall Schiring
on Jun 14 2012 13:25 PM
Intellectual420 points

Hello again,

I am using XDC v3.23.2.47 with SYS/BIOS 6.33.5.46. IPC is version 1.24.3.32 and I also have PSP 3.0.1.00. All using CCSv5.1.

I am trying to get the IPC IOMAdapter with streams to work with an old iom driver written for DSP/BIOS 5. I am currently having 2 problems.

First, I notice when my program comes out of c_int00() that SYS/BIOS is calling my IOM Adapter create() function before bind(). This is a problem because bind is suppose to setup my device (*devp) with the parameter devParams which is later used in create(). Is this intended behavior, or am I doing something wrong? I am currently able to work around this by finding out where my devParams are in memory and changing the *devp when create() is called. Here is the driver and streams setup:

var IomParams = new IomAdapter.Params();
IomParams.instance.name = "myIOM";
IomParams.iomFxns = "&IomFunctions";
IomParams.initFxn = "&IomInit";
IomParams.deviceId = 0;
IomParams.deviceParams = null;
Program.global.myIOM = IomAdapter.create(IomParams);
DriverTable.addMeta("/myIOM", Program.global.myIOM);

var stream0Params = new Stream.Params();
stream0Params.instance.name = "stream0";
Program.global.stream0 = Stream.create("/myIOM", Stream.OUTPUT, stream0Params);

var stream1Params = new Stream.Params();
stream1Params.instance.name = "stream1";
Program.global.stream1 = Stream.create("/myIOM", Stream.INPUT, stream1Params);

Simple producer/consumer tasks using the two streams as inputs:

var task0Params = new Task.Params();
task0Params.instance.name = "task0";
task0Params.arg0 = Program.global.stream1;
task0Params.priority = 2;
Program.global.task0 = Task.create("&task0Fxn", task0Params);

var task1Params = new Task.Params();
task1Params.instance.name = "task1";
task1Params.arg0 = Program.global.stream0;
task1Params.priority = 3;
Program.global.task1 = Task.create("&task1Fxn", task1Params);

The second issue I am seeing is that both my streams (one input and one output) are giving IOM_READ commands in their IOM_Packet. When I do a Stream_issue() on both streams I go to my IOM_Submit() function. One of the parameters is a pointer to IOM_Packet. I believe my OUTPUT stream is suppose to give a IOM_WRITE command instead of an IOM_READ command (this is how the driver was written for DSP/BIOS 5). If I manually change this value during debug to IOM_WRITE my program works as I expect. What am I doing wrong to have both streams appear as reading?

Here's my tasks:

Void task0Fxn (Stream_Handle inStream)
{
	unsigned char bufferIN[1];
	xdc_Ptr myBuf1;
	unsigned char i;
	unsigned long counter=0;
	while(1)
	{
		for (i = 0; i < 1; i++)
		{
			bufferIN[i] = counter++;
		}

		Stream_issue(inStream, bufferIN, sizeof(bufferIN), NULL, NULL);    /* IOM_READ */

		Stream_reclaim(inStream, &myBuf1, BIOS_WAIT_FOREVER, NULL, NULL);
	}
}


Void task1Fxn (Stream_Handle outStream)
{
	unsigned char bufferOUT[1];
	xdc_Ptr myBuf2;
	while(1)
	{
		Stream_issue(outStream, bufferOUT, sizeof(bufferOUT), NULL, NULL); /* IOM_READ */
		Stream_reclaim(outStream, &myBuf2, BIOS_WAIT_FOREVER, NULL, NULL);
	}
}

Thanks for any help!

Report Abuse
  • Reply
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
All Replies
  • Marshall Schiring
    Posted by Marshall Schiring
    on Jun 19 2012 09:21 AM
    Intellectual420 points

    Still have not found an explanation or documentation explaining these issues. Given how streams work in DSP/BIOS I do not believe this is desired behavior.

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Scott Gary
    Posted by Scott Gary
    on Jun 20 2012 18:36 PM
    Genius10040 points

    Marshall,

    Your config script and C code look fine.  It seems you are doing all the right things.  I am going to have to discuss this internally and get back to you…

    Scott

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Marshall Schiring
    Posted by Marshall Schiring
    on Jun 21 2012 15:49 PM
    Intellectual420 points

    Thanks for the update Scott. Please let me know if I can help by providing any more information or articulating anything I have made unclear.

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Scott Gary
    Posted by Scott Gary
    on Jun 22 2012 13:04 PM
    Genius10040 points

    Marshall,

    For the first issue about the startup sequence, I think this is because the streams are being statically created.  There is a note about how this changes the startup sequence in the IPC and I/O user’s guide (http://www.ti.com/lit/ug/sprugo6d/sprugo6d.pdf)

    For the second issue, can you check that the stream handles being passed into the task functions are correct?  I’m wondering if somehow the same handle is being used by both functions (so the IOM packets are always carrying READ).

    Can you pull up the ROV tool and look at what is shown for the Streams?  Does this look correct?

    Also, I’m wondering why you have both a buffer and a buffer pointer in each task, and are passing one to issue and the other to reclaim.  Normally you’d just have a single buffer in each, and pass it to both the issue and reclaim calls.  As is it shouldn’t be causing a problem, but the usage is not typical.

    Scott

     

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Marshall Schiring
    Posted by Marshall Schiring
    on Jun 22 2012 15:42 PM
    Intellectual420 points

    Scott,

    First issue: I missed that note in the IPC User's Guide. I agree with you that this is likely what has happened and that my driver code must be written in a way to account for this. It has made for some ugly code, but I think it is working for now. Looking forward, I don't know if this will be an issue because I think we will be forced to declare streams at runtime because tasks only take 2 parameters (we have been trying to avoid dynamic creation). Thanks for resolving this issue!

    Second issue: I've looked at the ROV for my streams and everything appears normal. The two streams do not share the same address and the modes display as expected. The streams are also passed into the functions correctly (verified by stepping through code). The code has changed a bit from my original post, but the userSuppliedSync and issue columns below agree with how I've configured them. Both streams are still submitting IOM_READ commands.

    As far as using 2 different buffers for reclaim/issue, I was at one point having an issue when they both were the same buffer. I would get an immediate system abort() on reclaim or issue (can't remember which). I changed them to try to target down specific problems, but I will go back and look more closely at this issue now. I seem to get the abort() problem quite frequently and each time it has ended up being a configuration setting is incorrect.

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Scott Gary
    Posted by Scott Gary
    on Jun 25 2012 11:33 AM
    Genius10040 points

    Marshall,

    Thanks for checking the stream handles and ROV contents.

    Is it possible to step the code into the Stream_issue() for the write, and see where the wrong IOM_READ is being picked up?  

    Also, as suggested on the other thread (http://e2e.ti.com/support/embedded/bios/f/355/t/192759.aspx), is it an option for you to use the simpler GIO interfaces instead?

    Scott

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Marshall Schiring
    Posted by Marshall Schiring
    on Jun 26 2012 09:58 AM
    Intellectual420 points

    Scott Gary

    Marshall,

    Thanks for checking the stream handles and ROV contents.

    Is it possible to step the code into the Stream_issue() for the write, and see where the wrong IOM_READ is being picked up?  

    Also, as suggested on the other thread (http://e2e.ti.com/support/embedded/bios/f/355/t/192759.aspx), is it an option for you to use the simpler GIO interfaces instead?

    Scott

    I feel kind of stupid, but I can't figure out how to enable debugging symbols for SYS/BIOS modules so I haven't been able to step through Stream to find the issue. I've made sure I'm using "Full symbolic debug" in project properties compiler basic options. I've also set the RTSC build-profile as debug and I have no optimization on. I've played with a bunch of settings. The most promising looks like under project properties->Debug there is a field "OS Aware Debug Options", but none of them seem to allow me to set a breakpoint in Stream.c. Is there something I'm missing?

    I'll look into using GIO instead of Stream. Upon quick initial inspection in the user guides the sections look almost copy and pasted. GIO is only dynamically created but other than that they look identical.

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Scott Gary
    Posted by Scott Gary
    on Jun 26 2012 19:14 PM
    Genius10040 points

    Marshall,

    You shouldn’t need to do anything additional to get debug symbols for Stream.  Tomorrow morning I will have access to a board that I can try this on myself, and I’ll reply back then…

    The main reason for the GIO suggestion regards its simpler implementation.

    Scott

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Marshall Schiring
    Posted by Marshall Schiring
    on Jun 27 2012 17:25 PM
    Intellectual420 points

    Scott,

    I read up on the GIO interface and tried to convert my code from Stream to GIO. This is in the code below. Honestly, after reading the documentation, I wouldn't be able to explain to someone the difference between GIO and Stream other than the fact that GIO seems more restrictive and it is a part of the SYS/BIOS package (thus not needing IPC). It's restrictive in that GIO must be defined dynamically (which I think, by definition, must mean tasks are also dynamically created) and also the blocking timeout must be determined upon GIO creation (rather than during buffer issue like with Stream). I don't think either of these restrictions are a big deal for us, but they are the only differences I can point out between GIO and Stream.

    Taking all tasks out and just using GIO issue/reclaim in main() showed promise as in my driver I was getting both IOM_READ and IOM_WRITE. However, when I add a task my Task_Handle is always NULL. I found it interesting that if I comment out all my GIO function calls in the task I am trying to create, the task create's fine and executes normally! I put the GIO issue/reclaim/prime function calls back in the task and the task fails to create again. For fun, I also tried putting GIO functions in my custom user idle function (outside the task) and the task creation still failed. Any idea why adding GIO functions to a task would cause the task to fail to create?

    So here's my code with Stream_issue's replaced with GIO_issue, etc. I do use a custom user idle function to simulate my writer class waking up at a later time to some sort of input.

    #include xdc/std.h>
    #include xdc/runtime/System.h>
    #include xdc/runtime/Error.h>
    #include ti/sysbios/BIOS.h>
    #include ti/sysbios/knl/Queue.h>
    #include ti/sysbios/knl/Task.h>
    #include ti/sysbios/io/IOM.h>
    #include ti/sysbios/knl/Event.h>
    #include ti/sysbios/knl/Clock.h>
    #include ti/sdo/io/Stream.h>
    #include ti/sysbios/io/GIO.h>
    #include xdc/cfg/global.h>
    unsigned char WaitForInput;
    static Void task0Fxn(GIO_Handle outStream);
    static Void task1Fxn(GIO_Handle inStream);
    GIO_Handle handleIN, handleOUT;
    Task_Handle task0, task1;
    /*
    * ======== main ========
    */
    Int main(Int argc, Char* argv[])
    {
    GIO_Params gioParams;
    Task_Params task0Params, task1Params;
    Error_Block eb;
    GIO_Params_init(&gioParams);
    // gioParams.__size = 1;
    gioParams.timeout = BIOS_WAIT_FOREVER;
    gioParams.numPackets = 2;
    gioParams.model = GIO_Model_ISSUERECLAIM;//GIO_Model_STANDARD;
     handleIN = GIO_create("/BSP_DivertToEI", GIO_INPUT, &gioParams, NULL);
    handleOUT = GIO_create("/BSP_DivertToEI", GIO_OUTPUT, &gioParams, NULL);

    Task_Params_init(&task0Params);
    task0Params.stackSize = 512;
    task0Params.arg0 = (xdc_UArg)handleOUT;//&handleOUT;
    task0Params.priority = 2;
    task0 = Task_create((Task_FuncPtr)task0Fxn, &task0Params, &eb);
    //
    // Task_Params_init(&task1Params);
    // task1Params.stackSize = 2048;
    // task1Params.arg0 = (xdc_UArg)&handleIN;
    // task1Params.priority = 3;
    // task1 = Task_create((Task_FuncPtr)task1Fxn, &task1Params, &eb);
    if (task0 == NULL)// || task1 == NULL)
    {
    System_abort("");
    }
    BIOS_start();
    return(0);
    }
    /*
    * ======== tsk0Fxn ========
    * Task that owns input channel
    */
    Void task0Fxn(GIO_Handle outStream)
    {
    unsigned char bufferOUT[1];
    unsigned char i;
    unsigned long counter=1;
    xdc_SizeT Size;
    unsigned char Run = 1;
    /* Load static buffers - OUTPUT */
    // GIO_prime(outStream, bufferOUT, 1, NULL);
    GIO_issue(outStream, bufferOUT, 0, NULL);
    GIO_issue(outStream, bufferOUT, 0, NULL);
    while(Run == 1)
    {
    /* Simulate waiting for input to wake task up */
    WaitForInput = 1;
    Clock_tickStart();
    while (WaitForInput == 1)
    {
    Task_sleep(10);
    }
    // GIO_reclaim(outStream, (xdc_Ptr)bufferOUT, &Size, NULL);
    for (i = 0; i < 1; i++)
    {
    bufferOUT[i] = counter++;
    }
    // GIO_issue(outStream, bufferOUT, sizeof(bufferOUT), NULL);
    }
    }
    Void userIdle1(void)
    {
    unsigned char deleteResources = 0;
    WaitForInput = 0;
    unsigned char bufferOUT[1];
    unsigned char bufferIN[1];
    xdc_SizeT Size;
    if (deleteResources == 1)
    {
    // GIO_issue(handleIN, bufferIN, sizeof(bufferIN), NULL);
    // GIO_issue(handleOUT, bufferOUT, 0, NULL);
    // GIO_reclaim(handleOUT, (xdc_Ptr)bufferOUT, &Size, NULL);
    // GIO_reclaim(handleIN, (xdc_Ptr)bufferIN, &Size, NULL);
    Task_delete(&task0);
    GIO_delete(&handleIN);
    GIO_delete(&handleOUT);
    }
    }
    Void task1Fxn(GIO_Handle inStream)
    {
    unsigned char bufferIN[1];
    // xdc_Ptr myBuf2;
    xdc_SizeT Size;
    /* Load static buffers - INPUT */
    GIO_issue(inStream, bufferIN, sizeof(bufferIN), NULL);
    GIO_issue(inStream, bufferIN, sizeof(bufferIN), NULL);
    while(1)
    {
    GIO_reclaim(inStream, (xdc_Ptr)bufferIN, &Size, NULL);
    //process incoming data
    GIO_issue(inStream, bufferIN, sizeof(bufferIN), NULL);
    }
    }
    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Scott Gary
    Posted by Scott Gary
    on Jun 27 2012 22:18 PM
    Verified Answer
    Verified by David Friedland
    Genius10040 points

    Marshall,

    OK thanks for switching to GIO, and for the update.

    It doesn’t make any sense to me that the Task_create() calls will fail just because the task’s function has GIO_issue()/GIO_reclaim() calls in it.  The only things I can think of are if the memory allocations for the task’s stack or hooks are failing, or the creation hooks (if used) return errors.  But those don’t really fit with what you describe. 

    Is it possible that your Task.defaultStackHeap is running out of space?

    I will send some pings internally to see if any others have ideas…

    Scott

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Marshall Schiring
    Posted by Marshall Schiring
    on Jun 28 2012 11:00 AM
    Intellectual420 points

    Scott Gary

    Marshall,

    OK thanks for switching to GIO, and for the update.

    It doesn’t make any sense to me that the Task_create() calls will fail just because the task’s function has GIO_issue()/GIO_reclaim() calls in it.  The only things I can think of are if the memory allocations for the task’s stack or hooks are failing, or the creation hooks (if used) return errors.  But those don’t really fit with what you describe. 

    Is it possible that your Task.defaultStackHeap is running out of space?

    I will send some pings internally to see if any others have ideas…

    Scott

    Scott,

    No task hooks are used. I thought it might be stack sizes or some other memory allocation as well. Something related to running the program and making a change and rerunning without ever calling a delete(). For this reason I added the option to delete resources in my idle function (although I don't know if this is proper usage, but I don't know how to return from BIOS_start() either to do it in main).

    I doubled the default heapMem from 8192 to 16384 and had no luck. Looking at ROV it doesn't look remotely close to filling (something like 0x3e30 free of 0x4000). I am still not able to debug step into these module functions to see what might be going on.

    But now for some good news, I moved the task back to being created statically in the configuration file. My GIO_Handle is just a global variable in my main file and no arguments passed into the task. The task creates and runs fine with GIO functions. I'm not sure how this might help us figure out why the dynamic task creation fails.

    Marshall

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Marshall Schiring
    Posted by Marshall Schiring
    on Jun 29 2012 15:47 PM
    Intellectual420 points

    Scott,

    I think I've found my error in dynamically creating the tasks. I had not initialized my Error_Block. Setting this parameter to NULL, initializing the Error_Block pointer, eb, to NULL, or using the Error_init() function all seem to have task creation going smoothly. I'm not sure on the inner working on why/how that relates to the GIO calls, but nonetheless, I can keep moving forward!

    So I guess I'll move along using GIO - is there a reason shy away from Stream? Stream and GIO look functionally the same. It looks like IPC (stream) is fairly "new" while SYS/BIOS (and I suspect GIO) has been out much longer.

    Anyway, thanks for all your help and patience.

    Marshall

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Scott Gary
    Posted by Scott Gary
    on Jun 29 2012 16:41 PM
    Genius10040 points

    Marshall,

    OK, great!  Thanks for the update. And for *your* patience in working thru this.

    I’d been trying to imagine a scenario where just adding the GIO function calls (but without calling them) could cause the Task create failures.  I was going to build a test case this afternoon to see if I could recreate it.  Now I’ll look at how the uninitialized Error_Block would cause the create failure, and look for a way to fix it, or at least document it.

    For GIO versus Stream… I don’t know the details, but from talking to those more familiar with the two, GIO is the recommendation.  I gather there are more people using GIO versus stream, and the internals are simpler.

    Scott

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
TI E2E™ Community
  • Support Forums
  • Blogs
  • Videos
  • Groups
  • Site Support & Feedback
  • Settings
TI E2E™ Community Groups
  • TI University Program
  • Make the Switch
  • Microcontroller Projects
  • Motor Drive & Control
Other Communities
  • Deyisupport
  • Designsomething.org
  • beagleboard.org
  • TI on Element 14
  • TI on TechXchangeSM
Other Technical & Support Resources
  • WEBENCH® Design Center
  • Product Information Centers
  • Technical Documents
  • TI Design Network
  • TI Technical Articles
  • TI Training

All content and materials on this site are provided "as is". TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with regard to these materials, including but not limited to all implied warranties and conditions of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with respect to these materials. No license, either express or implied, by estoppel or otherwise, is granted by TI. Use of the information on this site may require a license from a third party, or a license from TI.

Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms of Use of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms of Use of this site. TI, its suppliers and providers of content reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.

Follow Us Texas Instruments on Facebook Texas Instruments on Twitter Texas Instruments on LinkedIn Texas Instruments on Google+
TI Worldwide | Contact Us | my.TI Login | Site Map | Corporate Citizenship | mobile m.ti.com (Mobile Version)

TI is a global semiconductor design and manufacturing company. Innovate with 100,000+ analog ICs and
embedded processors, along with software, tools and the industry’s largest sales/support staff.

© Copyright 1995-2013 Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy Policy | Terms of Use