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.

MSP430FR2311: MSPGANG: Not able to use some native functions from the MSP-GANG dll in C#

Part Number: MSP430FR2311
Other Parts Discussed in Thread: MSP-GANG

Hi Team,

I'm trying to integrate MSP-Gang.dll in my C# project  but there are some native functions (e.g.  "GetDataBuffers_ptr(void** x)") that are using not easy to handle parameters in Managed envirnoment.

I had a look at the C# example in the MSP-GANG package but it is not really implementing all the functions so in this case it has not been helpful.

By looking at the CPP_Interactive_MSP_DLL example I was able to find how to get the DATA_BUFFERS class instance from the GetDataBuffers_ptr function void** parameter:

void *temp;
DATA_BUFFERS  *RxGang;

MSPGANG_GetDataBuffers_ptr((&temp));

RxGang = (DATA_BUFFERS *)temp;

Unfortunately this is not helping much in C# as I din't find a way to marshal the void** pointer to the DATA_BUFFERS class instance, can anyone help?

Thanks.

Edoardo

  • Hi Edoardo,

    Unfortunately, there isn't much information on using C#, but I did reach out to our SW team to see if they had something to offer.

  • I tried something like this:

    - redefined DATA_BUFFER declaration

    [StructLayout(LayoutKind.Sequential)]
        public struct DATA_STRUCT
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE)]
            public byte[] SourceCode;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE)]
            public byte[] UsedCode;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE )]
            public byte[] CommonTx;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE * GenericConstants.GANG_SIZE)]
            public byte[] GangTx;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE * GenericConstants.GANG_SIZE)]
            public byte[] GangRx;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE)]
            public byte[] Tmp;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2 * DatBufConst.JTAG_PASSW_LEN)]
            public byte[] JTAG_Passsword;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2 * DatBufConst.BSL_PASSW_LEN)]
            public byte[] BSL_Passsword;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE)]
            public byte[] Flag_ScrCode;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE)]
            public byte[] Flag_UsedCode;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE)]
            public byte[] Flag_WrEn;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE)]
            public byte[] Flag_EraseEn;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE)]
            public byte[] Flag_RdEn;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE)]
            public byte[] Flag_Sp1;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE)]
            public byte[] Flag_Sp2;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE)]
            public byte[] Flag_Sp3;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2 * DatBufConst.JTAG_PASSW_LEN)]
            public byte[] Flag_JTAG_Passw;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2 * DatBufConst.BSL_PASSW_LEN)]
            public byte[] Flag_BSL_Passw;
        }

    - changed the native function parameter void** to IntPtr

    [DllImport("MSP-GANG.dll", EntryPoint = "MSPGANG_GetDataBuffers_ptr", ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
            public static unsafe extern Int32 GetDataBuffers_ptr(out IntPtr data);

    - used the Marshal.PtrToStructure() method 

    IntPtr ptr = new IntPtr();
    DATA_STRUCT data = new DATA_STRUCT();
    unsafe
    {
        
        status = MSPGANG_API.GetDataBuffers_ptr(out ptr);
    
        
        data = (DATA_STRUCT)Marshal.PtrToStructure(ptr, typeof(DATA_STRUCT));                       
    }
    
    if (Evaluate(status, out mess) == false)
    {
       tbStatus.Text += "ERROR: " + mess + Invio;
    }

    This compiles and seems to correctly work at runtime but the status returned by the GetDataBuffers_ptr function is the following:

    "ERROR 1: BOOT Firmware only is in the MSP-GANG! The API Firmware should be downloaded"

    this is confusing me as all the other interactive functions are working without errors, what could it be?

  • Hi Edoardo,

    Have you tried reaching out the Elprotronics company for help?  They have support via email. They build the MSPGANG programmer and maintain the SW. They might be able to point you in the right direction.

  • Finally I found a solution and I would like to share.

    Basically the issue was caused by some mistakes on the daclarations file (MSP-GANG-Dll.cs) found in the MSP-GANG package examples:

    1. the DATA_BUFFER structure in C# was declared as managed class and this turned out to be very difficult to manage from unmanaged to managed code so I declared it as structure like this:

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct DATA_STRUCT
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE)]
            public byte[] SourceCode;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE)]
            public byte[] UsedCode;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE * GenericConstants.GANG_SIZE)]
            public byte[] GangRx;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE)]
            public byte[] Tmp;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE)]
            public byte[] Flag_ScrCode;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE)]
            public byte[] Flag_UsedCode;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE)]
            public byte[] Flag_WrEn;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE)]
            public byte[] Flag_EraseEn;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE)]
             public byte[] Flag_RdEn;
           [MarshalAs(UnmanagedType.ByValArray, SizeConst = DatBufConst.DBUFFER_SIZE)]
             public byte[] Flag_Sp3;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2 * DatBufConst.JTAG_PASSW_LEN)]
            public byte[] JTAG_Passsword;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2 * DatBufConst.BSL_PASSW_LEN)]
             public byte[] GBSL_Passsword;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2 * DatBufConst.JTAG_PASSW_LEN)]
             public byte[] Flag_JTAG_Passw;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2 * DatBufConst.BSL_PASSW_LEN)]
            public byte[] Flag_BSL_Passw;
        }

    paying attention to the GangRX buffer that in this case I needed to flatten from a bidimensional to one dimension array

    2. managed the GetDataBuffers_ptr function parameter as out InPtr type ( as posted above)

    3.using the Marshal.PtrToStructure to get the proper data structure from the IntPtr pointer ( as posted above)

    4. Changing the definition of the "DBUFFER_SIZE" from 0x90000 (mistakenly set in the MSP-GANG-Dll.cs file) to 0x210000 ( as per the cpp examples)

**Attention** This is a public forum