STM32F107 boot from external Flash over SPI - embedded

I'm running out of memory with my STM32F107. Unfortunately is 256kb the maximum size of this MCU and there is no pin compatible alternative.
I found several Flash Modules and I know there are ways to boot from it, but I never done that before and I dont know if its possible with the STMF107.
Have someone tried that? Is SPI fast enough, I read something about QSPI, but the STM doesnt support that.
Here the Datasheet from the STM: https://www.st.com/resource/en/datasheet/cd00220364.pdf
Here the Datasheet from the favorite Flash: https://www.mouser.de/datasheet/2/198/IS25LP032-064-128-463542.pdf

The only way you would be able to do this with your microcontroller and that flash is to copy the code into ram and execute it from there. This is not a great solution.
The QSPI interface in some STM32 microcontrollers is different to regular SPI, it has 4 data lines, and is memory mapped, which allows it to be executable, the 'regular' SPI interface has no means for execution of code.

Related

How does JTAG flash memory programming work?

I am currently using Xilinx ZCU106 board, and I am curious about How does JTAG support flash memory programming. I can upload the boot images or hardware logic just by connecting JTAG USB cable to USB connector at the ZCU106 Board, and press the flash button on the host PC. By doing this it looks like the QSPI Flash holds the boot images or hardware logic image and the system initializes itself by using this image. It seems like a magic, and I want to know about the detail.
So far I understood is that I can access JTAG interface via USB cable (thanks to the FTDI chip?), and JTAG boundary-scans the devices connected to it.
However the problem is here, I couldn't find the link between JTAG and QSPI Flash (MT25QU512ABB8ESF-0SIT). I searched several references, including manual of QSPI Flash (MT25QU512ABB8ESF-0SIT, https://media-www.micron.com/-/media/client/global/documents/products/data-sheet/nor-flash/serial-nor/mt25q/die-rev-b/mt25q_qlkt_u_512_abb_0.pdf) but there seems no port for JTAG (such as TDI, TDO, and TCK), but only SPI.
So the first assumption, I thought on the JTAG chain maybe there is a SPI controller to flash the memory. However I couldn't find any clue on the references that I've read so far that a SPI controller exists on the chain or even a SPI controller that controls the QSPI flash really exists. And the second assumption, I thought PS- ARM Cortex A53- TAP (?) does the magic. PS TAP receives JTAG signal and processes the JTAG command. To be precise, let's say about flash memory programming case, then there is like a JTAG command for write data on the flash memory via SPI.
Among these two, I wonder if there is the answer. One thing for the last, if the second one suppose to be the answer, then the processor (Cortex A53) should implement the functionalities by hardware logic to parse Flash write/erase command signal from JTAG interface and let the SPI controller that the system includes perform the write/erase job? Somewhere I read that the JTAG itself supports writing data on the Flash memory but everything I could find was just TDI, TCK, TDO, TMS, and TRST ports which does not fit in any port of QSPI Flash.
Probably I am confusing a lot of concepts very much, but I want to know about the exact mechanism behind the scene on JTAG flash memory programming.
Normally, it will do with the following sequence:
Send some software to target processor in RAM
Send data to target processor (in RAM)
Trigger execute command to store data into the flash memory.
Now the expected data are available in flash memory.

STM32 boot loader

I'm learning about embedded systems and have an idea about one small project and I want to use Cortex M0+ based MCU STM32G081KBT6. I saw a lot of tutorials with this MCU type, but all of them are based on developer board and with them it is very simple to upload code with USB cable. I want to make my custom PCB for this. So my question is what I have to do so I can upload my code to this microcontroller?
From a datasheet I think I have to use SWDIO (PA13) and SWCLK(PA14) ports for Boot, but if someone can help me do I have to use also some resistors, can I make it USB to wire transfer with this, or I have to use some external device to make it possible? Or there is some easier and better solution to upload code from my laptop to microcontroller?
Thanks for the replies.
There two main options:
SWD
Implement an SWD programming connector. Basically the pins GND, SWDIO, SWCLK and preferably 3.3V are made available. No resisters are needed. You can fit a 4 pin header, an official 10 pin SWD connector or just 4 pads (for connecting using an adapter with pogo pins).
This option requires an SWD debug adapter like ST-Link or J-Link. In addition to uploading firmware, this option supports debugging.
USART
Make the USART (RX, TX) pins plus GND and 3.3V available on the board. This option requires a USB-to-serial adapter.
It's also possible to use I2C or SPI instead, though there are no standard solutions for connecting to your board that I'm aware of.
USB isn't an option for this particular chip. It is supported on many of the more expensive STM32 chips though.
I strongly recommend the first option. It is far more versatile than the other options. And an ST-Link adapter isn't expensive.
Details regarding the bootloader capabilities and pins:
https://www.st.com/resource/en/application_note/cd00167594-stm32-microcontroller-system-memory-boot-mode-stmicroelectronics.pdf

how the usb spi flashing device write program to atmega?

the atmega microcontrollers have the internal programmable memory.So the usb flash device write data to internal memory of atmega through spi or it store the program and works as slave?i also want to know can the atmega get program,file in the MicroSD and run without internal memory or it need to run a program in internal disk then including the program in MicroSD?i don't know how the process work in atmega microcontroller.
There are several ways to program the AVR:
Using an external programmer. The Chip is in reset state during this. Then the programmer uses special a special protocol to directly write to the flash inside the controller. This is how your USB programming device probably writes code to the AVR. There are several protocols for this, but the most common one uses the same pins that are used by SPI. You should not confuse them just because of that ;-).
The controller writes the program itself. The chip is actively executing a program. That program on the chip fetches the instructions from e.g. a sd card and using the SPM instruction to copy it to local flash.
The AVR can only fetch instructions from it's own flash memory - you cannot execute directly from RAM or from any other external source.
The best answer for this question you can find at the end or middle of datasheet for AVR device (eg ATMEGA 328P-PU). If you are using some flashing device connected with computer, there is some initialization sequence after start and then there are send some 4 Bytes commands that tels microcontrolers, where to store values to flash and/or eeprom, fuse bits, or cares about erasing etc. There is also posible to read ID of chip.
Atmega microcontroler can be also programmed in paralel mode, where are some bits used for sending commands that tels, what to do with data on data bit.
If you ask about downloading program from SD card or any other device, there is possible to write to the flash through SPM, as there was told above. Some devices do not have part of flash for downloader - if I remember ATMEGA 48, and devices, that have configurable part of memory usable also for downloader, that can handle this, eg. ATMEGA 88, 168, 328. So if you want to download program from SPI, USART, TWI, etc, you need to configure fuse bits and create downloader that will do it for you. I am not sure, how ATMEGA 48 do this, but there si probably possible to write whole flash by SPM instruction.
However the best answer you can find in the datasheet. On pages folowing 255 you can find further information. http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf

how to port uclinux linux to any microcontroller

I have stellaris LM4f232 evaluation borad. I have ported free rtos , sysbios to stellaris lm4f232 board and successfully developed an gps tracking application . But I always wanted to port uc linux for my board . my question are
i) is there any material to port uclinux to any controller
ii)what are necessary knowledge I required to do the same
I have googled a lot . I did n't get the right information, but I have seen posts that its difficult ,but I cant able to realise the same .any help????
iii) what is the road map to achieve it , what are the knowledge I should need to achieve this
Linux, even uCLinux requires considerable memory resources; you'd want to start with at least 2Mb for the boot device and 16Mb of RAM (although a minimal system can be booted in as little as 4Mb). On a microcontroller, this means that you must have external memory.
Another issue is that Cortex-M devices are optimised to run code from on-chip Flash memory, having separate buses for ROM and RAM so that data and instructions can be fetched simultaneously. uClinux must run from external RAM, which has a detrimental effect on the performance, and you will be unlikely to achieve the 1.25MIPS per MHz figure the CM4 is otherwise capable of. It is possible to arrange for time critical code to be placed in on-chip flash is necessary, but it is of course a limited resource.
Some good advice on the issues of deploying Linux on a Cortex-M device can be found here
I would suggest to have a look on buildroot which as far as I know can be build for this board.
adding to #Clifford , you can use u-boot (bootloader) ,already configured for many boards ,if your board is not on list you can edit it.,

Bootloader Working

I am working on Uboot bootloader. I have some basic question about the functionality of Bootloader and the application it is going to handle:
Q1: As per my knowledge, bootloader is used to download the application into memory. Over internet I also found that bootloader copies the application to RAM and then the application runs from RAM. I am confused with the working of Bootloader...When application is provided to bootloader through serial or TFTP, What happens next, whether Bootloader copies it to RAM first or whether it writes directly to Flash.
Q2: Why there is a need for Bootloader to copy application to RAM and then run the application from RAM? What difficulties we will face if our application runs from FLASH?
Q3: What is the meaning of statement "My application is running from RAM/FLASH"? Is it mean that our application's .text segment or .code segment is in RAM/FLASH? And we are not concerned about .bss section because it is designed to be in RAM.
Thanks
Phogat
When any hardware system is designed, the designer must consider where the executable code will be located. The answer depends on the microcontroller, the included memory types, and the system requirements. So the answer varies from system to system. Some systems execute code located in RAM. Other systems execute code located in flash. You didn't tell us enough about your system to know what it is designed to do.
A system might be designed to execute code from RAM because RAM access times are faster than flash so code can execute faster. A system might be designed to execute code from flash because flash is plentiful and RAM may not be. A system might be designed to execute code from flash so that it boots more quickly. These are just some examples and there are other considerations as well.
RAM is volatile so it does not retain code through a power cycle. If the system executes code located in RAM then a bootloader is required to obtain and write the code to RAM at powerup. Flash is non-volatile so execution can start right away at powerup and a bootloader is not necessary (but may still be useful).
Regarding Q3, the answer is yes. If the system is running from RAM then the .text will be located in RAM (but not until after the bootloader has copied it to there). If the system is running from flash then the .text section will be located in flash. The .bss section is variables and will be in RAM regardless of where the .text section is.
Yes, in general a bootloader boots the system, but it might also provide a mechanism for interrupting the default boot path and allow alternate firmware to be downloaded and run instead, as well as other features (like flashing).
Traditional rom had a traditional ram like interface, address, data, chip select, read/write, etc. And you can still buy rom that way, but it is cheaper from a pin real estate perspective to use something spi or i2c based, which is slower. Not desireable to run from, but tolerable to read once then run from ram. newer flash technologies can/have had problems with read-disturb, where if your code is in a tight loop reading the same instructions or for any other reason the flash is being read too fast, the charge can drop such that a read returns the wrong data, potentially causing the program to change course or crash. Also your PC and other linux platforms are used to copying the kernel from NV storage (hard disk) to ram and then running from there so the copy from flash to ram and run from ram has a comfort level, and is often faster than flash. So there are many potential reasons to not use flash, but depending on the system it may be possible to run from flash just fine (some systems the flash in question is not accessible directly and not executable, of course SOME rom in that system needed to be executable/bootable).
It simplifies the coding challenges if you program the flash with something that is in ram. You can create and debug the code one time that reads from ram and writes to flash and reads from flash and writes to ram. DONE. Now you can work on separate code that receives data from serial to ram, or from ram to serial. DONE. Then work on code that does the same over ethernet or usb or whatever DONE. You dont have to deal with inventing a protocol or solving the problem of timing. Flash writing is very slow, and even xmodem at a moderate speed can be way too fast, so you have to buffer that data in ram anyway, might as well make the tasks completely separate, instead of an xmodem or any other serial based flash loader with a big ram based fifo, just move the data to ram, then separately go from ram to flash. Same for other interfaces. It is technically possible to buffer the data and give the illusion of going from the download interface straight to flash, and depending on the protocol it is technically possible to hold off the sender so that as little as one flash page is required in ram before programming flash. With the older parallel flashes you could do something pretty cool which I dont think most people figured out. When you stop writing to the flash page for some known period of time the flash would automatically start to program that page and you have to wait for 10ms or something like that before it is done. What folks assumed was you had to program sequential addresses and had to get the new data for the next address in that period of time and would demand high serial port speeds, etc, the reality is you can pound the same address over and over again with the same data and the flash wont start to program the page, and the download interface can be infinitely slow. Serial flashes work differently and either dont need tricks or have different tricks.
RAM/FLASH is not some industry term. It likely means that .text is in rom (flash) and .data and .bss are in ram. A copy of the initial state of .data will probably be on flash as well and copied to ram before main() is called, likewise .bss will be zeroed before main() is called. look at crt0.S for most platforms in gnu sources (glibc, or is it gcc, I dont know) to get the gist of how the bootstrap works in a generic fashion.
A bootloader is not required to run linux or other operating systems, you dont NEED uboot, but it is quite useful. Linux is pretty easy, you copy the kernel and root file system, either set some registers or some tags in memory or both then branch to the entry point in the kernel and linux takes over from there. Because linux is so complicated it is desireable to have a complicated bootloader that can capitalize on high speed interfaces like ethernet (rather than being limited to serial or slower).
I would add something regarding your question Q2.
Q2: Why there is a need for Bootloader to copy application to RAM and then run the application from RAM? What difficulties we will face if our application runs from FLASH?
It is not only about having SPI or similar serial external code memory (which is not that often anyway).
Even the external ROM/FLASH/EPROM/ connected to the usual high speed parallel bus will will prevent a system from running on a maximum clock (with zero wait state) even on the relatively slow MCUs due to the external memory access time. You would need 10 ns FLASH access time for the 100 MHz clock, which is not so easy to get (if economically possible at all). And you would agree that 100 MHz is not such a brain spinning speed any more :-)
That is why many MCU/CPU architectures are doing tricks with reading multiply instructions at once, or having internal cash, or doing whatever was needed to compensate for a slow external code memory. Only most older 8-bit architectures can execute the code directly from the flash memory ('in place').
Even if your only code memory was the internal Flash, something need to be done to speed it up. Take a look for example at this article:
http://www.iqmagazineonline.com/magazine/pdf/v_3_2_pdf/pg14-15-18-19-9Q6Phillips-Z.pdf
It desribes how the ARM7 has incorporated something they called MAM (Memory Accelerator Module). It is a good read, and you will find some measures there to speed up the code memory access for the specific ARM7 arhitecture (goes for most others):
Limit maximum clock frequency (from 80 MHz to about 20 MHz for the example in the article)
Insert wait-cycles during flash accesses
Use an instruction cache
Copy the program code from flash to RAM
Obviously, if the instruction cache was not an option (too small, or the clock too high) you are really left only with execution from the RAM, after relocating the code there at the start up.
There is an option also to run only specific section of code from the RAM, which could be specified to the linker. For the DSP (Digital System Processing) systems, there was really no option to run from the EPROM/FLASH even in the old days with clock around only few tens of MHz, let alone now.
Another issue is debugging, the options for debugging the code placed in ROM, or even Flash, are very limited (you have to move section of the code to RAM to be able to set a break point on most systems).
Regarding Q2, one of the difficulties you may face executing from Flash is another code update. If you are executing from the same block of Flash you are trying to update, the system will crash. This depends on your system architecture (how your application and bootloader are organized in Flash) but may be particularly hard to avoid if you are trying to update the bootloader itself.