Computers and modern gadgets



In my project I am using STM32F103C8 microcontroller and stm32duino framework. This Arduino clone offers a special bootloader that allows you to upload firmware via USB, without the use of external components such as ST-Link or a USB-UART adapter.

Today I needed to work with a bare controller from under CooCox and without stm32duino. But here's the problem. Even a simple blinker with a light bulb poured through this bootloader does not work.

Let's figure it out. Perhaps my calculations will seem banal to someone. But I'm just starting to study STM32 controllers and I killed at least half a day to find a problem. Suddenly this article will reduce someone's development time.

I have nothing against ST-Link and other debuggers. But in my finished device it will not be, but it will definitely be USB. Why not immediately lay down the ability to update the firmware via USB? Personally, I find this method convenient. especially since I still have a cord connected through which power and USB Serial are supplied.

Let's see how the bootloader works. To begin with, on the example of AVR controllers. Why did I remember him? I was moving from Arduino and subconsciously expected the same behavior. But in STM32 everything turned out differently. Therefore, I want to talk about the difference between these two microcontrollers.

So. In AVR ATMega microcontrollers, a certain amount of memory can be reserved for the bootloader closer to the end of the flash. Using fuse bits, you can control from which address the program will start. If there is no bootloader, the program starts from address 0x0000. If there is a bootloader, it starts from some other address (say, in ATMega32 with 0x3C00, if the bootloader size is set to 2k).


When the bootloader has done its work, it transfers control to the main program from address 0x0000. Those. the program always starts at address 0x0000. The compiler and linker work with the assumption that the code will be located at the beginning of the address space.

In STM32 microcontrollers, everything is different. All programs start at address 0x0800000. The bootloader is nothing special. This is the same program that starts from the same starting address. During operation, the bootloader can receive firmware (via USB or UART, read from a USB flash drive, receive from a satellite, get it from subspace, whatever ...) and write it to addresses higher than the bootloader itself is located. And, of course, at the end of your work, transfer control to the main program.


So, when compiling the firmware, you need to know where the bootloader will write the firmware and adjust the addresses accordingly.

That's all with theory. Let's move on to practice. Below is a step-by-step instruction on how to screw a USB bootloader to STM32F1xx series microcontrollers, and maybe to some others too.

There are, however, some restrictions on circuitry. Here, unfortunately, I am not strong. YTP needs a 1.5k pull-up resistor for the PA12 port (aka USB D+). This allows the bootloader to connect and disconnect from USB at the right time.

  • Now the microcontroller is ready to be flashed via the USB bootloader. But you still need to fix the firmware itself. And you need to do 2 things:
    • Specify the linker's starting address. In CooCox, this is done in the project settings, Link tab, Memory Areas section, IROM1 Start Address. The bootloader occupies the first 8 kilobytes, so the starting address of the firmware will be 0x0800000 + 0x2000 = 0x08002000. The Size field should probably also be reduced by 8k.
    • Somewhere at the beginning of the program, before initializing the peripherals, make a call

      NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x2000);

  • The firmware uploader can be taken from the stm32duino project. In the tools directory, look for a script called maple_upload. I used only the Windows version - maple_upload.bat.
  • Run like this:

    "maple_upload.bat" COM20 2 1EAF:0003 "Path\To\Firmware.bin"
    Instead of COM20, you need to substitute your port where the microcontroller is attached.

    The filler is a very delicate thing, it does not like relative paths. so the path to the firmware must be specified in full.

    1EAF:0003 is VID and PID

    2 is the AltID parameter, which indicates that the firmware should be uploaded at 0x08002000 (read).

  • A few more nuances. Before uploading the firmware, you need to run the bootloader. The easiest way is to press the reset button. After that, the bootloader will start and wait a few seconds for the firmware. If no one is running maple_upload at this point, the loader will pass control to the main firmware.

    This may cause inconvenience. If the microcontroller shuts down and hangs, then it no longer listens to the port. Therefore, he cannot hear the key sequence and reboot into the bootloader. Then only reset to help.

    That's all. I hope my article will shed light on how the bootloader works in STM32 and how you can upload firmware via USB port. Unfortunately, the entry threshold is still high, but suddenly my article will help someone overcome it.

    Answers to frequently asked questions:

  • 1. Who is this FAQ for?

    Most specialists who develop devices based on microcontrollers are already familiar with the topic of protecting microcontroller programs, so we can assume that this section will not tell them anything new. However, there is a huge army of engineers and ordinary consumers of electronic devices who are not familiar with the detailed organization of such protection, but who want to either understand the details of the operation of an existing device or create such a device, this collection of answers to questions is intended for them.

  • 2. Why and from whom is the protection of microcontrollers done?

    Many manufacturers of electronic devices try to protect their device from being easily copied by another manufacturer. Manufacturers of microcontrollers met them halfway by introducing copy protection of the program (microprogram) contained in the memory of the microcontroller into the functionality of their products. Using this firmware read protection, manufacturers of electronic devices can protect their product from being simply copied by another manufacturer.

  • 3. What is copy protection in the microcontroller, and why can't I read the protected microprogram (firmware) myself?

    Usually, copy protection is set during microcontroller programming by setting a special protection bit or a few bits in the microcontroller configuration word. Physically, these bits are located in special memory cells on the microcontroller chip. Sometimes other security methods are used, such as password protection, but the principle is the same. To remove the protection, it is usually necessary to change the value of this bit or several bits, although other methods of reading the contents of the microcontroller program memory can often be used. Conventional methods, such as a programmer, will not be able to do this; complex expensive equipment is required, which an ordinary developer of electronic devices does not have. Therefore, having the necessary equipment, knowledge and experience, we specialize in providing this kind of service.

  • 4. What does the removal of protection from reading the firmware (firmware) do for me?

    Let's say you have a device that you purchased from one of the manufacturers of electronic devices and you want to produce the same, but modified device. But of course, you do not have the source codes of the firmware or the finished firmware, and you will need to develop and debug the firmware completely from scratch. This, in comparison with copying the electronic component of the device (circuit), will have to spend a lot of money and time. Using our professional services, you will save both money and time for device development. In the presence of a device or its electrical circuit, we can completely restore the algorithm of its operation and the text of the microprogram in the programming language C or Assembler.

  • 5. What is the legality of such actions in terms of legislation?

    We read all microprograms (firmware) at the request of the client in order to repair his device, or to familiarize himself with the algorithm of the microprogram. All further responsibility for the illegal distribution of the firmware or other actions with it or with its help lies entirely with the customer.

    Our company operates on the territory of the Russian Federation, so below is a quote from the law. The legislation of other countries declares a similar position.

    Article 1280 of the Civil Code of the Russian Federation. "Free reproduction of computer programs and databases. Decompilation of computer programs".

    2. A person who lawfully owns a copy of a computer program has the right, without the consent of the right holder and without paying additional remuneration, to study, investigate or test the functioning of such a program in order to determine the ideas and principles underlying any element of the computer program, by carrying out the actions provided for in subparagraph 1 paragraph 1 of this article.

    3. A person lawfully in possession of a copy of a computer program has the right, without the consent of the right holder and without paying additional remuneration, to reproduce and convert the object code into source text (decompile the computer program) or instruct other persons to carry out these actions if they are necessary to achieve interoperability a computer program independently developed by this person with other programs that can interact with the program being decompiled ...

  • 6. What is additional read protection and why is it better than regular?

    Additional three-level protection is designed to create conditions for the impossibility of reading the microprogram (firmware) using known methods. It can include from one to three levels of protection: protection against opening the case, hidden in-case breakage of the leg used by the programmer for reading, hidden on-chip removal of the leg control logic used for reading.

    The first level is a refractory polymer resistant to acids and solvents, which does not allow access to the crystal.

    The second level makes it impossible for the programmer to read without special expensive tools.

    The third level performs a function similar to the second, but at the same time, on-chip restoration of the control logic on the internal layers is practically impossible, or it requires very expensive equipment.

    Given that in the overwhelming majority of cases, conventional factory protection is easily bypassed, additional protection for many expensive and complex devices is an extremely necessary measure to prevent material losses associated with the fall of the fruits of intellectual activity into the hands of third parties.

  • 7. I want to install additional protection, but I'm afraid that you consider my top-secret program before installing protection. Is there any way to put additional protection on the chip before I finally program it?

    In this case, before installing our additional protection, you can only flash the bootloader without the main program. After we install additional protection, you can already program the main memory. Moreover, the bootloader for loading the main program must use any other interface other than the main one used for standard programming, since the main interface will be disabled after installing our additional protection. Usually the bootloader itself is of no interest for copying. As a bootloader, you can use your own or modified from the examples from the microcontroller manufacturer.

  • This Arduino clone offers a special bootloader that allows you to upload firmware via USB, without the use of external components such as ST-Link or a USB-UART adapter.

    Today I needed to work with a bare controller from under CooCox and without stm32duino. But here's the problem. Even a simple blinker with a light bulb poured through this bootloader does not work.

    Let's figure it out. Perhaps my calculations will seem banal to someone. But I'm just starting to study STM32 controllers and I killed at least half a day to find a problem. Suddenly this article will reduce someone's development time.

    I have nothing against ST-Link and other debuggers. But in my finished device it will not be, but it will definitely be USB. Why not immediately lay down the ability to update the firmware via USB? Personally, I find this method convenient. especially since I still have a cord connected through which power and USB Serial are supplied.

    Let's see how the bootloader works. To begin with, on the example of AVR controllers. Why did I remember him? I was moving from Arduino and subconsciously expected the same behavior. But in STM32 everything turned out differently. Therefore, I want to talk about the difference between these two microcontrollers.

    So. In AVR ATMega microcontrollers, a certain amount of memory can be reserved for the bootloader closer to the end of the flash. Using fuse bits, you can control from which address the program will start. If there is no bootloader, the program starts from address 0x0000. If there is a bootloader, it starts from some other address (say, in ATMega32 with 0x3C00, if the bootloader size is set to 2k).

    When the bootloader has done its work, it transfers control to the main program from address 0x0000. Those. the program always starts at address 0x0000. The compiler and linker work with the assumption that the code will be located at the beginning of the address space.

    In STM32 microcontrollers, everything is different. All programs start at address 0x0800000. The bootloader is nothing special. This is the same program that starts from the same starting address. During operation, the bootloader can receive firmware (via USB or UART, read from a USB flash drive, receive from a satellite, get it from subspace, whatever ...) and write it to addresses higher than the bootloader itself is located. And, of course, at the end of your work, transfer control to the main program.


    So, when compiling the firmware, you need to know where the bootloader will write the firmware and adjust the addresses accordingly.

    That's all with theory. Let's move on to practice. Below is a step-by-step instruction on how to screw a USB bootloader to STM32F1xx series microcontrollers, and maybe to some others too.

    There are, however, some restrictions on circuitry. Here, unfortunately, I am not strong. YTP needs a 1.5k pull-up resistor for the PA12 port (aka USB D+). This allows the bootloader to connect and disconnect from USB at the right time.

  • Now the microcontroller is ready to be flashed via the USB bootloader. But you still need to fix the firmware itself. And you need to do 2 things:
    • Specify the linker's starting address. In CooCox, this is done in the project settings, Link tab, Memory Areas section, IROM1 Start Address. The bootloader occupies the first 8 kilobytes, so the starting address of the firmware will be 0x0800000 + 0x2000 = 0x08002000. The Size field should probably also be reduced by 8k.
    • Somewhere at the beginning of the program, before initializing the peripherals, make a call

      NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x2000);

      UPDATE 05/17/2018: There is no NVIC_SetVectorTable() function in the modern version of STM32Cube. Instead, you can fix the VECT_TAB_OFFSET define in the system_stm32f1xx.c file (or similar for another microcontroller)

  • The firmware uploader can be taken from the stm32duino project. In the tools directory, look for a script called maple_upload. I used only the Windows version - maple_upload.bat.
  • Run like this:

    "maple_upload.bat" COM20 2 1EAF:0003 "Path\To\Firmware.bin"
    Instead of COM20, you need to substitute your port where the microcontroller is attached.

    The filler is a very delicate thing, it does not like relative paths. so the path to the firmware must be specified in full.

    1EAF:0003 is VID and PID

    2 is the AltID parameter, which indicates that the firmware should be uploaded at 0x08002000 (read).

  • A few more nuances. Before uploading the firmware, you need to run the bootloader. The easiest way is to press the reset button. After that, the bootloader will start and wait a few seconds for the firmware. If no one is running maple_upload at this point, the loader will pass control to the main firmware.

    This may cause inconvenience. If the microcontroller shuts down and hangs, then it no longer listens to the port. Therefore, he cannot hear the key sequence and reboot into the bootloader. Then only reset to help.

    That's all. I hope my article will shed light on how the bootloader works in STM32 and how you can upload firmware via USB port. Unfortunately, the entry threshold is still high, but suddenly my article will help someone overcome it.

    Today we will protect the firmware on stm32 from being read by cool hackers. In order not to pull the rubber, here is a piece of code:

    #ifdef NDEBUG if (FLASH_GetReadOutProtectionStatus() == RESET) ( FLASH_Unlock(); FLASH_ReadOutProtection(ENABLE); FLASH_Lock(); ) #endif

    As you might guess, the piece uses the library from stm. It is very convenient to use such a piece of code - the controller sets its own protection at the first start, and the first start is easy to organize after the firmware. Here it is, freedom from the tyranny of fuses!

    Yes, I know, about the holivor about "library vs direct access to registers". My position here is this - if you need high speed, or there is very little memory left, but you need a direct access to the registers. If speed is not important and there is a lot of memory, it is better to use a library - this way the program is written faster and more readable.

    Remove protection
    We have protected the controller. But here's the trouble - we need to fix our program, and with the protection installed, nothing can be done with the controller - neither read nor write. How to remove protection? I warn you right away - the guys from ST did everything right and the whole firmware is destroyed along with the protection.

    To remove protection, we need the st-link utility program. You can download it.

    Run the program and select this item, or just press ctrl-b:

    In the "Read protection state, select off" field. And press the Apply button:

    Together with the protection bit, all memory is also erased:

    Protect yourself, we are for a safe embed.

    The easiest and most affordable way to flash STM32- by using bootloader, in this article we will look at how to do this using the example of a board miniSTM32F103V.

    First, let's understand what is bootloader or whatever it is called loader. Loader- it's just a program that is stored in a specific section of memory and can overwrite the flash microcontroller. It is sewn up during the production of the chip and cannot be changed in any way. In order for the microcontroller to enter this section of memory, you need to output BOOT0 pull up to power, and output BOOT1 to the ground. On the board, these two pins are located near the usb connector, and the pull-up is carried out using jumpers.
    Below is a table that determines from which memory area the microcontroller will start after a reset, depending on BOOT0 And BOOT1.


    Suppose we have installed jumpers, now we need to transfer the hex file with the firmware to the bootloader, we will transfer it by uart, for this we need a converter usb uart.


    I have such a converter made on the basis of a microcircuit FT232RL using a thin tip for a soldering station, soldering it is very simple. The sealing method is as follows, first you need to grab a leg from two opposite angles, then when the microcircuit is fixed, solder the rest of the legs with a soldering iron or a hairdryer. And the final touch, once again we solder the legs, which were soldered first, in order to remove mechanical stress from them.

    We connect the adapter usb uart to the computer and depending on which chip it is made on CP2120 or FT232, install the appropriate drivers. After that, it should be defined in the system as COM_PORT.


    Now let's connect our adapter to the board, connect the RX output of the adapter to the output MCU_TxD, and the output of TX with the output MCU_RхD. The topology of the board that the seller sent is slightly different from the one in the top picture, the pins for the firmware are displayed separately and are marked with red arrows.


    Next, you need to download a program with which we will contact the bootloader, it is called FLASH LOADER DEMONSTRATOR.


    After installing the program, select the com port under which our adapter was defined usb uart and press the NEXT button, the speed will be determined automatically. If the controller is read-protected, then protection can be removed by pressing the "Remove Protection" button, while the flash memory will be erased and, accordingly, all the data that is written in it is lost.


    If the controller is not protected, the window shown below will appear, in it we press the NEXT button.


    In the next window, you need to choose what we want to do: read / write the flash of the microcontroller, erase it, prohibit reading / writing, we are interested in writing, for this we select the file we want to upload and press NEXT.

    If you notice an error, select a piece of text and press Ctrl + Enter
    SHARE:
    Computers and modern gadgets