How to initialize the initialized data section? - bare-metal

I do own linker script and crt for MIPS64
And cause of what Ive got a question:
How to initialize the initialized data section?
Should this filled by zero?
I have got MIPS64 and MIPS bare metal compiler(mips-mti-elf) and in my linker script I do initialization only sbss and bss section and my application works with en errors for while
Is it enough to initialize onf sbss and bss by zero?, if, in addition, apply RTOS

Related

Is there a process to remap/switch CANTX/CANRX pins STM32H7 FDCAN module?

Testing out an STM32 with an FDCAN module (updated from the older BxCAN peripheral). CAN Classic at 500kbps.
I am running into an issue that when using the default pair of pins (D0/D1 in my case) I get expected behavior, but when switching the pins to the secondary option (B8/B9) using GPIO remapping, I get strange output on the bus.
I tried baud settings and options like protocol exception. Nothing seems to explain where this scope output is coming from.
I'm using the HAL to get this working, so I'm certain I'm not missing any registers on remapping. I've DeInit and ReInit the FDCAN module, started/stopped, etc. There seems to be no documented "process" for remapping pins. The entire FDCAN section of the reference module doesn't have the letters GPIO.
Picture: Yellow is the CANTX 0-3V signal (low is dominant). Purple is the CAN+ signal that idles at 2.5V and pulls past ~3.5V on a dominant. There is nothing else on this line, so I'm not concerned about the sawtoothing. The large initial CAN "SOF" pulse is wrong for timing. The long recessives are nonsense. Then the small value 1 bits are of the correct 2uS pulses for 500kbps. Changing the data put into the FDCAN FIFO makes no difference, the output is always the same.
Solved.
After sending this message, the INIT bits were set in the FDCAN->CCCR register. There were values in the error counters. Indicates an internal error. I was using the HAL as a time saver, but it was over-writting my desired GPIO settings.
I would set the pins B8/B9 to AF mode for FDCAN. Then call FDCAN_DeInit/Init, which via an MSP_INIT callback also calls GPIO Init, but for the original D0/D1 pins. Meaning the B8/B9 I set, and the D0/D1 pins were enabled at the same time.
This is an obvious problem. The HAL is fine for prototyping, but careful because it will try and "help". Undefined behavior at best and I normally wouldn't even post such a dumb mistake.
However... Maybe someone else finds it interesting that whatever the FDCAN state machine is doing here, makes this unique output seen in the scope picture. I initially didn't double check my pin setup, because it looked right, I was getting output on the scope, just the wrong output. I spent much more time going over peripheral settings and data I was feeding to it.

STM32H7 - IAR Placing Local Variables into 'Reserved Memory' (0x1FF20000 - 0x1FFFFFFF)

I started a new project using an STM32H7, currently using IAR EWARM V8, used the STM32CUBEMX to generate the configuration code, and get an initial project going.
I worked through a couple of the CUBEMX eval projects to get some hardware verified and working, and am able to step through code fine.
But there is something odd going on, in particular with variables if you assign them as local vars within a function, somehow IAR is placing them into the 'System Reserved' memory range...
ie within 0x1FF20000 - 0x1FFFFFFF
For example... the project example 'FMC_NOR' that STM provides, is test code for testing our a NOR flash, etc..
they created these two small arrays as globals vars just at the top of the main.c file.
(buffer_size is 0x1000)
uint16_t aTxBuffer[BUFFER_SIZE] = {0};
uint16_t aRxBuffer[BUFFER_SIZE] = {0};
When in the global space, they are allocated in the DTCM region (0x2000:0000)
When moved as local vars, they then become allocated into the 'reserved space'...
What happens is, when IAR encounters any arrays like this, the processor faults with an 'imprecise data access' hardware fault.
This same error occurs with code to initialize the JPEG module, as it attempts to load the arrays of Huffman tables, etc...
When using TrueStudio this problem does not occur... CubeMX auto-generates the linker files for whichever compiler you are using.
I didn't specifically see anything in the linker files pointing to the reserved memory address.
So not sure what could be going on? I'm new to using this processor, so I'm just starting to understand it's memory mapping.
Thanks for any help or suggestions, I'd like to get IAR figured out, as so far I like it a bit over TrueStudio.
I solved my own question... so no longer need help on this...
This is in the 'stm32h743xx_flash.icf' generated by STM CUBEMX for the STM32H7...
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__ = 0x200;
/**** End of ICF editor section. ###ICF###*/
Bumped the 'size_cstack' up to 2k (0x800) and everything is fine...

uC/OS-II How to dynamically load a task

Basically, when my system is running, I would like the user to ftp some new code to the SD card, and dynamically load the new function and create a task to run in the system. This is normal for Linux. For example, I can compile a SO, and dynamically load into the memory.
How to do it in uC/OS II or III?
This is not a service uC/OS-II or uC/OS-III can provide by itself.
You would need a program loader that is able to read an ELF file, copy its relevant sections (ex .text, .rodata, etc.) in memory according to load addresses specified and allocate memory for uninitialized memory sections. You would then be able to create a new uC/OS task and pass it the function pointer that corresponds to the ELF entry point.
Most embedded systems don't have a Memory Management Unit (MMU) and thus you would need to pay special care to the linking process to make sure any of those sections don't overlap with any code that would already running on your target. Depending on your toolchain, that would most likely involve carefully crafting your linker script.
Another option that would avoid the problem of potential overlapping of the memory space would be to use a toolchain that can produce position independent code and load the ELF in the heap of your main application or in any other allocated and available memory space that is allocated by your main application.
Yet another option would be to produce relocatable code and use or build a program linker that is able to process relocations at runtime, when you want to load the uploaded code.

Section load address and execution address in linker script

I'm writing a customized linker script for a bare-metal ARM application. The application is stored in a flash memory, at the moment I have a bootup code copying the whole application in SDRAM, and continuing execution in SDRAM for speed purpose. I want to modify this script to run the whole code from flash directly, but I have problems understanding certain elements.
In the linker script below, the .ram_data section has an execution address in RAM and a load address in ROM (both sections in SDRAM). From what I understand the execution address is used by the linker to do the symbol resolution of all elements which are not PC relative, but what about the load address? In the context of a bare-metal ARM there is no such thing as a program loader, and there is no way the linker can have any influence on where I write the program in flash, so what is it actually used for?
In the same way, how can the linker have any influence on the SDRAM being (rx) or (rw) at run-time? Does it actually change anything when I modify those options in the memory regions?
MEMORY
{
RAM(rw) : ORIGIN = 0x00001000, LENGTH = 12M-4K
ROM(rx) : ORIGIN = 0x007f1000, LENGTH = 60K
}
SECTIONS
{
.startup :
{ ... } > VECTOR
.rom_text :
{ ... } > ROM
.ram_data :
{
_data_start = .;
*(.data*)
_data_end = .;
} > RAM AT>ROM
.ram_bss :
{ ... } > RAM
}
Given your example linker script, these two questions are related.
From what I understand the execution address is used by the linker to do the symbol resolution of all elements which are not PC relative, but what about the load address?
In the same way, how can the linker have any influence on the SDRAM being (rx) or (rw) at run-time? Does it actually change anything when I modify those options in the memory regions?
The LOAD address is useful as everything must be programmed to FLASH. This is why .ram_data should have AT>ROM. It is telling the linker that the data will LOAD from the ROM/Flash. You have to make some assembler boot code that will copy it from flash to SDRAM in this case.
The 2nd question can be answered by putting >ROM for the .ram_data section. If you do this, the linker will complain that a write-able section is being placed in read-only memory. It is good to mark the MEMORY sections with read/write information as it can help to make sure you have the sections in the correct places. Ie, it is a cross check on the information you give the linker.
A mistake where >RAM AT>ROM is instead just >ROM makes the concepts/questions similar.
From what I understand the execution address is used by the linker to do the symbol resolution of all elements which are not PC relative, but what about the load address? In the context of a bare-metal ARM there is no such thing as a program loader, and there is no way the linker can have any influence on where I write the program in flash, so what is it actually used for?
That information is stored in the ELF executable, and is used by tools like objcopy to determine how the binary file (e.g, .bin or .hex) is laid out. Ultimately, it ends up telling your programmer where to put the program.
In the same way, how can the linker have any influence on the SDRAM being (rx) or (rw) at run-time? Does it actually change anything when I modify those options in the memory regions?
In this particular use case, I believe those flags are informational only. They're primarily used for dynamic-loaded programs.

Why would the address of reset vector differ when two firmwares are linked with the same linker script?

I have a Cortex-M3 chip and on it I am running a bootloader that uses eCos. The bootloader, after checking for firmware updates etc, jumps to another location (BASE_ADDRESS_OF_APP + 0x19) on the ROM where the actual application resides (also compiled with eCos).
Now instead of running the normal firmware, I want to run my CppUTests compiled for the Cortex-M3 target. So I am able to compile and link my tests for the target platform, using the ecos glibc, but not the actual operating system. But when I load it on to my board using JTAG, it doesn't run.
After some investigation using arm-eabi-objdump, I found out that the reset vector of the CppUTest firmare is at an offset of 0x490 as opposed to an offset of 0x18 for the normal firmware. My suspicion is that this is the reason why the tests are never executed. Is this correct?
How is it possible that the two firmwares have different starting addresses when I am linking them with the same linker script?
How can I make sure that the starting point of the test program is the same as the starting point of the application?
It depends on how your linker script is written, if your entry point address is not set to a static location in the linker script, then there could be the chance that other data/code is put in the object file before your entry point, effectively moving the location of your entry point and indeed causing problems.
I typically solve this by creating a new section with only 1 symbol in it, and a jump/branch instruction as follows:
.section entryPointSection
b myCodeEntryPoint
Then in your linker script put the entryPointSection at the hard coded address that your bootloader will jump to.
The myCodeEntryPoint label can be the name of a C function (or assembly label if necessary) that is in the normal .text section and can be linked anywhere within reach of the jmp. It will become your entry point, but you don't really care where it is because the linker should find it and link it properly.
Consider posting your linker script if you have further questions.