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.

Compiler/CC2640R2F: using #pragma pack(1) on structure stop a task working properly.

Part Number: CC2640R2F
Other Parts Discussed in Thread: LAUNCHXL-CC2640R2

Tool/software: TI C/C++ Compiler

Hi team

It looks like the way I use #pragma pack(n) to reduce size of my structures can some how cause a task stopped a task working properly. I am pretty sure it's not stack of heap problem. A full minimal repeatable example is also attached.

And also, there is no compiler error. My attached example is tested on:

board: LAUNCHXL-CC2640R2

Code Composer Studio
Version: 9.3.0.00012

OS: Windows 10, v.10.0, x86_64 / win32
Java version: 1.8.0_144

Compiler ver: TI v18.12.4.TLS

Here is my main.c

int main()
{
    /* Call driver init functions */
    Board_init();

    inputs_task_init();

    BIOS_start();
    return(0);
}

Here is my inputs_api.h

/*
 * inputs_api.h
 *
 *  Created on: Jan 10, 2020
 *      Author: James Wu
 */

#ifndef INPUTS_INPUTS_API_H_
#define INPUTS_INPUTS_API_H_

#include <stdint.h>

/*! \brief  Data structure for device information
 */
#pragma pack (1)     //// <<<< having this seems to cause my task stopped working >>>>
typedef struct CAPSENSE_DEV_INFO{
    uint8_t family_id;
    uint16_t device_id;
    uint16_t device_revision;
}capsense_dev_info_t;

/*! \brief  Total working sensor
 */
#pragma pack (1)     //// <<<< having this seems to cause my task stopped working >>>>
typedef union CAPSENSE_TOTAL_WORKING_SNS{
    struct{
        uint8_t sensor_count    : 5;    /* Number of sensors that passed system diagnostic test */
        uint8_t reversed        : 2;    /* reserved                                             */
        uint8_t sysd_err        : 1;    /* Indicator of whether any errors were detected during
                                         * system diagnostic test
                                         */
    }bits;
    uint8_t data;
}capsense_total_working_sns_t;

/*! \brief  Device sensor information
 */
typedef union CAPSENSE_SENSOR_INFO{
    struct{
        uint16_t cs0    : 1;
        uint16_t cs1    : 1;
        uint16_t cs2    : 1;
        uint16_t cs3    : 1;
        uint16_t cs4    : 1;
        uint16_t cs5    : 1;
        uint16_t cs6    : 1;
        uint16_t cs7    : 1;
        uint16_t cs8    : 1;
        uint16_t cs9    : 1;
        uint16_t cs10   : 1;
        uint16_t cs11   : 1;
        uint16_t cs12   : 1;
        uint16_t cs13   : 1;
        uint16_t cs14   : 1;
        uint16_t cs15   : 1;
    }bits;
    uint8_t data[2];
}capsense_sensor_info_t;


/*! Initial input task
 */
void inputs_task_init(void);




#endif /* INPUTS_INPUTS_API_H_ */

Here is my inputs_api.c file

/*
 * inputs_api.c
 *
 *  Created on: Jan 10, 2020
 *      Author: James Wu
 */


#include "inputs_api.h"

/* XDC Module Headers */
#include <xdc/std.h>
#include <xdc/runtime/System.h>

/* BIOS Module Headers */
#include <ti/sysbios/BIOS.h>

#include <ti/sysbios/knl/Task.h>
//#include <ti/drivers/PIN.h>
#include <ti/drivers/I2C.h>

//#include <string.h>

/* task stuff */
static Task_Params task_params;
static uint8_t stack[1024];
Task_Struct taskInputsStruct;
void taskInputs(UArg arg0, UArg arg1);

/* constants */
const unsigned DELAY_1MS = 100;

void inputs_task_init(void){

    /* setup task */
    Task_Params_init(&task_params);
    task_params.priority = 1;
    task_params.stack = stack;
    task_params.stackSize = 1024;

    Task_construct(&taskInputsStruct, taskInputs, &task_params, NULL);

    System_printf("Starting Input scan task...\n");
    System_printf("size = %d, %d\n", sizeof(capsense_dev_info_t), sizeof(capsense_total_working_sns_t));
    System_flush();
}

void taskInputs(UArg arg0, UArg arg1){




    /* setup I2C */
    I2C_Params i2cparams;
    I2C_Params_init(&i2cparams);

    /* test code */
    capsense_sensor_info_t sensor;
    sensor.data[0] = 1;
    sensor.data[1] = 2;

    System_flush();

    while(1){
        Task_sleep(DELAY_1MS * 100);
        System_printf("Running...\n");
        System_flush();
    }
}

hello_CC2640R2_LAUNCHXL_tirtos_ccs.zip

  • Hi Zhuhua,

    The problem is that you have packed everything because you did not have a #pragma pack() after the capsense_total_working_sns_t. So the I2C_Params local variable was getting packed also and causing an misaligned exception. This became apparent once I moved to the debug kernel (refer to the SimpleLink SDK User Guide for details on how to move to the debug kernel). 

    So try this instead and see if that fixes the problem:

    #pragma pack (1)     //// <<<< having this seems to cause my task stopped working >>>>
    typedef struct CAPSENSE_DEV_INFO{
        uint8_t family_id;
        uint16_t device_id;
        uint16_t device_revision;
    }capsense_dev_info_t;
    
    /*! \brief  Total working sensor
     */
    
    typedef union CAPSENSE_TOTAL_WORKING_SNS{
        struct{
            uint8_t sensor_count    : 5;    /* Number of sensors that passed system diagnostic test */
            uint8_t reversed        : 2;    /* reserved                                             */
            uint8_t sysd_err        : 1;    /* Indicator of whether any errors were detected during
                                             * system diagnostic test
                                             */
        }bits;
        uint8_t data;
    }capsense_total_working_sns_t;
    #pragma pack()

    You might want to look at __attribute__((packed)) as another option. This is supported on several different compilers.

    Todd

  • Hi Todd

    Thanks for your reply, so do you mean I should use #pragma pack like this instead:

    /*! If I need to pack struct A, B and C,
     *  Do I need to wrap them up between
     *  #pragma pack(n) and #pragma pack() ?
     */
    
    #pragma pack(1)
    
    typedef struct A{
      // some members
    }a_t;
    
    typedef struct B{
      // some members
    }b_t;
    
    typedef struct C{
      // some members
    }c_t;
    
    #pragma pack()
    
    

    Also thanks for the suggestion for  __attribute__((packed))

  • Zhuhua Wu said:
    do you mean I should use #pragma pack like this instead

    Yes.

  • Thanks Tod, appreciate it!