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.

[C6713] Posting simple SWI leads to problems

Other Parts Discussed in Thread: CCSTUDIO

I am having trouble getting a SWI to function properly on my TMS320C6000.

In my application, main waits for messages from a host application. The HWI takes care of time-critcal data events and the SWI is posted from within the HWI such that it takes care of less time-critical calculations after the HWI finishes up.

The trouble is that the code hangs up the first time the SWI is called. I can use the "DSP/Bios Kernal Object View" to check on the status of the SWI I created dynamically. The state of the SWI (which could be "inactive", "ready", or "running") starts out as "inactive". Once the SWI is posted, it becomes "ready". At that point, the code hangs up. I never see it show "running". So, I suspect I am doing something wrong, and I need some help.

I have defined my SWI with the following:

volatile  int  SWITally = 0;

void  swiCountFxn(void); // Function for SWI

// Use the below for dynamic creation of the SWI
SWI_Attrs  attrs={(SWI_Fxn)swiCountFxn,0,0,10,0}; // Pointer to swi attributes (Priority=10)
SWI_Handle    swi;    // Handle for new swi object that will use 'attrs'


// SWI Function
//=============================================================================
void swiCountFxn(void) // Simple function for testing SWI
{
    SWITally = (SWITally + 1) % 100000; // Increment SWITally index modulus 100000
}
//=============================================================================

 

And I post the SWI from within my HWI with:

SWI_post(swi);


Any thoughts here? Have I set-up and defined my SWI properly?

For the record, when the code does hang up, it seems to just sit there without ever advancing (or allowing anymore HWIs). At that point, if I "halt" the run or refresh the "watch window", I get a warning that forces me to disconnect.

Any thoughts, ideas or suggestions are appreciated.

Thanks.

  • wrettubj said:
    In my application, main waits for messages from a host application.

    If I understood correctly, you are not leaving main. Do you have like a while loop inside main waiting for something? If you are not leaving main, DSP/BIOS will not work. So SWIs will not work either.

  •  

    I do have a while loop inside main that waits for a message from the host. But, I do believe that I am leaving main as the HWI is a outside of main, and if I comment out the line

    SWI_post(swi);

    from my HWI, then everything else (besides the SWI) works fine including the calculations in the HWI and the receipt of messages in main.

    This is why I suspect the problem is only related to the SWI.

    Is that clear? I'm new to this, so let me know if I am not being clear enough.

    Thanks.

  • It is clear.

    Hardware Interrupts might work because they are not necessarily DSP/BIOS dependent. But all the other DSP/BIOS functions (TSKs, SWIs, SEM, MBX) will not work unless you leave main. So your main function would be used just for initializations in a DSP/BIOS project - and never with a while loop inside it:

    void main (void){

    // initializations

    } -> when main exits, DSP/BIOS is initialized and starts running

    You would put the while loop inside a task probably.

    If you are a beginning with bios, I would take a look at the examples we provide:

    C:\CCStudio_v3.3\bios_5_xx_xx\packages\ti\bios\examples

    This way you have a starting point.

     

     

  •  

    Mariana,

    Thanks for your replies. I have learned that (due to my inexperience) we are not on the same page. But the good news is that I have also learned a few things because of your replies.

    So, I am using a TI TMS320C6713 mounted on a third-party PCI board that comes with a number of supporting classes. After you mentioned the problem with the while loop in main, I did some digging as I recalled that in some provided examples, the third-party had used a while loop in main in the same way I did.

    It turns out that in their examples, they replace main with something else ( let's call it XYZmain() ) which is constructed as a default thread running within normal priority. The third party claims that I can safely call any BIOS function within XYZmain().

    So, I have build my development code on one of these examples, and as a result, the main I refer to above is actually XYZmain().

    Armed with this knowledge, I removed the line of code in my HWI that posts my SWI and put it into the while loop in XYZmain(). Simultaneously, I commented out the line in the while loop that waits for messages from the host.

    When I run that version of the code, I am able to get the SWI to post and run properly.

    So, this all makes me think that my problem is with posting a SWI from the HWI and not with the SWI itself.

    Any tips or pitfalls that I should be aware of when posting a SWI from a HWI?

    Thanks!

     

     

     

  • Are you ever actually creating the SWI? Because you are not creating the SWI statically (inside the BIOS graphical configuration tool) you are attempting to create one dynamically at run-time. I see the attributes for the SWI I do not see in your code snippet anyplace where you actually create the new SWI (SWI_create()).

    Assuming you are indeed creating the SWI there aren't any real pitfalls from calling it within an HWI. The SWI module was built to generate an identical execution flow to a HWI, but by its definition the SWI is preemptable (interruptible) whereas an HWI is not. This allows you to execute the code at a higher priority than every task, but does not prevent the system from servicing additional interrupts.

  •  

    Thanks Tim.

    Yes, I failed to mention that within XYZmain(), I have the line

    swi = SWI_create(&attrs);

    that creates the SWI dynamically and prior to the while loop in XYZmain().

    The strange thing is that I can get the SWI to post and run fine when I post it in the while loop in XYZmain(), but when I move the SWI post command to the HWI things fall apart.

    I'm not sure what else to try!

  • Have you tried creating the SWI statically in the .tcf file?

  • The only other thing I can think to try is to de-reference the SWI object when you post the function (SWI_post(&swi);). It could be a problem with scope, but I would think that the compiler would gripe if this were incorrect.

  • Tim, that made me think that if your swi (the swi object that is callen when you do SWI_post(swi)) is local in XYZmain, it could be causing the problem.

    wrettubj, make sure it is global...

  • I agree, but if the object is indeed local (stored on the stack) then the compiler should fail when it sees the SWI_post(swi). The object itself should indeed be global.

  •  

    The compiler gives me an error when I de-reference the SWI object when I post the function ( SWI_post(&swi) )...

    "Abc.cpp", line 108: error: argument of type "SWI_Handle *" is incompatible with parameter of type "SWI_Handle"

     

     

    ... and as for creating the SWI statically in the *.tcf file...

    I could never get the code to compile when I did this. I create the SWI object in the*.tcf file ( let's call it SWItcf ). At the top of my code, I define

    extern  SWI_Obj  SWItcf;

    and in contrast to the above, I MUST de-reference the SWI object when I post it ( SWI_post(&SWItcf) ). But when I ask this version to compile, I get the error...

    "error: symbol referencing errors - './Debug/Abc.out' not built"

    And that error comes with additional information that says: "undefined symbol, swiCountFxn. First referenced in file C:\\...\Debug\\Abccfg.obj"

    swiCountFxn is the SWI function that I related to the SWI object in the properties of the SWI in the *.tcf file.

    So, I couldn't get the statically created SWI to releate to the SWI function I defined. I am assuming it is safe to keep the SWI function in the general code (just the same way I did above when I dynamically created a SWI). Is that a correct assumption?

    Thanks.

     

     

  •  

     

    Yep, It's global. I define it up with all my other global variables and such.

  • wrettubj said:

    and in contrast to the above, I MUST de-reference the SWI object when I post it ( SWI_post(&SWItcf) ). But when I ask this version to compile, I get the error...

    "error: symbol referencing errors - './Debug/Abc.out' not built"

    And that error comes with additional information that says: "undefined symbol, swiCountFxn. First referenced in file C:\\...\Debug\\Abccfg.obj"

    swiCountFxn is the SWI function that I related to the SWI object in the properties of the SWI in the *.tcf file.

    So, I couldn't get the statically created SWI to releate to the SWI function I defined. I am assuming it is safe to keep the SWI function in the general code (just the same way I did above when I dynamically created a SWI). Is that a correct assumption?

    When you specify a function in the SWI object in BIOS you must precede the function name with an underscore (e.g., _swiCountFxn). BIOS allows you to plug in an Assembly routine to any of these functions, and as such you must define the raw symbol name. Way back when the fathers of C were creating the language they decided they wanted C and Assembly code to coexist peacefully without stomping on each other. As such they decided to add an underscore to the beginning of every C symbol. This means that your C code could contain a variable 'int temp' (which, when compiled, becomes _temp) and your Assembly routine could create a symbol temp: as well. Despite the same spelling they are now different symbols.

    With all that said, if you are not married to the idea of dynamically creating your SWI try creating the object statically in the .tcf file again only this time ensure you link it to function _swiCountFxn instead.

  •  

    Thanks Tim.

    Yeah, I read about this and tried it previously. I get the same error I mentioned above, but this time it says: "undefined symbol, _swiCountFxn". By the way, this is an error that comes up during the linking portion of the compile..

    Admittedly, I was not sure how liberal I had to be with the underscores. By this I mean, I only put the underscore in front of the function name when adding it to the property of SWItcf in the *.tcf file. I kept all the other associations the same... i.e. no underscore for:

    void  swiCountFxn(void); // Function for SWI

     

    // SWI Function
    //=============================================================================
    void swiCountFxn(void) // Simple function for testing SWI
    {
        SWITally = (SWITally + 1) % 100000; // Increment SWITally index modulus 100000
    }
    //=============================================================================

    I have tried putting underscores in front of all mentions of swiCountFxn throughout the code, but this made little sense to me, and did not help anyway.

    I appreciate your time an patience; thanks!

  • The only reason you have to add the underscore in BIOS is because the BIOS routine does not assume you are calling a C function. Because of the possibility of calling Assembly you must explicitly tell it the exact symbol name.

    Also, make sure that you are adding the BIOS-generated header file to your source code (e.g., if you named your BIOS file myBios.tcf then the header will be named myBioscfg.h).

  • Ok, I have the one underscore in front of the linked SWI function in the *.tcf file.

    And, I had forgotten to include the BIOS header file, so at the top of my source code, I added the line:

    #include "Abccfg.h"

    The end result is the same when compiling: "undefined symbol, _swiCountFxn"

    Sorry guys! This might be too many problems for a Friday afternoon!

  • I went ahead and created a simple project that builds and runs properly (note the PLL is not configured in my code so it may run slow). See the attached.

    This project uses a Task function with a dummy loop to spread out the SWI_post calls. Once the SWI is posted the scheduler will immediately branch to the SWI function swiCountFxn() and then jump back to the task when the SWI completes. You can watch the static integer defined in the SWI increment over time.

    6713_swi.zip
  •  

    Thanks Tim.

    Well, I must have bigger problems because I had been setting up my static SWI in the exact same way you did in the example you provided.

    Further, I can get your example code to compile and run, but I was never able to see any changes in the static integer in the SWI function. It only ever displayed "Identifier not found" in the watch window.

    Anyway, I think I must have some conflicts between the TI examples and resources provided by this third party... In the meantime, I will try to create a work around by creating a separate thread.

    On a related note... While trying to tackle this problem, I have learned a bunch from you and the online TI documentation. The trouble is, there is so much TI documentation available. Suppose a beginner to TMS320C6000 asked you for help in learning as much as they could about the chip and how to use it, which particular documents would you point him or her to?... and in which order would you suggest they are studied?

    Thanks.

  • wrettubj said:
    Well, I must have bigger problems because I had been setting up my static SWI in the exact same way you did in the example you provided.

    I am not sure what to say without having the whole project - but if you can leverage the example I provided maybe that will be enough.

    wrettubj said:
    Further, I can get your example code to compile and run, but I was never able to see any changes in the static integer in the SWI function. It only ever displayed "Identifier not found" in the watch window.
    I'm not sure why this wasn't updating unless you weren't stopping inside the SWI. It should show up in the watch window if you are breaking in the SWI. Try placing a breakpoint on the increment statement and mouse over the variable - this should show the current value.

    wrettubj said:
    On a related note... While trying to tackle this problem, I have learned a bunch from you and the online TI documentation. The trouble is, there is so much TI documentation available. Suppose a beginner to TMS320C6000 asked you for help in learning as much as they could about the chip and how to use it, which particular documents would you point him or her to?... and in which order would you suggest they are studied?
    I understand how overwhelming our documentation can be. Unfortunately this question is very dependent on what specifically you want to learn. Most of the better documents for general device information can be found off the device's product folder; however, this is by no means a complete list. You may also want to get familiar with the Embedded Processors Wiki as this is a great (and rapidly growing) source of information.