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.

MSP430FR2355: code issue ??

Part Number: MSP430FR2355


For reference :

                    if (!process.sysIDlockoutFlag)
                    {
                        /*
                         * return last four keystrokes before
                         * ALL switch and check to see all
                         * are valid (!= 0)
                         */
                        p_Seq = systemIdentification(systemID);
                        for (int lcl = 0; lcl < 4; lcl++)
                        {
                            if (*(p_Seq + lcl) == 0)
                            {
                                process.sysIDlockoutFlag = F;
                                Button = NUL;
                                break;
                            }
                            process.sysIDlockoutFlag = T;
                            Button = DEFINE_SYS;
                        }
                    }

                case DEFINE_SYS:
                    if (process.sysIDlockoutFlag)
                    {
                        switch (sysMssg)
                        {
                        case MSG1:
                            mssg[4] = (0xC0);
                            mssg[5] = *p_Seq;
                            sysMssg++;
                            break;
                        case MSG2:
                            mssg[4] = (0xA0);
                            mssg[5] = *(p_Seq + 1);
                            sysMssg++;
                            break;
                        case MSG3:
                            mssg[4] = (0x90);
                            mssg[5] = *(p_Seq + 2);
                            sysMssg++;
                            break;
                        case MSG4:
                            mssg[4] = (0x88);
                            mssg[5] = *(p_Seq + 3);
                            sysMssg++;
                            break;
                        default :
/*                            sysMssg = MSG1;
                            currentSwState = 0;
                            swInfo.multipleSw = F;
                            swInfo.err = F;
                            swInfo.twoSec = 0;
                            memset(swInfo.hits, 0, sizeof(swInfo.hits));
                            process.mssgPopulatedFlag = F;
                            Button = NUL;
                            wakeRadio(F);*/
                        }
                    }

                if ((Button == PAIR) || (Button == DEFINE_SYS))
                {
                    CRC_Result = CRC((char *)pTx);
                    mssg[6] = (char)((CRC_Result >> 8) & 0xFF);
                    mssg[7] = (char)(CRC_Result & 0xFF);
                    process.mssgPopulatedFlag = T;
                }

The basics....the code above puts messages together and prepares them for another block of code which is a transmitter.  If I place a breakpoint within case MSG1 I can see p_Seq and all looks fine....If I then move the breakpoint to case MSG2 only *p_Seq looks fine and *(p_Seq + x) all get scrubbed.  The only place in code it gets written to is within the if statement above.  I have verified that I do not break within here until all MSG1 - MSG4 have transmitted.  There are conditional wrappers (not seen) around some of the code above but ALL flags indicate they do NOT change until everything has been transmitted out.  Can someone give me insight as to why p_Seq values are updated from good to '0' on the last three entries??

Thanks

  • It looks like systemIdentification() returns a pointer. If systemIdentification() is returning a pointer to a variable on the stack then what p_Seq points at may be overwritten by other variables on the stack.

    Can you show the contents of systemIdentification()?

  • Yes the function returns a char * and p_Seq is the local variable in main that takes that value.  I never call the function a second time.  I guess I don't understand how it could get overwritten as I thought that returning from a function and placing the value into a block function variable in main protects it from getting crushed.....certainly after returning throughout the process of sending the 4 packet message other ISRs will get called.

    unsigned char* systemIdentification (volatile char *p) {
        unsigned char j, k, t, r, allSwPosition, trap = 0;
        unsigned char realign[6] = {0};
        unsigned char result[4] = {0};
    
        for (j = 0; j < 6; j++) {
            /*
             * this will trap any oddities with ALL
             * bit set...There should ever only be one
             * of the entries that has the ALL bit set.
             */
            if (*(p+j) & SW_ALL) {
                allSwPosition = j;
                trap++;
            }
        }
        /*
         * Only execute if ALL switch has
         * been set on one of the captures
         * from here we count backwards to
         * locate the switches thrown
         * for system ID...xor loop checks from
         * entry to entry to identify what
         * was thrown...first 2 for loops
         * realign entries placing the all
         * entry at 0 location
         */
        if (trap == 1) {
            for (k=allSwPosition; k < 6; k++)
                realign[k-allSwPosition] = *(p+k);
    
            for (t = 0; t < allSwPosition; t++)
                realign[t + (6-allSwPosition)] = *(p+t);
    
            for (r = 0; r < 4; r++)
                result[r] = realign[r+1]^realign[r+2];
        }
        return result;
    }
    

  • Steve Wenner said:
    I guess I don't understand how it could get overwritten as I thought that returning from a function and placing the value into a block function variable in main protects it from getting crushed.

    systemIdentification() allocates the result[] array as a local variable on the stack, and returns a pointer to the result[] array on the stack.

    Once systemIdentification() has returned then the stack address for result[] may be re-used for a different variable. See Return of Stack Variable Address for some background information.

    Suggest systemIdentification() is changed so that the result array is passed as a parameter, which the calling function supplies.

  • I'm confused as I copied this function from rev 1 of the application and it worked just fine....I can certainly pass an empty array into the function to be filled by result but doesn't that defeat the whole purpose of using pointers to move things back and forth?  Is there a way at the main level to have the pointer point to an empty array and that array takes on result before moving to the next line of code where result can get reused??

    My apologies....I'm a hardware guy who's self taught learning coding on the fly the past year and a half

    I guess it could have worked in version 1 based upon how the ISRs, etc. may have been called relative to version 2 here?

  • Steve Wenner said:
    I'm confused as I copied this function from rev 1 of the application and it worked just fine.

    Does Scope vs. Lifetime of Variable help to explain why the code has Undefined Behavior?

  • Yes I sort of understand the scope issue and I can certainly see where there will be issues.....

    Let  me ask you.....I placed static in front of the variable result within the function and that seems to have solved my issue....Can you see anything wrong with doing it this way?

  • Steve Wenner said:
    Can you see anything wrong with doing it this way?

    By making the result variable static the only potential issue is that the function is not reentrant. I.e.:

    a. The systemIdentification() function is not safe to be called from both an interrupt routine and the main thread.

    b. A 2nd call to systemIdentification() will overwrite the result from a previous call. I.e. the result from from systemIdentification() needs to be processed before the function can be called again.

  • I am fulfilling both of those cases.....

    Thank you

**Attention** This is a public forum