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

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

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

跳至解决方案
1,086 次查看
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 解答
871 次查看
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 回复数
871 次查看
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 项奖励
回复
872 次查看
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 项奖励
回复
871 次查看
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 项奖励
回复