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.

Watch Window having trouble understanding structure data types

CCS 4.1.2
F283x Simulator

I'm having major trouble trying to view a structure of a TSK_Obj from BIOS.  My issues are similar to those described by other customers in the thread What does "cannot load from non-primitive location" mean ?.

Here's what I do.  First I create a task in the BIOS GUI:

This in turn generates several files.  The structure itself is declared in bioscfg.s28 (i.e. assembly):

bioscfg.s28 said:

;; ======== TSK_Obj BradTSK ========
;; <add comments here>
;;
;; TSK_Obj BradTSK (iFXN, iARG0, iARG1, iARG2, iARG3, iARG4, iARG5, iARG6, iARG7, iAUTOSTK, iMANSTK, iSTKSZ, iSTKSEG, iPRI, iENV, iEXITFLAG, iUSETSKNAME, iSTATREG, Order, filter, maxformat, sumformat, avgformat, filtmaxmult, filtsummult, unittype)
    .global BradTSK
    .asg _my_task, _iFXN
    .asg 00H, _iARG0
    .asg 00H, _iARG1
    .asg 00H, _iARG2
    .asg 00H, _iARG3
    .asg 00H, _iARG4
    .asg 00H, _iARG5
    .asg 00H, _iARG6
    .asg 00H, _iARG7
    .asg 01H, _iAUTOSTK
    .asg null, _iMANSTK
    .asg 0800H, _iSTKSZ
    .asg LSARAM, _iSTKSEG
    .asg 01H, _iPRI
    .asg 00H, _iENV
    .asg 01H, _iEXITFLAG
    .asg 00H, _iUSETSKNAME
    .asg 00H, _iSTATREG
    .asg 01H, _Order
    .asg 02H, _filter
    .asg "%g inst", _maxformat
    .asg "%g inst", _sumformat
    .asg "%.2f inst", _avgformat
    .asg 01H, _filtmaxmult
    .asg 01H, _filtsummult
    .asg 00H, _unittype
    TSK_Obj 1, BradTSK, 0, _iFXN, _iARG0, _iARG1, _iARG2, _iARG3, _iARG4, _iARG5, _iARG6, _iARG7, _iAUTOSTK, _iMANSTK, _iSTKSZ, _iSTKSEG, _iPRI, _iENV, _iEXITFLAG, _iUSETSKNAME, _iSTATREG, _Order, _filter, _maxformat, _sumformat, _avgformat, _filtmaxmult, _filtsummult, _unittype

It also generates in the linker an assignment to give me access from C:

bioscfg.cmd said:

_BradTSK = BradTSK;

Finally it generates a header file with the proper C extern:

bioscfg.h said:

extern TSK_Obj BradTSK;

Since "BradTSK" is of type TSK_Obj I expected the watch window to utilize the structure definition from BIOS:

tsk.h said:

typedef struct TSK_Obj {
    KNL_Obj     kobj;           /* kernel object */

    Ptr         stack;          /* used in TSK_delete() */
#ifdef _55_
    Ptr         sysstack;       /* system stack for 55x */
                                /* Unused in _55Pb_ */
#endif
    size_t      stacksize;      /* ditto */
#ifdef _55_
    size_t      sysstacksize;   /* system stackszie for 55x */
                                /* Unused in _55Pb_ */
#endif
    Int         stackseg;       /* segment to allocate stack from */
    String      name;           /* printable name */
    Ptr         environ;        /* environment pointer */
    Int         errno;          /* TSK_seterr()/TSK_geterr() */
    Bool        exitflag;       /* FALSE for server tasks */
} TSK_Obj, *TSK_Handle;

I haven't been able to figure out a way to view that object!  Here's a screenshot of things I tried and the corresponding memory:

Any other ideas?

Thanks,
Brad

 

 

  • Brad,

    Similarly to CCSv3.3, CCSv4 also requires the typecast conversion before the variable name. The post you sent before has a nice explanation by Darian to why this happens.

    I see above that you tried several combinations of typecasts but one: (TSK_Obj*) BradTSK

    This way BradTSK will be correctly treated as a task handler and show the correct elements. 

    You can see in the screens below.

     

    I don't know why, but the typedef TSK_Obj defines TSK_Obj and TSK_Handler*, therefore I wonder if CCS gets confused by that...

    Hope this helps,

    Rafael

  • That's a big step forward.  Thanks!  However, your solution does not correspond to the data definition in bioscfg.h.  It specifically defines BradTSK as being of type "TSK_Obj" not "TSK_Obj*".  I'm on vacation right now so I am not about to dig into this, but it appears to me like there is an error even in the generated header file or in the way CCS is interpreting things.

     

  • Brad,

    I did some experimenting. I defined a local variable as TSK_Obj and it was correctly identified as a struct TSK_Obj type.

    I also noticed that  CCSv4 reads BradTSK as an address instead of a variable - maybe because this variable is not explicitly defined in the source file (but via a .h file). I could file an enhancement to maybe increase the scope of verification for the watch window.

    The correct modifier and typecast should be *(TSK_Obj*) BradTSK (it works, I verified). Therefore the typecast I sent before seems to be a bug, but I am not sure if it kills to leave this "feature" as it is, since CCS recognizes both forms and gives the correct result.

    I am still checking some other things but please let me know your comments, ok?

    Just FYI: CCSv3.3 also behaves that way...

    Cheers,

    Rafael

     

  • A related question -- when you type a symbol name into the watch window does it first look for an assembly label or for the C definition first?  The command file defines _BradTSK = BradTSK.  I wonder if typing this symbol into the watch window is first resolving to the assembly language definition (i.e. no preceding underscore).  In that case perhaps it doesn't associate the corresponding C structure.

    Can you provide any more detail on how the current algorithm works?  The alternate syntax you provided doesn't make sense to me either:

    desouza said:
    The correct modifier and typecast should be *(TSK_Obj*) BradTSK (it works, I verified).

    Assuming I have not fundamentally misunderstood how this structure resides in memory, I don't believe we should be require any de-referencing in order to access it.  In other words, the structure should reside directly at the assembly label _BradTSK and not pointed to as it seems to me your syntax is doing.

  • Brad,

    Brad Griffis said:

    A related question -- when you type a symbol name into the watch window does it first look for an assembly label or for the C definition first?  

    I really don't know. At first glance it seems that it looks for symbols defined in C, since they can be used together with C modifiers. But I agree the statement _BradTSK = BradTSK can potentially confuse the debugger and thus prevent its proper type association in the watch window.

    Brad Griffis said:

    Assuming I have not fundamentally misunderstood how this structure resides in memory, I don't believe we should be require any de-referencing in order to access it.  In other words, the structure should reside directly at the assembly label _BradTSK and not pointed to as it seems to me your syntax is doing.

    In my original post I should have tied this sentence to the previous paragraph. The structure is correctly allocated in the memory and has a label called Brad_TSK at a given address. However, as I mention in the previous paragraph the watch window sees BradTSK as a pure address - if you simply put Brad_TSK in the watch window you will see a 32-bit address in hex format and of type void*.

    With this in mind, the watch window can display two things: the Brad_TSK address (no dereferencing) or the contents at the address Brad_TSK (using the dereferencing operand *).

    In other words, the first * dereferences a pointer of type TSK_Obj* named Brad_TSK. The number of asterisks and parenthesis is a bit confusing, though.

    Let me know if this helps, ok?

    Rafael

     

  • Rafael,

    Thanks for your help on this issue.  I believe it makes sense and we can mark it resolved.

    I think the issue ultimately is due to the fact that BIOS defines:

    _BradTSK = BradTSK

    This is a special/rare case where 2 versions of the same name exist, one with the underscore and one without.

    As far as I can tell, when you type a symbol into the watch window it will first attempt to match that symbol against all the assembly labels, and then it will try to prepend a leading underscore (i.e. treat it as C) and match it against those assembly labels again.  So when I typed "BradTSK" into the watch window I really intended "BradTSK" to be the name of a C structure.  However, since a label already exists called BradTSK it matches that first.

    A different way that works that might conceptually be easier to understand is to type "_BradTSK" into the watch window.  In this case it is obvious to both the user and to CCS that _BradTSK is the name of an assembly label (i.e. there is not an __BradTSK too with two leading underscores).  Since _BradTSK is a label/address it is obvious that it is the address of a TSK_Obj, i.e. a TSK_Obj*.  So the alternate way that you can write in the watch window is:

    (TSK_Obj*)_BradTSK

    It's been a long day so hopefully that explanation makes sense to everybody else!

    Best regards,
    Brad