One not widely known feature of the FreeMASTER tool is the ability of using FreeMASTER communication library in 3rd party applications or scripts. This library implements the proprietary communication protocol and allows developers to interact with the target board from their own desktop application (complementary to FreeMASTER GUI and JSON-RPC API usage).
Note: although this approach grants developers full control over the communication with the target board it lacks some advanced features of the FreeMASTER tool such as symbol loading (it does not include TSA loading and ELF parsing functionalities) and users need to pass numeric addresses when reading and writing embedded project variables.
This article is meant to provide a basic example on the communication library usage in a custom Python script using ctypes based on the shared library distributed with FreeMASTER Lite.
An similar articles covering the same topic using C/C++ can be found here.
Required files for this example are located under FreeMASTER Lite installation directory (default location C:\NXP\FreeMASTER 3.x\FreeMASTER):
Considering the library targets 32bit architecture you would need a 32bit variant of Python (tested with version 3.6)
from ctypes import *
def hex32(val):
return hex(val & (1 << 32 - 1))
def MCB_FAILED(val):
return val < 0
def MCB_SUCCEEDED(val):
return val >= 0
class DESCRIPTION(Array):
_length_ = 25
_type_ = c_uint8
class MCB_RESP_GETINFO_t(Structure):
_fields_ = [("protVer", c_uint8),
("cfgFlags", c_uint8),
("dataBusWdt", c_uint8),
("globVerMajor", c_uint8),
("globVerMinor", c_uint8),
("cmdBuffSize", c_uint8),
("recBuffSize", c_uint16),
("recTimeBase", c_uint16),
("descr", DESCRIPTION)]
mcbcom = CDLL("C:/NXP/FreeMASTER 3.1/FreeMASTER Lite/lib/mcbcom.dll")
pCom = c_void_p()
result = mcbcom.McbOpenComEx(byref(pCom), c_char_p(b"RS232;port=COM3;speed=115200;tmoRI=40;tmoRTM=40;tmoRTC=50;tmoWTM=40;tmoWTC=50"))
if (MCB_FAILED(result)):
print("Could not open communication channel. Error code: ", hex32(result))
exit(1)
boardInfo = MCB_RESP_GETINFO_t()
result = mcbcom.McbGetInfo(pCom, byref(boardInfo))
if (MCB_SUCCEEDED(result)):
print("Board is using FreeMASTER Driver v", boardInfo.protVer, sep='')
print("Embedded application description", str(boardInfo.descr, 'utf-8'))
mcbcom.McbCloseCom(pCom)
#define MCB_FAILED(code) (((int32_t)(code)) < 0)
#define MCB_SUCCEEDED(code) (((int32_t)(code)) >= 0)
Python implementation:
def MCB_FAILED(val):
return val < 0
def MCB_SUCCEEDED(val):
return val >= 0
typedef struct MCB_RESP_GETINFO_t
{
uint8_t protVer; /**< @brief protocol version */
uint8_t cfgFlags; /**< @brief MCB_CFGFLAG_ bits */
uint8_t dataBusWdt; /**< @brief data bus width (bytes) */
uint8_t globVerMajor; /**< @brief board firmware version major number */
uint8_t globVerMinor; /**< @brief board firmware version minor number */
uint8_t cmdBuffSize; /**< @brief receive/transmit buffer size (without SOB, CMD/STS and CS) */
uint16_t recBuffSize; /**< @brief recorder buffer memory */
uint16_t recTimeBase; /**< @brief recorder time base (2 MSB exponent 1 = m, 2 = u, 3 = n) */
uint8_t descr[MCB_DESCR_SIZE]; /**< @brief ANSI string, board description */
} MCB_RESP_GETINFO_t;
Python implementation using ctypes:
class DESCRIPTION(Array):
_length_ = 25
_type_ = c_uint8
class MCB_RESP_GETINFO_t(Structure):
_fields_ = [("protVer", c_uint8),
("cfgFlags", c_uint8),
("dataBusWdt", c_uint8),
("globVerMajor", c_uint8),
("globVerMinor", c_uint8),
("cmdBuffSize", c_uint8),
("recBuffSize", c_uint16),
("recTimeBase", c_uint16),
("descr", DESCRIPTION)]
pCom = c_void_p()
result = mcbcom.McbOpenComEx(byref(pCom), c_char_p(b"RS232;port=COM3;speed=115200;tmoRI=40;tmoRTM=40;tmoRTC=50;tmoWTM=40;tmoWTC=50"))
boardInfo = MCB_RESP_GETINFO_t()
result = mcbcom.McbGetInfo(pCom, byref(boardInfo))