I am working on a project using STM32F103 and I have finished development of the firmware. I use ST-Link Utility for downloading stuff to the microcontroller. When I activate read out protection on my chip, it stops working. And I need to protect my firmware. What is the problem?
Just a bit more info to the accepted answer:
From ST32F10XXX docs, section "2.4.1 Read protection":
The read protection is activated by setting the RDP option byte and
then, by applying a system reset to reload the new RDP option byte.
Note: If the read protection is set while the debugger is still
connected through JTAG/SWD, apply a POR (power-on reset) instead of a
system reset (without debugger connection).
Once the protection byte
has been programmed:
Main Flash memory read access is not allowed
except for the user code (when booting from main Flash memory itself
with the debug mode not active).
Pages 0-3 (for low- and
medium-density devices), or pages 0-1 (for high-density and
connectivity line devices) are automatically write-protected. The rest
of the memory can be programmed by the code executed from the main
Flash memory (for IAP, constant storage, etc.), but it is protected
against write/erase (but not against mass erase) in debug mode or when
booting from the embedded SRAM.
All features linked to loading code into and executing code from the embedded SRAM
are still active (JTAG/SWD and boot from embedded SRAM) and this can be used to
disable the read protection. When the read protection option byte is altered to a
memory-unprotect value, a mass erase is performed.
When booting from the embedded SRAM, Flash memory accesses through the code
and through data read using DMA1 and DMA2 are not allowed.
Flash memory access through data read using JTAG, SWV (serial wire viewer), SWD
(serial wire debug), ETM and boundary scan are not allowed
Unprotection
To disable the read protection from the embedded SRAM:
Erase the entire option byte area. As a result, the read protection code (RDP) will be
0xFF. At this stage the read protection is still enabled.
Program the correct RDP code 0x00A5 to unprotect the memory. This operation first
forces a Mass Erase of the main Flash memory.
Reset the device (POR Reset) to reload the option bytes (and the new RDP code) and,
to disable the read protection.
Note: The read protection can be disabled using the boot loader (in this case only a System Reset
is necessary to reload the option bytes). For more details refer to AN2606.
There's also a write protection on the chip, see the doc.
ADDED: STM32 readout protection has problems: https://blog.zapb.de/stm32f1-exceptional-failure/ so be aware.
You have to unlock the flash first. There should be a call in the STM32 StdPeriph library. My code looks something like this:
/* Read protect the flash. NEVER EVER set this to level 2. You can't
* write to the chip ever again after that. */
FLASH_OB_Unlock();
FLASH_OB_RDPConfig( OB_RDP_Level_1 );
if (FLASH_OB_Launch() != FLASH_COMPLETE)
{
err_printf("Error enabling RDP\n");
}
FLASH_OB_Lock();
Related
I encountered the following issue while using Keil MDK 5 for STM32H743.
I had a communication problem with my SPI code and after a while I found out that it was due to the Periodic Windows Update.
When it is activated, it seems that the debugger is reading regularly the SPI data register, which reads the FIFO (so changes the state of the FIFO). Consequently when the software reads the FIFO, some bytes have been "lost" (or consumed by the debugger).
Is it an expected behaviour ? Do you know if it is due to Keil or to the STM32 ?
I don't fully understand how an access from the debugger to a register is working: I guess there is a read command sent over SWD but then, internally does the access to memory go through AHB / APB like for code executing on the CPU ?
Any registers that modify behaviour by being read (such as clearing status bits) can be problematic when debugging and the registers are shown in the debug window.
The best bet is to only look at the registers when you stop (close the DR window for the peripheral), and always be aware that you may clear status bits etc.
It is the way the processor works and nothing to do with the debugger.
It is a very common debug issue with serial comms etc.
if you have DR display in your watch window (or any other similar windows on the debugger screen) and you step through the code every time you step (or generally break) the data is read.
That is the only possible reason.
Is it possible to enable readout protection on STM32 discovery board?
First I've tried STM32F429I-DISC1 but after enabling RDP with "stm32f4x lock 0" command (I'm using Linux/OpenOCD) MCU doesn't seem to work until sending unlock command (and writing new firmware).
Then I found following statement in this board documentation: 'Known limitation:
• Activating the readout protection on the ST-LINK/V2-B target, prevents the target application from running afterwards. The target readout protection must be kept disabled on the ST-LINK/V2-B boards.'
After that I've tried TM32L100CDISCOVERY - its documentation doesn't have such limitation note, and also its ST-LINK/V2 board, not ST-LINK/V2-B. But I've got exactly same behaviour - everything works fine - LEDs blinking as I programmed, but after locking (with 'stm32lx lock 0' command and subseqyent power cycle) - target MCU doesn't do anything.
So, it looks like no one discovery board support RDP protection at all and if I want to play with this feature - I anyway need to make a custom device? Or its possible with stock demo board but I did something wrong?
The full commands sequence to lock looks so:
init
reset halt
stm32lx lock 0
reset halt
exit
.. or stm32F4x instead of stm32lx for STM32F429I board
I need to implement a multitasking system with MPU for ARM Cortex M3/M4 processors.
In that system, there will be a Kernel which manages resource in Privileged mode and user applications in Unprivilege mode. And I want to seperate User Application from rest of it and system resources.
Therefore, when I switch to a new task, I am releasing Stack and Global Memory area of user application.
It can be done easily using ARM Cortex MPU registers.
But problem is that, when a context switching is occurred, I need to use also some global variables of Kernel.
For example, I am calling a function to get next TCB in PendSV Handler during context switching but task pool is out of user app area and it is protected from user application.
So, it seems there should be balance, right? What are the secure and efficient strategies for memory protection?
Privilieged mode can be raised before context switching when Yield function is called but it does not seem a good solution.
What are the general strategies on that issue?
Perhaps you might take a look at an existing open source implementation and see what design decisions were made there. FreeRTOS for example has Cortex-M MPU support here; it may not answer your exact question directly and you may have to inspect the source code to get complete details.
Possibly divide the data memory into three regions - user, kernel and shared.
I was just wondering whether the switch between the kernel mode and the user mode in an operating system is done by the hardware or the os itself.
I understand that when a user process wants to get into kernel mode it can make a system call and execute some kernel code. When the system call is made, the process goes into the kernel mode and now all memory becomes accessible, etc. In order for this to happen, I would assume that the interrupt handler needs to switch or alter the page table. Is this true? If not, how does the CPU know, that it is running in the kernel mode and does not need to page fault when accessing restricted (unaccessible to the user process) memory?
Thanks!
The last answer is actually not true....
Changing to kernel mode doesn't go through 'Real mode'. Actually after finishing the boot process, the computer never goes back to real mode.
In normal x86 systems, changing to kernel mode involves calling 'sysenter' (after setting parameters in some registers), which causes jumping a predefined address (saved in the MISR register of the CPU), that was set when the computer booted, because it can be done only from kernel mode (it is a 'privileged' command).
So it basically involves executing a software command, that the hardware responds to, by the way it was set, when it was in kernel mode
This is kind of a broad question - each hardware platform is going to do things slightly differently, but I think the basic answer is that it's done w/ software that leverages hardware facilities for memory protection, etc.
When a user process wants to do a system call, it executes a special CPU instruction, and the CPU switches from virtual mode (for user processes, has page tables specific to processes) to real mode (for the kernel) and jumps to the OS syscall handler. The kernel can then do what it likes.
CPU support for this is required. The CPU keeps track of which mode it is in, where the page tables are located, jumping the instruction pointer, etc. It is triggered by the user software doing the syscall, and is dependent on the kernel providing support for whatever it is trying to do. As with all computation, it's always both hardware and software. I cannot be done solely with software however, because then there would be no way to prevent a process making a syscall from abusing the privelages it gains, e.g. it could start reading /etc/shadow.
Modern x86 computers have a special instruction just for doing system calls. Earlier x86 processors, and some current RISC ones, have an instruction to trigger an interrupt. Older architecures had other ways of switching control.
RESOLVED
After much confusion and frustration, I finally got my hard disk to interrupt. :D It basically came down to the fact that I kept reading the status register instead of the alternate status register. A few other things were messed up to boot, but the point is my hard disk driver is finally starting to take shape. Now, for others I will leave the original post.
P.S. For further clarification, I didn't need to issue any sort of reset command. All I did was the following:
Select the device (didn't want to kill the Solaris OS on the other disk)
clear the nIEN bit in the DEVICE CONTROL register
issue an IDENTIFY DEVICE command***
Actually, I am not sure if the IDENTIFY DEVICE command is need because I left the lab happy before I could test the code without issuing the command. However, the main point is that I needed to be sure to read the alternate status register and have the nIEN bit cleared without the need for a reset. The BIOS apparently takes care of most stuff.
I am currently trying to write a disk driver for a hobby OS being developed at my school. I currently have routines to read/write data in the PCI configuration space and assembly routines to do port IO with the various registers defined by ATA/ATAPI-7. Now, my question is, specifically how will I get an IDE hard drive to start generating interrupts? I have been looking through all this documentation and is hasn't become clear to me what I am doing wrong.
Can someone explain exactly what causes an IDE hard drive to start generating interrupts? I already have an interrupts service routine ready to test, but am having difficulty getting the interrupts in the first place. Can this be accomplished through the ATA SOFT RESET?
Thanks!
UPDATE: Ok, I was able to get the secondary channel, an ATAPI CDROM to generate interrupts by setting the SRST bit in the DEVICE CONTROL register for a soft reset. This does not work for the hard disk on the primary channel. What I have noticed so far is that when I set the SRST bit for the HDD, it sets the BSY bit and leaves it set. From there I don't know what to do.
This reference should help you a fair bit: Kenos description of programming ATA/ATAPI.
The basic mechanism to enable interrupts is to clear nIEN in the DCR (Device Control Register):
nIEN: Drive Interrupt Enable bit. The enable bit for the drive interrupt to the host. When nIEN is 0 or the drive is selected the host interrupt signal INTRQ is enabled through a tri state buffer to the host. When nIEN is 1 or the drive is not selected the host interrupt signal INTRQ is in a high impedance state regardless of the presence or absence of a pending interrupt.
This www.ata-atapi.com is a good jumping-off point to find way more info about ATA/PATA/SATA/ATAPI than you want to know... Note that the official ATA-6/7/etc specs cost $$ from T13, though you can download current drafts of ATA-8 from them.
This link describes a few of the many ways ATA devices vary from the specs. (I used to write SCSI and ATA/ATAPI drivers for Commodore/Amiga, way back when, as well as help with qualifying drives - or more accurately, figuring out what idiocies drive makers had done.)
if this is just a hobby OS, why not use the BIOS interrupt (int 13h)? admittedly not as fast as direct disk access but safer for your hard drive (I've put a read head through a plate before messing with disk I/O).