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.

CC1310: Retrieve program loaded from device

Part Number: CC1310
Other Parts Discussed in Thread: UNIFLASH

Hello,

I'm using several custom boards based on CC1310 (CC1310F32RSMT micro) and some of them are working fine but others no. I would like to retrieve the code loaded to the program to check if there were some loading errors. Is there any way to do it?

My project consists of sending packets by RF to a gateway each 12 hours, and between this time going to sleep. The problem occurs in transmitters nodes, as some of them send the packet but don't go to sleep.

It could be due to hardware errors but customs boards are made in reels all same. That's why I wanted to check the code loaded, in case it's a chip problem. Other suggestions to check why they are not working are accepted.

Thanks in advance,

Alberto

  • Hi Alberto, 

    Assuming debugging is allowed, you can use UniFlash to verify the image on the target. The memory browser in UniFlash (or CCS) can also be used read the entire flash memory range and export it to a file.

    Above can only be done if debugging is allowed, and if debugging is allowed, I would suggest just starting a project-less debug session using CCS, and use the disassembler and debug the program.

    If debugging is not allowed, then I am afraid that you won't be able to retrieve the program. 

    Regards,
    Nikolaj

  • Hi Nikolaj,

    Thanks for your reply. I used uniflash and export memory. I compared both and are exactly the same.

    Do you know any other suggestions?

    Regards,
    Alberto

  • Hi Alberto, 

    How are you determining that the the node does not go to sleep? For nodes which have this issue, is it only sometimes that they don't go to sleep or do they never go tp sleep after they send the packet?

    The problem occurs in transmitters nodes, as some of them send the packet but don't go to sleep.

    Thanks,
    Nikolaj

  • Hi Nikolaj,

    I'm mesuring current consumption using a multimeter, and when they go to sleep it consumes around 18 uA. The ones which have this issue consumes 1.3 mA. They never go to sleep after they send the packet.

    If this helps, this is my code. Sleep() is located in 441 line.

    /*
     * Copyright (c) 2019, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /***** Includes *****/
    /* Standard C Libraries */
    #include <stdlib.h>
    #include <unistd.h>
    
    /* TI Drivers */
    #include <ti/drivers/rf/RF.h>
    #include <ti/drivers/PIN.h>
    #include <ti/drivers/pin/PINCC26XX.h>
    #include <math.h>
    #include <smartrf_settings/smartrf_settings.h>
    #include <time.h>
    #include <ti/sysbios/hal/Seconds.h>
    #include <ti/drivers/ADCBuf.h>
    #include <ti/drivers/ADC.h>
    //#include <ti/devices/cc13x0/driverlib/aon_ioc.h>
    //#include <ti/sysbios/family/arm/cc26xx/Timer.h>
    #include <ti/dpl/PowerCC26XX_tirtos.c>
    #include <ti/drivers/Power.h>
    #include <ti/drivers/power/PowerCC26XX.h>
    #include <ti/devices/cc13x0/driverlib/aon_batmon.h>
    
    
    /* Driverlib Header files */
    #include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)
    
    /* Board Header files */
    #include "Board.h"
    #include <ti/drivers/GPIO.h>
    
    /***** Defines *****/
    #define ADCBUFFERSIZE    (28)
    
    #define ADC_SAMPLE_COUNT  (10)
    
    #define THREADSTACKSIZE   (768)
    
    #define ID0 0
    #define ID1 1
    
    /* Do power measurement */
    //#define POWER_MEASUREMENT
    
    /* Packet TX Configuration */
    #define PAYLOAD_LENGTH      204
    #define NORM_VALUES         10
    #ifdef POWER_MEASUREMENT
    #define PACKET_INTERVAL     5  /* For power measurement set packet interval to 5s */
    #else
    #define PACKET_INTERVAL     300  /* Set packet interval to 500000us or 500ms */
    #endif
    
    /***** Prototypes *****/
    
    /***** Variable declarations *****/
    static RF_Object rfObject;
    static RF_Handle rfHandle;
    //Timer_Object *TimerObj;
    //Timer_Handle TimerHandle;
    
    /* Pin driver handle */
    //static PIN_Handle ledPinHandle;
    //static PIN_State ledPinState;
    
    static char packet[PAYLOAD_LENGTH];
    //static uint16_t seqNumber;
    
    /* ADC conversion result variables */
    uint16_t adcValue0;
    uint32_t adcValue0MicroVolt;
    uint16_t adcValue1[ADC_SAMPLE_COUNT];
    uint32_t adcValue1MicroVolt[ADC_SAMPLE_COUNT];
    
    uint16_t sampleBufferOne[ADCBUFFERSIZE];
    uint16_t sampleBufferTwo[ADCBUFFERSIZE];
    float microVoltBuffer[ADCBUFFERSIZE];
    float valor_temperatura=0;
    float media[ADCBUFFERSIZE];
    int_fast16_t val;
    float Temperature;
    float v_temperature[24];
    bool first_time = true;
    bool send_payload = false;
    
    /*
     * Application LED pin configuration table:
     *   - All LEDs board LEDs are off.
     */
    PIN_Config pinTable[] =
    {
        Board_PIN_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    #ifdef POWER_MEASUREMENT
    #if defined(Board_CC1350_LAUNCHXL)
        Board_DIO30_SWPWR | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    #endif
    #endif
        PIN_TERMINATE
    };
    
    /***** Function definitions *****/
    float conversionTemp(uint16_t value){
        float NTC;
        float Temp;
    
    //    NTC = ((2.27*100000)/value)-100000;
    //    NTC = NTC/1000;
        NTC = 100000*4096/value - 100000;
        NTC = NTC/1000;
    
        Temp = 66.266*exp((-0.01*NTC));
    //    Temp = exp((NTC-421.37)/-96.7);
    
        return(Temp);
    }
    
    void conversionFloat(float temp, float battery, char * packet, unsigned int index)
    {
        float aux=roundf(temp * 100); // Get 2 decimals precision ( Format: 23.48 ºC for example )
        int n=(int)aux; // Convert to int
    
        uint8_t i;
    
        /*if(index == 0){
            for(i=5;i>1;i--) // Sending temperature data. First 2 bytes are not written, current configuration information
            {
                packet[i]=n%10; // In the first iteration, this corresponds to the first digit
                n=n/10;
            }
    
            aux=roundf(battery * 100); // Format: 2.35 V for example
            n=(int)aux;
    
            for(i=8;i>5;i--) // Sending battery voltage data
                {
                    packet[i]=n%10;
                    n=n/10;
                }
        }else{*/
        for(i=(5+index*9-index);i>(1+index*9-index);i--) // Temperature
        {
            packet[i]=n%10 + '0';
            n=n/10;
        }
    
        aux=roundf(battery * 100);
        n=(int)aux;
    
        for(i=(9+index*9-index);i>(5+index*9-index);i--) // Battery voltage
        {
            if((i+index) %9 == 0){
                packet[i] = '!'; // Data separator
            }else{
                packet[i]=n%10 + '0';
                n=n/10;
            }
        }
    }
    
    uint16_t readADC(){
    
        ADC_Handle   adc;
        ADC_Params   params;
        int_fast16_t res;
        //float floatValue;
        uint16_t normValue = 0;
        uint8_t i;
    
        ADC_init();
        ADC_Params_init(&params);
        adc = ADC_open(2, &params);
    
        if (adc != NULL) {
    
            for (i=0; i < NORM_VALUES; i++){
                /* Blocking mode conversion */
                res = ADC_convert(adc, &adcValue0);
    
                if (res == ADC_STATUS_SUCCESS) {
    
                    adcValue0MicroVolt = ADC_convertRawToMicroVolts(adc, adcValue0);
    //                floatValue = adcValue0MicroVolt*1.00/1000000.00;
                    normValue += adcValue0;
                    adcValue0 = 0;
    
                }else{
                    i--;
                }
            }
    
            normValue = normValue/NORM_VALUES;
    
            ADC_close(adc);
        }
    
        return (normValue);
    }
    
    float getBatteryValue(){
    //    uint32_t battery, BATstatus;
    //    float BATvoltage;
    //
    //    battery = AONBatMonBatteryVoltageGet();
    //
    //    // convert in Milli volts
    //    BATstatus = (BATstatus * 125) >> 5;
    //
    //    //convert in floating point value
    //    BATvoltage = (float)BATstatus / 1000;
    
        float MeasuredVoltage = (float)(((uint32_t)HWREG(AON_BATMON_BASE + AON_BATMON_O_BAT)*125) >> 5)/1000; // Convert to milivolts, then convert to float
    
        return (MeasuredVoltage);
    }
    
    void *mainThread(void *arg0)
    {
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        struct tm* next_time;
        struct tm current_time;
        //time_t next_seconds;
        time_t current_seconds;
        //uint32_t sleep_interval;
    
    //    float batteryValue;
    
    //    memset(&next_time, 0, sizeof(struct tm)); // YO he comentado esta línea
        memset(&current_time, 0, sizeof(struct tm)); // Esta línea estaba comentada
    
    //    float microVoltValue;
        uint16_t ADCvalue;
        //float Temperature;
        //float v_temperature[12]; // Vector of temperatures measured to be sent
        float v_MeasuredVoltage[24];
        float MeasuredVoltage;
        float aux_temp = 0;
        float aux_voltage = 0;
        unsigned int cont = 0;
    
        RF_cmdPropTx.pktLen = PAYLOAD_LENGTH;
        RF_cmdPropTx.pPkt = packet;
        RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
    
        /* Request access to the radio */
        rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
    
        /* Set the frequency */
        RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
    
    
        // Set guardian ID
        unsigned int id = 5;
    
        // Payload id
        unsigned int payload_id = 0;
    
        // Set the struct date / time to 2016 / 5 / 21 18:00:00
        current_time.tm_year = 2022 - 1970;
        current_time.tm_mon = 8 - 1;
        current_time.tm_mday = 11;
        current_time.tm_hour = 16;
        current_time.tm_min = 49;
        current_time.tm_sec = 0;
    
        // Set the struct date / time to 2016 / 5 / 21 18:00:00
        //next_time.tm_year = 2016 - 1970;
        //next_time.tm_mon = 5 - 1;
        //next_time.tm_mday = 21;
        //next_time.tm_hour = 18;
        //next_time.tm_min = 0;
        //next_time.tm_sec = 0;
    
        AONBatMonEnable(); // Enable the measurements of the temperature and the battery voltage
    
        /* Create packet with incrementing sequence number and random payload */
        packet[0] = (uint8_t)ID0;
        packet[1] = (uint8_t)ID1;
    
        // Estas líneas de abajo estaban comentadas
        current_seconds = mktime(&current_time); // Convert to number of seconds, this will also fill up tm_wday and tm_yday
        Seconds_set(current_seconds); // Set the date into the system (Update the real time clock with number of seconds since 1970)
    //
    //    next_seconds = mktime(&next_time);
    //
    //    sleep_interval = next_seconds-current_seconds;
        RF_EventMask terminationReason;
    
        while(1) // Executed each 1 hour
        {
            // Get Battery level
    //        float batteryValue = getBatteryValue();
            //float MeasuredVoltage = (float)(((uint32_t)HWREG(AON_BATMON_BASE + AON_BATMON_O_BAT)*125) >> 5)/1000; // Battery level. Convert to milivolts, then convert to float
    
            uint8_t i = 0;
            for(i=0; i<5; i++){ // Mean of 5 measurements
                ADCvalue = readADC();
                aux_temp += conversionTemp(ADCvalue); // ADC value conversion to temperature
                aux_voltage += (float)(((uint32_t)HWREG(AON_BATMON_BASE + AON_BATMON_O_BAT)*125) >> 5)/1000; // Battery level. Convert to milivolts, then convert to float
            }
            Temperature = aux_temp/5;
            MeasuredVoltage = aux_voltage/5;
            aux_temp = 0;
            aux_voltage = 0;
    
            //ADCvalue = readADC();
            //Temperature = conversionTemp(ADCvalue); // ADC value conversion to temperature
            //conversionFloat(Temperature, MeasuredVoltage, packet); // Get packet with temperature and battery data
    
            if(cont<12){
                v_temperature[cont] = Temperature;
                v_MeasuredVoltage[cont] = MeasuredVoltage;
                cont++;
            }
            else{
                cont = 0;
                send_payload = true;
            }
    
            if(send_payload){// Down half with current measurements and upper half with 12h previous ones
                send_payload = false;
                uint8_t j=0;
                for(j=0; j<12; j++){
                    v_temperature[j+12] = v_temperature[j];
                    v_MeasuredVoltage[j+12] = v_MeasuredVoltage[j];
                }
            }
    
    //        uint8_t i;
    //        for (i = 2; i < PAYLOAD_LENGTH; i++)
    //        {
    //            packet[i] = 9;
    //        }
    
            UInt32 seconds = Seconds_get(); // Get current seconds
            next_time = localtime(&seconds); // Convert current time to struct
    
            if(next_time->tm_hour == 4 || next_time->tm_hour == 16){ // Send packet each 12h
            //if(next_time->tm_min >= 0 || next_time->tm_min == 1 || next_time->tm_min == 2 || next_time->tm_min == 3 || next_time->tm_min == 4 || next_time->tm_min == 5){
                if(first_time){
                    //sleep(id); // Offset random time
                    first_time = false;
                }
                for(i=0; i<24; i++){
                    conversionFloat(v_temperature[i], v_MeasuredVoltage[i], packet, i); // Create packet with temperature and battery voltage
                }
    
                // Copy guardian identifier into packet
                packet[194] = 'I';
                unsigned int n;
                if(id<10){
                    packet[195] = id +'0';
                }else if(id>=10 && id<100){
                    n = id;
                    packet[196]=n%10 + '0';
                    n=n/10;
                    packet[195]=n%10 + '0';
                }else if(id>=100){
                    n = id;
                    packet[197]=n%10 + '0';
                    n=n/10;
                    packet[196]=n%10 + '0';
                    n=n/10;
                    packet[195]=n%10 + '0';
                }
    
                // Copy payload identifier into packet
                packet[198] = 'T';
                if(payload_id<10){
                    packet[199] = payload_id +'0';
                }else if(payload_id>=10 && payload_id<100){
                    n = payload_id;
                    packet[200]=n%10 + '0';
                    n=n/10;
                    packet[199]=n%10 + '0';
                }else if(payload_id>=100 && payload_id<1000){
                    n = payload_id;
                    packet[201]=n%10 + '0';
                    n=n/10;
                    packet[200]=n%10 + '0';
                    n=n/10;
                    packet[199]=n%10 + '0';
                }else if(payload_id>=1000 && payload_id<10000){
                    n = payload_id;
                    packet[202]=n%10 + '0';
                    n=n/10;
                    packet[201]=n%10 + '0';
                    n=n/10;
                    packet[200]=n%10 + '0';
                    n=n/10;
                    packet[199]=n%10 + '0';
                }else if(payload_id>=10000 && payload_id<100000){
                    n = payload_id;
                    packet[203]=n%10 + '0';
                    n=n/10;
                    packet[202]=n%10 + '0';
                    n=n/10;
                    packet[201]=n%10 + '0';
                    n=n/10;
                    packet[200]=n%10 + '0';
                    n=n/10;
                    packet[199]=n%10 + '0';
                }
    
                terminationReason = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, NULL, 0); // Send packet
                payload_id++;
            }
            RF_yield(rfHandle); // Radio powered off
            sleep(3600); // 1 hour sleep
        }
    }
    
     

    Regards,

    Alberto

  • Hi Alberto,
    will you be able to debug your application, and step through the sleep function. Calling sleep will result in a call to PowerCC26XX_standbyPolicy. If it enters standby it is supposed to call Power_sleep, if it does not enter standby it will call PRCMDeepSleep or PRCMSleep. 

    If it does not call Power_sleep, could you inform me of the condition that prevents it from calling Power_sleep?

    Regards,
    Nikolaj

  • Hi Nikolaj,

    Sorry for my late reply, I was out of office. I can't debug my application on my custom board. Instead, I debugged it on CC1310 launchpad but it doesn't enter to Power_sleep() function you mention, but to sleep() function in 'sleep.c' file.

    unsigned sleep(unsigned seconds)
    {
        unsigned long secs, ticks;  /* at least 32-bit */
        unsigned max_secs, rval;    /* native size, might be 16-bit */
    
        max_secs = MAX_SECONDS;
    
        if (seconds < max_secs) {
            secs = seconds;
            rval = 0;
        }
        else {
            secs = max_secs;
            rval = seconds - max_secs;
        }
    
        /* must use 64-bit math to compute tick value */
        ticks = ((uint64_t)secs * 1000000L) / (uint64_t)Clock_tickPeriod;
    
        /* must add one tick to ensure a full duration of requested ticks */
        Task_sleep((UInt32)(ticks + 1));
    
        return (rval);
    }

    Regards,

    Alberto

  • Hi Alberto,

    Sorry for the bad explanation. I will try to improve it.
    Calling sleep(3600); will block the calling task for 1 hour. If all other tasks (except the idle task) are also blocked, the idle task task will execute. With the default configuration of most of our examples, the idle function will call Power_idleFunc() which will call PowerCC26XX_standbyPolicy(). It is in this function Power_sleep() will be called, if the necessary conditions are met.

    So you can check the following two things:

    1. Verify that the idle task is actually running (verify that all task are blocked)
    2. If the idle task is running, verify that it calls Power_idleFunc() and check if Power_sleep() is called or not.

    However, if you are not able to debug this on the boards are actually failing to enter standby then it could be difficult to debug.

    Regards,
    Nikolaj

  • Hi Nikolaj,

    How can I check if a task is blocked or not? I can't debug the boards but I'm trying to debug on launchpad just in case. Debugging on the launchpad, I only can see that program stops at Task_sleep((UInt32)(ticks + 1)) for 1 hour in the piece of code I attached.

    As boards send data, I checked  the data received and I saw one of the data is not updated. This data is increased each time a packet is sent, but I see it's not increased. I think maybe the board is resetting each time a cycle is runned, that's why this data is not updated. 

    Regards,
    Alberto

  • Hi Alberto,

    You can use the Runtime Object View (ROV) to see which task is active task: https://software-dl.ti.com/ccs/esd/documents/rov_guide/html/src/rov.html

    By the way, why can't you debug your application on the custom board? If you were able to export the memory using UniFlash, then I would expect that you should be able to debug the application as well.

    Below is an interesting observation! When you say that you think maybe the the board is resetting each cycle, what exactly are you referring to? Each time sleep is called or each time the packet is sent? How often is a packet being sent from the "faulty" devices? Is it still once every 12 hours?

    As boards send data, I checked  the data received and I saw one of the data is not updated. This data is increased each time a packet is sent, but I see it's not increased. I think maybe the board is resetting each time a cycle is runned, that's why this data is not updated. 

    Regards,
    Nikolaj

  • Hi Nikolaj,

    When I try to debug my custom boards, I get the following errors:

    Below is an interesting observation! When you say that you think maybe the the board is resetting each cycle, what exactly are you referring to? Each time sleep is called or each time the packet is sent? How often is a packet being sent from the "faulty" devices? Is it still once every 12 hours?

    I double checked this and packets are set correclty. Updates are succesful, so we didn't find the error...

    I checked which task is active with ROV and I see the main thread where data is sent is blocked.

    Regards,
    Alberto

  • Hi Alberto,

    It looks like you added the wrong screenshot for the error message.

    Regards,
    Nikolaj

  • Hi Nikolaj,

    Sorry, that's the error message.

  • Hello again,

    Even though I can't debug custom boards, I could use ROV and I saw some differences in Tasks tab compared to launchpad.

    That's the tab task corresponding to custom board.

    Regards,
    Alberto

  • Hi Alberto,

    I think the problem you are seeing when trying to debug the custom board occurs sometime during the execution of the application. It would be useful to know when that is.

    Can you try to do the following and let me know when you experience the debug issue you have reported:

    1. Start a project-less debug session as described here: https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html#manual-launch 
    2. Before connecting to the target, issue a board reset. This should make the target halt in boot.
    3. Connect to the target
    4. Load ROM symbols
    5. Verify that the target is halted in boot. If you open the disassembly view you should see that the target is halted at the WaitHibProdNext symbol
    6.  Add application symbols. Run -> Load -> Add Symbols... -> Browse for the .out file of your project.
    7. Now you should be able to step through the application and you should be able to figure out when the issue occurs.

    Thanks,
    Nikolaj

  • Hi Nikolaj,

    Thanks a lot for your detailed help. To be able to start a project-less debug session the target should be connected, is it correct? In addition, in step 2 Board Reset is not available.

    Regards,
    Alberto

  • After starting a project-less debug session, the target will not be connected (the debug probe should of course be physically connected to the device), and you should not connect to it before issuing the board reset.
    In step 1. the only thing you should do is "Right-click on the desired target configuration file and select Launch Selected Configuration."

  • Hi Nikolaj,

    I did the 3 first seps: without connecting target (Only debug probe of launchpad), launched selected configuration; Board Reset; Connect the custom board. When I do step 4th, I get the following error:

    Cortex_M3_0: GEL Output: No symbols loaded (not connected to target).

  • Update: I flashed pinStandby project on my custom board and current consumption is even worse, consumming about 4 mA.

  • Connect the custom board

    Are you referring to connecting the debug probe to the custom board or clicking the connect button in CCS? (see below)
    The board should be physically connected to debug probe throughout all of the steps I have mentioned above. In step 4, you should just click "Connect Target" as shown below?

    Regards,
    Nikolaj

  • Hi Nikolaj,

    Thanks, I misunderstood it, now I'm able to debug the application through disassembly view only. When debugging it, it stops after executing 3 instructions:

    On the other side, debugging the custom board that works fine, it stops here:

    Comparing both (I don't know so much about disassembly), it seems like good board skips 6020 instruction and recognize "Enter Flash" instruction, whereas the bad one no. Anyway, our custom board don't have Flash memory. I also tried it on launchpad and the behaviour is same.

    I attach the schematics of our board.

     EsquemaGuardián_2v0.pdf

    Regards,
    Alberto

  • Hi Alberto,

    What do you mean with "it stops after executing 3 instructions"? How does it stop?
    Also, when stepping through the disassembly, can you please use the "Assembly Step Into" as highlighted below. 

    Thanks,
    Nikolaj

  • Hi Nikolaj,

    What do you mean with "it stops after executing 3 instructions"? How does it stop?

    It is just paused and I can't continue stepping through the disassembly.

    Also, when stepping through the disassembly, can you please use the "Assembly Step Into" as highlighted below. 

    I was debugging using "Step Over", thanks. Debugging using "Assembly Step", program is continuously inside a for loop and doesn't exit.

    The loop is located in "copy_decompress_lzss.c" file. It is located at C:\ti\ccs1110\ccs\tools\compiler\ti-cgt-atm_20.2.6.LTS\lib\src\

    /*****************************************************************************/
    /* copy_decompress_lzss.c                                                    */
    /*                                                                           */
    /* Copyright (c) 2006 Texas Instruments Incorporated                         */
    /* http://www.ti.com/                                                        */
    /*                                                                           */
    /*  Redistribution and  use in source  and binary forms, with  or without    */
    /*  modification,  are permitted provided  that the  following conditions    */
    /*  are met:                                                                 */
    /*                                                                           */
    /*     Redistributions  of source  code must  retain the  above copyright    */
    /*     notice, this list of conditions and the following disclaimer.         */
    /*                                                                           */
    /*     Redistributions in binary form  must reproduce the above copyright    */
    /*     notice, this  list of conditions  and the following  disclaimer in    */
    /*     the  documentation  and/or   other  materials  provided  with  the    */
    /*     distribution.                                                         */
    /*                                                                           */
    /*     Neither the  name of Texas Instruments Incorporated  nor the names    */
    /*     of its  contributors may  be used to  endorse or  promote products    */
    /*     derived  from   this  software  without   specific  prior  written    */
    /*     permission.                                                           */
    /*                                                                           */
    /*  THIS SOFTWARE  IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS    */
    /*  "AS IS"  AND ANY  EXPRESS OR IMPLIED  WARRANTIES, INCLUDING,  BUT NOT    */
    /*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR    */
    /*  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT    */
    /*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
    /*  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL  DAMAGES  (INCLUDING, BUT  NOT    */
    /*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,    */
    /*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY    */
    /*  THEORY OF  LIABILITY, WHETHER IN CONTRACT, STRICT  LIABILITY, OR TORT    */
    /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE    */
    /*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     */
    /*                                                                           */
    /*                                                                           */
    /* Decompress routine for Lempel-Ziv-Storer-Szymanski (LZSS) compression.    */
    /* Given an input buffer with data compressed using LZSS encoding and an     */
    /* output buffer, this routine decompresses the data in the output buffer.   */
    /*                                                                           */
    /* NOTE:                                                                     */
    /* 1. This routine could be used to copy uninitialized or initialized global */
    /*    data space of a program. Hence this routine cannot define any global   */
    /*    variable.                                                              */
    /* 2. This routine will never be used to initialize stack space and hence    */
    /*    all the variables are allocated to stack.                              */
    /* 3. The calling application should ensure the output buffer is big         */
    /*    enough to hold the uncompressed data.                                  */
    /*                                                                           */
    /*****************************************************************************/
    #include <stdint.h>
    #include <limits.h>
    
    #define LZSS_EOD             4095
    #define LZSS_WINDOW_SIZE     4095
    
    /*****************************************************************************/
    /* The offset is always 12-bits so use a 16-bit type.                        */
    /*****************************************************************************/
    typedef uint_fast16_t offset_t;
    
    #if CHAR_BIT == 8
    
    /*****************************************************************************/
    /* The max length is 2^15-1+18, which can fit in a 16-bit type.              */
    /*****************************************************************************/
    typedef uint_fast16_t length_t;
    
    /*****************************************************************************/
    /* Flags is always of length 1 char.                                         */
    /*****************************************************************************/
    typedef uint_fast8_t  flags_t;
    
    #elif CHAR_BIT == 16
    
    /*****************************************************************************/
    /* The max length =s 2^16-1+17, which may not fit in a 16-bit type, so use a */
    /* 32-bit type.                                                              */
    /*****************************************************************************/
    typedef uint_fast32_t length_t;
    
    /*****************************************************************************/
    /* Flags is always of length 1 char.                                         */
    /*****************************************************************************/
    typedef uint_fast16_t flags_t;
    
    #else
    #error Illegal value for CHAR_BIT
    #endif
    
    /*****************************************************************************/
    /* MSP copy tables can handle moving functions even in small data model +    */
    /* large code model, where data pointers are not big enough to represent     */
    /* function pointers.  This requires the EABI decompression functions        */
    /* (SHARED/copy_*.c) to be changed to accept "far" pointers.  For this       */
    /* memory model combination, the decompression functions are changed to use  */
    /* "unsigned long" to represent function pointers, so function pointers      */
    /* through which we call these functions also needs to have a prototype      */
    /* accepting "unsigned long" instead of pointer types.  All other memory     */
    /* model combinations use the same prototype that all the other targets use: */
    /* two data pointer arguments.  Ultimately we use MSP peek/poke intrinsics   */
    /* to read/write the "far" memory.                                           */
    /*****************************************************************************/
    #if defined(__MSP430__) && defined(__LARGE_CODE_MODEL__) && !defined(__LARGE_DATA_MODEL__)
    typedef unsigned long pointer_t;
    typedef unsigned long pointer_to_const_t;
    #define READ_CHAR_ADV(x)     __data20_read_char(x++)
    #define WRITE_CHAR_ADV(x, c) __data20_write_char(x++, c)
    #else
    typedef       unsigned char *pointer_t;
    typedef const unsigned char *pointer_to_const_t;
    #define READ_CHAR_ADV(x)    (*x++)
    #define WRITE_CHAR_ADV(x,c) (*x++ = (c))
    #endif
    
    /*****************************************************************************/
    /*                                                                           */
    /* __TI_DECOMPRESS_LZSS() - Decompress data encoded using LZSS encoding.     */
    /*                          Input buffer (inbuf) has the encoded data and    */
    /*                          uncompressed data is returned in outbuf.         */
    /*                                                                           */
    /*****************************************************************************/
    __attribute__((section(".text:decompress:lzss")))
    void __TI_decompress_lzss(pointer_to_const_t inbuf, pointer_t outbuf)
    {
        while (1)
        {
            flags_t flags = READ_CHAR_ADV(inbuf);
    
            int i;
            for (i=0; i<CHAR_BIT ; i++)
            {
               if (flags & 0x1)
               {
                  /*---------------------------------------------------------------*/
                  /* We have an uncoded byte, just write it out.                   */
                  /*---------------------------------------------------------------*/
                  WRITE_CHAR_ADV(outbuf, READ_CHAR_ADV(inbuf));
               }
               else
               {
                  /*---------------------------------------------------------------*/
                  /* Read and unpack the offset and length                         */
                  /*---------------------------------------------------------------*/              
                  offset_t offset;
                  length_t length;
                  
    #if CHAR_BIT == 8
                  offset = READ_CHAR_ADV(inbuf);
                  length = READ_CHAR_ADV(inbuf);
                  offset <<= 4;
                  offset |= ((length & 0x00F0) >> 4);
                  length = (length & 0x000F) + 3;
    
                  /*---------------------------------------------------------------*/
                  /* If the length is 3->17, we only use 4 bits. If the length is  */
                  /* >= 18, we read an additional 8 bits and add it to the length. */
                  /*                                                               */
                  /* If the msb of the second byte is 1, we read an additional     */
                  /* 8 bits and use that for bits 7-14 of the length. This gives   */
                  /* us a range of 3->32785.                                       */
                  /*---------------------------------------------------------------*/
                  if (length == 18)
                  {
                     length_t length2 = READ_CHAR_ADV(inbuf);
                     if (length2 & 0x80)
                     {
                        length_t length3 = READ_CHAR_ADV(inbuf);
                        length2 = (length2 & 0x7f) | (length3 << 7);
                     }
                     length += length2;
                  }
                  
    #elif CHAR_BIT == 16
                  unsigned char temp = READ_CHAR_ADV(inbuf);
                  length = (temp & 0xf) + 2;
                  offset = temp >> 4;
    
                  /*---------------------------------------------------------------*/
                  /* If the length is the maximum value encoded in 4 bits, read an */
                  /* additional 16-bit value and add it to the length.             */
                  /*---------------------------------------------------------------*/              
                  if (length == 17)
                     length += READ_CHAR_ADV(inbuf);
    #endif
    
                  /*---------------------------------------------------------------*/
                  /* If the offset indicates end of data, exit.                    */
                  /*---------------------------------------------------------------*/
                  if (offset == LZSS_EOD)
                     return;                           
    
                  /*---------------------------------------------------------------*/
                  /* Copy the decoded string from sliding window to output buffer. */
                  /*---------------------------------------------------------------*/
                  length_t j;
                  pointer_t pos = outbuf - offset - 1;
                  for (j = 0; j < length; j++)
                     WRITE_CHAR_ADV(outbuf, READ_CHAR_ADV(pos));
               }
    
               flags >>= 1;
            }
        }
    }
    
    
    

    I have been continuously stepping into this loop for over 5 minutes, the lenght of for loop seems to be too high (984). Is it normal?

    Thanks,
    Alberto

  • I was able to continue after finishing the for loop but the program is always inside the while loop in the __TI_decompress_lzss() function at the file I attached before, I don't know if at any moment it would finish because I have been stepping into fastly for more than 30 minutes.

  • Hi Nikolaj,

    I have been talking with one of your mates, asking if it would be possible to have a meeting in order to solve the issue earlier, as this work is inside a project which deadline is very close. If so, you can contact me through my corporate email: aaguayo@metrica6.es

    Thanks,
    Alberto