Hot!sizeof not function with PIC24

Page: 12 > Showing page 1 of 2
Author
IvanP
Starting Member
  • Total Posts : 45
  • Reward points : 0
  • Joined: 2014/11/14 05:00:13
  • Location: 0
  • Status: offline
2018/01/30 08:09:25 (permalink)
0

sizeof not function with PIC24

I generated a simple code with pic24 (pic24FJ256GB410) and the "sizeof" not function.
In this examlpe "SizeNum" is 6 and not 5, why?
 
 
 
#include "mcc_generated_files/mcc.h"



struct _eeprom {
  uint8_t AddH;
  uint8_t Dato1;
  uint8_t Dato2;
  uint16_t Dato3;

};
struct _eeprom ParEEPROM; //reserve place in RAM

uint16_t SizeNum;
/*
                         Main application
 */
int main(void)
{
    // initialize the device
    SYSTEM_Initialize();

    while (1)
    {
        // Add your application code
        SizeNum = sizeof(ParEEPROM);
    }

    return -1;
}
/**
 End of File
*/

#1

25 Replies Related Threads

    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 1916
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: online
    Re: sizeof not function with PIC24 2018/01/30 08:23:30 (permalink)
    0
    Account for padding to make addresses even.

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #2
    rodims
    Super Member
    • Total Posts : 1071
    • Reward points : 0
    • Joined: 2009/02/10 11:08:59
    • Location: 51.9627, 7.6262
    • Status: online
    Re: sizeof not function with PIC24 2018/01/30 08:24:05 (permalink)
    4 (1)
    What is a sizeof not function ?
     
    The first 3 uint_8 will each have one byte.
    Then the compiler will insert one filler byte, so he can ensure that the uint16_6 variable starts on a WORD boundary (16 bit boundary). This is a requirement for the PIC24 word access.
    If you don't want to have that, put the Dato3 at the begginng.
    Or google for packed structure.
    Or possibly add the filler byte yourself, just to make visible that there is one more byte.
    #3
    IvanP
    Starting Member
    • Total Posts : 45
    • Reward points : 0
    • Joined: 2014/11/14 05:00:13
    • Location: 0
    • Status: offline
    Re: sizeof not function with PIC24 2018/01/30 08:57:23 (permalink)
    0
    struct _eeprom { 
    uint16_t Dato3;
    uint8_t AddH;
    uint8_t Dato1;
    uint8_t Dato2;
    };
    struct _eeprom ParEEPROM; 
     
    Same result, SizeNum = 6 byte. 
    #4
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 1916
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: online
    Re: sizeof not function with PIC24 2018/01/30 09:05:56 (permalink)
    0
    I explained that in post #2.
     
    The compiler will align to 16bit.
     
    Other chips can read 16bit starting from odd addresses but the 16bit Microchip mpus cannot.
    post edited by Gort2015 - 2018/01/30 09:08:02

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #5
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 1916
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: online
    Re: sizeof not function with PIC24 2018/01/30 09:15:52 (permalink)
    0
    struct _eeprom ParEEPROM;
    int x;
     
    0x1000 ParEEPROM
    0x1006 X

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #6
    NKurzman
    A Guy on the Net
    • Total Posts : 15517
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: sizeof not function with PIC24 2018/01/30 09:22:55 (permalink)
    4 (2)
    If you need it to be 5 then look up "Structure packing".  Note that it may make the code less efficient.
    #7
    rodims
    Super Member
    • Total Posts : 1071
    • Reward points : 0
    • Joined: 2009/02/10 11:08:59
    • Location: 51.9627, 7.6262
    • Status: online
    Re: sizeof not function with PIC24 2018/01/30 09:27:18 (permalink)
    4 (1)
    IvanP
    struct _eeprom { 
    uint16_t Dato3;
    uint8_t AddH;
    uint8_t Dato1;
    uint8_t Dato2;
    };
    struct _eeprom ParEEPROM; 

     
    while the above fulfills the alignment requirements for the 16 bit MPUs, it indeed gives the same result, size = 6 byte, which I did not expect.
     
     
    The following will shrink it to 5 byte (XC16 1.33)
     
    struct  __attribute__ ((packed)) _eeprom { 
    uint16_t Dato3;
    uint8_t AddH;
    uint8_t Dato1;
    uint8_t Dato2;
    };
    struct _eeprom ParEEPROM;

     
    but be careful, if you would use an array of that structure.
    Keep in mind, the reason is that the 16 bit CPUs can only access 16 bit values with their 16-bit Ops, if they are aligned on WORD boundaries (or even addresses). Otherwise you will get a TRAP. So for your case, I would just live with that extra byte, no reason to worry.
     
    [edit: and DO NOT use packed, if you do not take care of the alignment yourself !]
    post edited by rodims - 2018/01/30 10:37:46
    #8
    IvanP
    Starting Member
    • Total Posts : 45
    • Reward points : 0
    • Joined: 2014/11/14 05:00:13
    • Location: 0
    • Status: offline
    Re: sizeof not function with PIC24 2018/01/30 09:56:55 (permalink)
    0
    Thank you very much
    #9
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 1916
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: online
    Re: sizeof not function with PIC24 2018/01/30 10:08:30 (permalink)
    5 (1)
    The only reason to use packed if using a structure like fat16 or fat32 where some structure elements  are not on an even boundry.
     
    0x1001 low X
    0x1002 high X
    0x1003
     
    non aligned packed:
    mov.b [ptr+1],data  ;high
    swap data
    mov.b [ptr+0],data ;low
     
    aligned:
    mov [ptr],data
     
     

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #10
    andersm
    Super Member
    • Total Posts : 2333
    • Reward points : 0
    • Joined: 2012/10/07 14:57:44
    • Location: 0
    • Status: offline
    Re: sizeof not function with PIC24 2018/01/30 10:10:25 (permalink)
    4 (1)
    rodimswhile the above fulfills the alignment requirements for the 16 bit MPUs, it indeed gives the same result, size = 6 byte, which I did not expect.

    If you create an array of structs, each element of the array must have correct alignment. Therefore the struct will always contain one byte of padding.
    #11
    rodims
    Super Member
    • Total Posts : 1071
    • Reward points : 0
    • Joined: 2009/02/10 11:08:59
    • Location: 51.9627, 7.6262
    • Status: online
    Re: sizeof not function with PIC24 2018/01/30 10:30:50 (permalink)
    0
    For completeness, I just verified what XC 16 does:
     
    If you use your original structure without packed attribute, no additional alignment code will be generated, the structure size is 6. As said, usually this should not be any problem.
     
    If you use your original structure, but with packed attribute, then the compiler will take care of the alignment. However as Neil said, this creates more code (taking place and execution time).
     
    If you use my modifed structure with the packed attribute (i.e. you ensure yourself that each 16 bit value starts on a WORD boundary), then you make it easier for the compiler and it also generates no additional code for the alignment.
     
    #12
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 1916
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: online
    Re: sizeof not function with PIC24 2018/01/31 16:31:51 (permalink)
    0
    Use offsetof to see the relative positions of each element of your structure.
     
    x=offsetof(_eeprom, AddH);

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #13
    IvanP
    Starting Member
    • Total Posts : 45
    • Reward points : 0
    • Joined: 2014/11/14 05:00:13
    • Location: 0
    • Status: offline
    Re: sizeof not function with PIC24 2018/02/13 01:26:48 (permalink)
    0
     
     
    #14
    IvanP
    Starting Member
    • Total Posts : 45
    • Reward points : 0
    • Joined: 2014/11/14 05:00:13
    • Location: 0
    • Status: offline
    Re: sizeof not function with PIC24 2018/02/13 01:44:53 (permalink)
    0
    Goodmorning,
    I use this structure for memory many parameters in external EEPROM.
    The solution with "struct __attribute__ ((packed))" function correctly and i recovery all data.
    I use Microchip library and it is all OK.
    But, when i use a pointer for manage one parameter (in thi case ParamEEPROM.Decimale) i have "TRAPS_halt_on_error" in "__DEBUG" mde.
    I program the PIC24 but not function, micro loop in reset.
    If i move "ParamEEPROM.Decimale" in other position function correctly
    Why?
     


     
     
     
     
     
     
     
    //Ciclo MACININO VOL.
    typedef struct __attribute__ ((packed)) _ciclo01{
    uint16_t Volume;
    }_ciclo01;
    //Ciclo MACININO a tempo
    typedef struct __attribute__ ((packed)) _ciclo02{
    uint16_t Tempo;
    }_ciclo02;
    //ESPRESSO
    typedef struct __attribute__ ((packed)) _ciclo03{
    uint16_t Acqua;
    }_ciclo03;
    //SOLUBILE 1 VOLUM
    typedef struct __attribute__ ((packed)) _ciclo04{
    uint16_t Polvere;
    uint16_t Acqua;
    }_ciclo04;
    //SOLUBILE 1 TEMPO
    typedef struct __attribute__ ((packed)) _ciclo05{
    uint16_t Polvere;
    uint16_t Acqua;
    }_ciclo05;
    //SOLUBILE 2 VOLUM
    typedef struct __attribute__ ((packed)) _ciclo06{
    uint16_t Polvere;
    uint16_t Acqua;
    }_ciclo06;
    //SOLUBILE 2 TEMPO
    typedef struct __attribute__ ((packed)) _ciclo07{
    uint16_t Polvere;
    uint16_t Acqua;
    }_ciclo0;
    //ACQUA CALDA VOL.
    typedef struct __attribute__ ((packed)) _ciclo08{
    uint16_t Acqua;
    }_ciclo08;
    //ACQUA CALDA TEMPO
    typedef struct __attribute__ ((packed)) _ciclo09{
    uint16_t Acqua;
    }_ciclo09;
    //PAUSA1
    typedef struct __attribute__ ((packed)) _ciclo10{
    uint16_t Tempo;
    }_ciclo10;
    //PAUSA2
    typedef struct __attribute__ ((packed)) _ciclo11{
    uint16_t Tempo;
    }_ciclo11;
    //PAUSA3
    typedef struct __attribute__ ((packed)) _ciclo12{
    uint16_t Tempo;
    }_ciclo12;
    //PAUSA4
    typedef struct __attribute__ ((packed)) _ciclo13{
    uint16_t Tempo;
    }_ciclo13;
    //DECOUNTER 1
    typedef struct __attribute__ ((packed)) _ciclo14{
    uint16_t NumDecounter;
    }_ciclo14;
    //DECOUNTER 2
    typedef struct __attribute__ ((packed)) _ciclo15{
    uint16_t NumDecounter;
    }_ciclo15;
     
     
     
    struct __attribute__ ((packed)) _cicli{
    struct _ciclo01 c01;
    struct _ciclo02 c02;
    struct _ciclo03 c03;
    struct _ciclo04 c04;
    struct _ciclo05 c05;
    struct _ciclo06 c06;
    struct _ciclo07 c07;
    struct _ciclo08 c08;
    struct _ciclo09 c09;
    struct _ciclo10 c10;
    struct _ciclo11 c11;
    struct _ciclo12 c12;
    struct _ciclo13 c13;
    struct _ciclo14 c14;
    struct _ciclo15 c15;

    };
     
     
     

    struct __attribute__ ((packed)) _storico{
    uint16_t id;
    uint16_t esito;
    };
    extern struct _storico storico[101];
     
     
     

    // ***** area parametri da salvare in EEPROM *****
    struct __attribute__ ((packed)) structEEPROM {
    uint8_t AddH; //contiene l'indirizzo di partenza per la lettura/scrittura in EEPROM
    uint8_t AddL; //contiene l'indirizzo di partenza per la lettura/scrittura in EEPROM
    uint8_t nul0; //byte di partenza per la lettura (deve essere a 8 bit)-> vedi funzione I2C
    uint8_t all_1;
    uint16_t Dato1;
    uint16_t Dato2;
    uint16_t Dato3;
    uint8_t Dato4;
    uint16_t PrezzoP0;
    uint16_t PrezzoP1;
    uint16_t PrezzoP2;
    uint16_t PrezzoP3;
    uint16_t PrezzoP4;
    uint16_t PrezzoP5;
    uint16_t PrezzoP6;
    uint16_t PrezzoP7;
    uint16_t PrezzoP8;
    uint16_t PrezzoP9;
    uint32_t MoneyTotUltIncassoBattute;
    uint32_t PzTotUltIncassoBattute;
    uint32_t moneyTotModTest;
    uint32_t PzTotModTest;
    uint32_t MoneyBatPerditaGratis;
    uint32_t PzBatPerditaGratis;
    uint16_t Decimale;
    // uint8_t VendSingNoResto;
    uint8_t all_2;
    uint8_t ProssimoIndStorico;
    struct _storico storico[101];
    char NomeValuta[16];
    struct _bevanda Bevanda[8];
    uint8_t checksum ;
    };
    extern struct structEEPROM ParamEEPROM;
     
     
     

     
    This solution function
     

     
     
     
    // ***** area parametri da salvare in EEPROM *****
    struct __attribute__ ((packed)) structEEPROM {
    uint8_t AddH; //contiene l'indirizzo di partenza per la lettura/scrittura in EEPROM
    uint8_t AddL; //contiene l'indirizzo di partenza per la lettura/scrittura in EEPROM
    uint8_t nul0; //byte di partenza per la lettura (deve essere a 8 bit)-> vedi funzione I2C
    uint8_t all_1;
    uint16_t Decimale;
    uint16_t Dato1;
    uint16_t Dato2;
    uint16_t Dato3;
    uint8_t Dato4;
    uint16_t PrezzoP0;
    uint16_t PrezzoP1;
    uint16_t PrezzoP2;
    uint16_t PrezzoP3;
    uint16_t PrezzoP4;
    uint16_t PrezzoP5;
    uint16_t PrezzoP6;
    uint16_t PrezzoP7;
    uint16_t PrezzoP8;
    uint16_t PrezzoP9;
    uint32_t MoneyTotUltIncassoBattute;
    uint32_t PzTotUltIncassoBattute;
    uint32_t moneyTotModTest;
    uint32_t PzTotModTest;
    uint32_t MoneyBatPerditaGratis;
    uint32_t PzBatPerditaGratis;

    // uint8_t VendSingNoResto;
    uint8_t all_2;
    uint8_t ProssimoIndStorico;
    struct _storico storico[101];
    char NomeValuta[16];
    struct _bevanda Bevanda[8];
    uint8_t checksum ;
    };
    extern struct structEEPROM ParamEEPROM;
     
     
     

     
    I use "Moddato(&ParamEEPROM.Decimale,2,0,STEP,&sys,1)" and this function for change me parameter:
     

     
    //****************************************
    //* Routine Moddato *
    //****************************************

    void Moddato (unsigned int *Dato, unsigned int MaxVal, unsigned int MinVal, unsigned int NDelta, struct s_system *dati,uint8_t tasti)
    {
     
    static uint8_t Exe_Inc = 0;
    static uint8_t Exe_Dec = 0;
    static uint8_t PulsPiu, PulsMeno = 0;


    //modifica il parametro con K1 e K5
    if (tasti == 0 && sys.PulsK5_giu == PREMUTO){
    PulsPiu = PREMUTO;
    }
    if (tasti == 0 && sys.PulsK5_giu == NON_PREMUTO){
    PulsPiu = NON_PREMUTO;
    }

    if (tasti == 0 && sys.PulsK1_su == PREMUTO){
    PulsMeno = PREMUTO;
    }
    if (tasti == 0 && sys.PulsK1_su == NON_PREMUTO){
    PulsMeno = NON_PREMUTO;
    }

    //modifica il parametro con K2 e K6
    if (tasti == 1 && sys.PulsK6_piu == PREMUTO){
    PulsPiu = PREMUTO;
    }
    if (tasti == 1 && sys.PulsK6_piu == NON_PREMUTO){
    PulsPiu = NON_PREMUTO;
    }

    if (tasti == 1 && sys.PulsK2_meno == PREMUTO){
    PulsMeno = PREMUTO;
    }
    if (tasti == 1 && sys.PulsK2_meno == NON_PREMUTO){
    PulsMeno = NON_PREMUTO;
    }

    //modifica il parametro con K3 e K7
    if (tasti == 2 && sys.PulsK7_dx == PREMUTO){
    PulsPiu = PREMUTO;
    }
    if (tasti == 2 && sys.PulsK7_dx == NON_PREMUTO){
    PulsPiu = NON_PREMUTO;
    }

    if (tasti == 2 && sys.PulsK3_sx == PREMUTO){
    PulsMeno = PREMUTO;
    }
    if (tasti == 2 && sys.PulsK3_sx == NON_PREMUTO){
    PulsMeno = NON_PREMUTO;
    }


    if (PulsPiu == PREMUTO) {
    if (T_ChangeIncSpeed <= 130) {
    if (T_Varia == 0) {
    Exe_Inc = 0;
    }
    }
    if (!Exe_Inc) {
    Exe_Inc = 1;
    if ((T_ChangeIncSpeed >= 80) && (T_ChangeIncSpeed <= 130)) {
    T_Varia = 5;
    }
    if ((T_ChangeIncSpeed >= 20) && (T_ChangeIncSpeed <= 80)) {
    T_Varia = 2;
    }
    if (T_ChangeIncSpeed < 20) {
    T_Varia = 1;
    }

    *Dato = *Dato + NDelta;
    if (*Dato > MaxVal) {
    *Dato = MaxVal;
    }


    }
    } else {
    Exe_Inc = 0;
    T_ChangeIncSpeed = 150;
    }
     

    if ((PulsMeno) == PREMUTO) {
    if (T_ChangeDecSpeed <= 130) {
    if (T_Varia == 0) {
    Exe_Dec = 0;
    }
    }
    if (!Exe_Dec) {
    Exe_Dec = 1;
    if ((T_ChangeDecSpeed >= 80) && (T_ChangeDecSpeed <= 130)) {
    T_Varia = 5;
    }
    if ((T_ChangeDecSpeed >= 20) && (T_ChangeDecSpeed <= 80)) {
    T_Varia = 3;
    }
    if (T_ChangeDecSpeed < 20) {
    T_Varia = 1;
    }


    if (*Dato != 0){
    *Dato = *Dato - NDelta;
    }
    if (*Dato <= MinVal ){
    *Dato = MinVal;
    }

    }
    } else {
    Exe_Dec = 0;
    T_ChangeDecSpeed = 150;
    }


    }
     

    post edited by IvanP - 2018/02/13 01:53:13
    #15
    qɥb
    Monolothic Member
    • Total Posts : 1291
    • Reward points : 0
    • Joined: 2017/09/09 05:07:30
    • Location: Jupiter
    • Status: offline
    Re: sizeof not function with PIC24 2018/02/13 02:06:46 (permalink)
    0
    Why do you persist in putting the small members first in your structure after people explain why this causes problems?
    All you need to do is put the biggest ones first, smallest ones last, and you avoid all those problems.
     

    PicForum "it just works"
    #16
    IvanP
    Starting Member
    • Total Posts : 45
    • Reward points : 0
    • Joined: 2014/11/14 05:00:13
    • Location: 0
    • Status: offline
    Re: sizeof not function with PIC24 2018/02/13 02:37:42 (permalink)
    0
    My function use  AddH AddL for addressing EEPROM.
    The last one parameter is "uint8_t checksum" 
     
    I thought the "__attribute__ ((packed))" solve all the problems
    If i care to align it seems to work
     
     
    #17
    IvanP
    Starting Member
    • Total Posts : 45
    • Reward points : 0
    • Joined: 2014/11/14 05:00:13
    • Location: 0
    • Status: offline
    Re: sizeof not function with PIC24 2018/02/13 02:41:22 (permalink)
    0
    This code function, i ADDED 3 null parameters:

    // ***** area parametri da salvare in EEPROM *****
    struct __attribute__ ((packed)) structEEPROM {
    uint8_t AddH; //contiene l'indirizzo di partenza per la lettura/scrittura in EEPROM
    uint8_t AddL; //contiene l'indirizzo di partenza per la lettura/scrittura in EEPROM
    uint8_t nul0; //byte di partenza per la lettura (deve essere a 8 bit)-> vedi funzione I2C
    uint8_t all_1;
    uint16_t Dato1;
    uint16_t Dato2;
    uint16_t Dato3;
    uint8_t Dato4;
    uint8_t nul1;                              //ADDED
    uint16_t PrezzoP0;
    uint16_t PrezzoP1;
    uint16_t PrezzoP2;
    uint16_t PrezzoP3;
    uint16_t PrezzoP4;
    uint16_t PrezzoP5;
    uint16_t PrezzoP6;
    uint16_t PrezzoP7;
    uint16_t PrezzoP8;
    uint16_t PrezzoP9;
    uint32_t MoneyTotUltIncassoBattute;
    uint32_t PzTotUltIncassoBattute;
    uint32_t moneyTotModTest;
    uint32_t PzTotModTest;
    uint32_t MoneyBatPerditaGratis;
    uint32_t PzBatPerditaGratis;
    uint16_t Decimale;
    // uint8_t VendSingNoResto;
    uint8_t all_2;
    uint8_t ProssimoIndStorico;
    struct _storico storico[101];
    uint8_t null2;                                                  //ADDED
    char NomeValuta[16];
    struct _bevanda Bevanda[8];
    uint8_t null3;                                                  //ADDED
    uint8_t checksum ;
    };
    extern struct structEEPROM ParamEEPROM; //reserve place in RAM
     

     
    #18
    qɥb
    Monolothic Member
    • Total Posts : 1291
    • Reward points : 0
    • Joined: 2017/09/09 05:07:30
    • Location: Jupiter
    • Status: offline
    Re: sizeof not function with PIC24 2018/02/13 02:52:14 (permalink)
    0
    I guess you just don't get the concept of word aligned variables in a 16 bit processor....
     

    PicForum "it just works"
    #19
    IvanP
    Starting Member
    • Total Posts : 45
    • Reward points : 0
    • Joined: 2014/11/14 05:00:13
    • Location: 0
    • Status: offline
    Re: sizeof not function with PIC24 2018/02/13 03:57:22 (permalink)
    0
    Probably yes... can you help me please? 
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2018 APG vNext Commercial Version 4.5