Passing 2D array to a function - Hard Falt when reading it

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Passing 2D array to a function - Hard Falt when reading it

ソリューションへジャンプ
1,166件の閲覧回数
anthonyduhamel
NXP Employee
NXP Employee

Hello,

I'm coding on a KL46Z Mcu, using CW10.6/PEx IDE plus MQXLite and I have some troubles with double pointer accesses. In fact I'm passing a 2D array to a function. When I read the double pointer value, there is a Cpu Hard Fault.

Basically my function is:

vMyClass_MyFunction(int16_t** __aai16_Buffer,uint8_t __u8_BufferLength)

{

     int16_t __i16_test;

     uint16_t __u16_i;

     for(__u16_i=0;__u16_i<__u8_BufferLength ;__u16_i++)

       {

               //__i16_test= __aai16_Buffer[0][__u16_i];  // Hardfault when uncommented

               if(  __aai16_Buffer[0][__u16_i]!=0 && __aai16_Buffer[1][__u16_i]!=0) // hard fault here

               {

                    // do something

               }

        }  

}

Called by:

static int16_t _aai16_globalBuffer[2][100];

vMyClass_MyFunction(_aai16_globalBuffer, 100);

This function worked in an other project. Maybe there is an option to tick or enable to allow those kind of access in my project.

Does anybody have an answer to fix that?

Thanks!

Anthony

0 件の賞賛
返信
1 解決策
951件の閲覧回数
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello Anthony:

I think this is a coding issue. In your code the compiler does not interpret the parameter __aai16_Buffer as a "2D array", but as a "pointer to pointer", which is not the same thing. Then you would need to cast the pointer back to 2D array type.

So the function definition should be something like this:

void vMyClass_MyFunction(int16_t** __aai16_Buffer,uint8_t __u8_BufferLength)

{

    int16_t __i16_test;

    uint16_t __u16_i;

    for(__u16_i=0;__u16_i<__u8_BufferLength ;__u16_i++)

    {

        __i16_test= ((int16_t(*)[__u8_BufferLength])__aai16_Buffer)[0][__u16_i];

        if(((int16_t(*)[__u8_BufferLength])__aai16_Buffer)[0][__u16_i]!=0 && ((int16_t(*)[__u8_BufferLength])__aai16_Buffer)[1][__u16_i]!=0)

        {

            // do something

        }

    }

}

or this:

void vMyClass_MyFunction(int16_t** __aai16_Buffer,uint8_t __u8_BufferLength)

{

    int16_t __i16_test;

    uint16_t __u16_i;

    for(__u16_i=0;__u16_i<__u8_BufferLength ;__u16_i++)

    {

        __i16_test= (*((int16_t(*)[__u8_BufferLength])__aai16_Buffer+0))[__u16_i];

        if( (*((int16_t(*)[__u8_BufferLength])__aai16_Buffer+0))[__u16_i]!=0 && (*((int16_t(*)[__u8_BufferLength])__aai16_Buffer+1))[__u16_i]!=0)

        { 

            // do something

        }

    }

}

And even simpler if you use the correct parameter type instead of int16_t**, although this requires a fixed array size:

void vMyClass_MyFunction(int16_t __aai16_Buffer[][100],uint8_t __u8_BufferLength)

{

    int16_t __i16_test;

    uint16_t __u16_i;

    for(__u16_i=0;__u16_i<__u8_BufferLength ;__u16_i++)

    {

        __i16_test= __aai16_Buffer[0][__u16_i];

        if(__aai16_Buffer[0][__u16_i]!=0 && __aai16_Buffer[1][__u16_i]!=0)

        {

            break;

        }

    }

}

Regards!
Jorge Gonzalez

元の投稿で解決策を見る

0 件の賞賛
返信
3 返答(返信)
951件の閲覧回数
anthonyduhamel
NXP Employee
NXP Employee

The strange thing is that I can read the 2D-array cell value by attacking directly the memory with pointers & casts.

__i16_test=*( ((int16_t*)__aai16_Buffer)+0*__u8_BufferLength+__u16_i);// equals to [0][i]

__i16_test=*( ((int16_t*)__aai16_Buffer)+1*__u8_BufferLength+__u16_i);// equals to [1][i]

.. without cpu Hard fault ....

Anthony

0 件の賞賛
返信
952件の閲覧回数
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello Anthony:

I think this is a coding issue. In your code the compiler does not interpret the parameter __aai16_Buffer as a "2D array", but as a "pointer to pointer", which is not the same thing. Then you would need to cast the pointer back to 2D array type.

So the function definition should be something like this:

void vMyClass_MyFunction(int16_t** __aai16_Buffer,uint8_t __u8_BufferLength)

{

    int16_t __i16_test;

    uint16_t __u16_i;

    for(__u16_i=0;__u16_i<__u8_BufferLength ;__u16_i++)

    {

        __i16_test= ((int16_t(*)[__u8_BufferLength])__aai16_Buffer)[0][__u16_i];

        if(((int16_t(*)[__u8_BufferLength])__aai16_Buffer)[0][__u16_i]!=0 && ((int16_t(*)[__u8_BufferLength])__aai16_Buffer)[1][__u16_i]!=0)

        {

            // do something

        }

    }

}

or this:

void vMyClass_MyFunction(int16_t** __aai16_Buffer,uint8_t __u8_BufferLength)

{

    int16_t __i16_test;

    uint16_t __u16_i;

    for(__u16_i=0;__u16_i<__u8_BufferLength ;__u16_i++)

    {

        __i16_test= (*((int16_t(*)[__u8_BufferLength])__aai16_Buffer+0))[__u16_i];

        if( (*((int16_t(*)[__u8_BufferLength])__aai16_Buffer+0))[__u16_i]!=0 && (*((int16_t(*)[__u8_BufferLength])__aai16_Buffer+1))[__u16_i]!=0)

        { 

            // do something

        }

    }

}

And even simpler if you use the correct parameter type instead of int16_t**, although this requires a fixed array size:

void vMyClass_MyFunction(int16_t __aai16_Buffer[][100],uint8_t __u8_BufferLength)

{

    int16_t __i16_test;

    uint16_t __u16_i;

    for(__u16_i=0;__u16_i<__u8_BufferLength ;__u16_i++)

    {

        __i16_test= __aai16_Buffer[0][__u16_i];

        if(__aai16_Buffer[0][__u16_i]!=0 && __aai16_Buffer[1][__u16_i]!=0)

        {

            break;

        }

    }

}

Regards!
Jorge Gonzalez

0 件の賞賛
返信
951件の閲覧回数
anthonyduhamel
NXP Employee
NXP Employee

Thanks for your answer Jorge. It makes sense that the compiler can not interpret the 2D array because it does not know the size of the array of array.

The last option is more legible, but it assumes fixed array size..

By the way,  all methods work. And mine too.

Thanks again.

Anthony

0 件の賞賛
返信