STM32CubePrg API(example project)


To assist the client, we need to embed the ST update software within the client’s customized software. Therefore, we delve into the original interfaces of STM32CubePrg and gradually integrate them into the client’s specified template. Essentially, the framework is based on STM32CubePrg, with the interface primarily focusing on USB DFU (other customized methods such as HID are not covered within this scope).

STM32CubePrg Project Structure

It will mainly be divided into two parts. One part is to configure the data connecting to the MCU and the interface connected to the update. First, we will go to the following path to open the project:

This folder is located in the personal data folder within the C drive after installing STM32CubePrg.

The first part is to set up MCU update data.
int main()
	int ret = 0;
    const char* loaderPath = "./.";
    displayCallBacks vsLogMsg;

    /* Set device loaders path that contains FlashLoader and ExternalLoader folders*/

    /* Set the progress bar and message display functions callbacks */
	vsLogMsg.logMessage = DisplayMessage;
	vsLogMsg.initProgressBar = InitPBar;
	vsLogMsg.loadBar = lBar;

    /* Set DLL verbosity level */
    setVerbosityLevel(verbosityLevel = VERBOSITY_LEVEL_1);
    ret = USB_Example();
    std::cout << "\n" << "Press enter to continue...";
	std::cin.get() ;
	return ret;

Here are a few points to note, using USB as an example:

  • If using the SW DFU mode, setLoadersPath is not necessary because setLoadersPath is used to let the system know the architecture of the MCU. If writing SW DFU, this part will be written on the MCU, and feedback data will be available.
  • If using the System bootloader, it is important to pay attention to setLoadersPath. The linked MCU data must be located in the directory.

The path needs to point to the Database to confirm which MCU needs to be updated. Keep one file for each MCU, and it can also be connected using ST-LINKV2. The data will appear in STM32CubePrg Information. Not all data needs to be adopted, but the path must be set correctly.

Updating the core API (using USB as an example)

Next is selecting the interface to complete. Here, USB is chosen.

int USB_Example(void) {

	logMessage(Title, "\n+++ USB Bootloader Example +++\n\n");

	generalInf* genInfo;
	dfuDeviceInfo *dfuList;

	int getDfuListNb = getDfuDeviceList(&dfuList, 0xdf11, 0x0483);

	if (getDfuListNb == 0)
		logMessage(Error, "No USB DFU available\n");
		return 0;
	else {
		logMessage(Title, "\n------------- USB DFU List --------------\n");
		for (int i = 0; i < getDfuListNb; i++)
			logMessage(Normal, "USB Port %d \n",i);
			logMessage(Info, "	USB index   : %s \n", dfuList[i].usbIndex);
			logMessage(Info, "	USB SN      : %s \n", dfuList[i].serialNumber);
			logMessage(Info, "	DFU version : 0x%02X ", dfuList[i].dfuVersion);
		logMessage(Title, "\n-----------------------------------------\n\n");

	/* Target connect, choose the adequate USB port by indicating its index that is already mentioned in USB DFU List above */
	int usbConnectFlag = connectDfuBootloader(dfuList[0].usbIndex); 
	if (usbConnectFlag != 0) 
		return 0;
	else {
		logMessage(GreenInfo, "\n--- Device Connected --- \n");

	/* Display device informations */
	genInfo = getDeviceGeneralInf();
	logMessage(Normal, "\nDevice name : %s ", genInfo->name);
	logMessage(Normal, "\nDevice type : %s ", genInfo->type);
	logMessage(Normal, "\nDevice CPU  : %s \n", genInfo->cpu);

	/* Download File + verification */
#ifdef _WIN32
	const wchar_t* filePath = L"../test file/VL53L7_USB_HID_PresV4_ALS_V519_withDFU.BIN";
	const wchar_t* filePath = L"../api/test file/data.hex";

	unsigned int isVerify = 1; //add verification step	
	unsigned int isSkipErase = 0; // no skip erase
	int downloadFileFlag = downloadFile(filePath, 0x08000000, isSkipErase, isVerify, L"");
	if (downloadFileFlag != 0)
		logMessage(Normal, "\ndownloadFileFlag :%d\n", downloadFileFlag);
		return 0;

	/* Process successfully Done */
	return 1;

Essentially, the FW download Function is downloadFile, while others are for checking if the connection is normal. Testing this function with absolute paths showed that some may fail, possibly due to internal optimizations where absolute paths are relative to resources. Hence, it is recommended to use relative paths for execution.

Leave a Comment

Your email address will not be published. Required fields are marked *

Shopping Cart