Dynamically build STM32 application but for two different partitions of flash - linker

I'm using the STM32L496 and have a bootloader at 0x08000000 of flash. After that, I have two partitions for applications, one at 0x08040000 which is the main application, and one at 0x080C0000 for a "golden image" that the bootloader can use if the main application is corrupted (the idea being the main app can be re-programmed with IAP).
I've been able to modify the linker and scb->vtor setting so it will build the application to boot from either partition (golden image when main app is blank).
My question is, is there a way to do this without changing the linker and vector offset manually? Let's say I have a new build that is the new "golden image", I'd like to be able to build that so I can program it to each partition.

I think what you mean is Position Independant Code. It's possible to generate PIC code with ARM cortex GCC though I never did it myself.
It is pretty complicated: see here for example.
However as others wrote already, I don't really see the benefit to do that especially on a small STM32L4 MCU. It is inefficient and complex (so error prone).
Moreover the STM32L4 provide a functionality to do (more or less) what you need: there are two flash banks and you can swap them. It means the HW changes the aliased adress of bank2: you can link your software always to the same adress 0x0800 0000 but load it either in bank 1 or in bank 2. It is meant to ease software update.

Related

Is it possible to create a PIC firmware binary that supports multiple different microcontrollers?

Due to the current chip shortage, I have had to purchase PIC microcontrollers that have a different specification to what was initially designed.
Initial: PIC24FJ256GA606
Revision 1: PIC24FJ512GA606
Revision 2: PIC24FJ1024GA606
In this instance, the microcontrollers are within the same family but have different size of memory.
Initially, the binary was created to support multiple product variants and they all use this microcontroller (using hardware pins to define the type of product and thus the software features it supports). I would like to continue with a single binary but to be able to support the different microcontrollers specified above.
We flash the microcontrollers using a PICKIT 4 during manufacturing.
A custom bootloader is also flashed onto the microcontroller during manufacturing to allow the firmware update procedure to be is driven by another PIC microcontroller out in the field (it's a distributed system connected by RS-485).
I use MPLAB X IDE for development and buildings production binaries.
I guess the key question is about if this is even possible?
If so, then how would I achieve creating the single binary that supports multiple processors?
Normally a single binary should only correspond to the specific controller. Because especially Microchip has really wide variaty of microcontrollers. But as you mentioned in your question:
In this instance, the microcontrollers are within the same family but have different size of memory.
You can slightly use the same binary as long as you select the hardware very carefully. I mean if those 3 different models has the same pin mapping but some has less or some has more, then you would select the common corresponding pins for the I/O functions wherever possible. Since those devices are from the same family they must have common IO pins with the same port and pin numbering.
If those similarities including of that the internal registers are enough for the functionality of your system, you can use the same binary for those 3 or more devices as long as you select the right hardware very carefully and none of the functions remain without touching its hardware.
But it is very hard to say the same for the others that are not belong to a series in the same family. In this case you can check the hardware similarities for each functionality of your system. If that micro provides the same hardware, then you can go and firstly give it a try to see whether it will be programmed and then it will funtion in the same way. After making sure enough you can add that model in your usable models list, too.
Hope this give you a helpful idea.
For two microcontrollers to have compatible binaries, they need to fulfil the following:
The CPU cores must have identical Instruction Set Architecture. Be aware that the term "code compatible" by the manufacturer might only mean that two parts have the same ISA and are compatible on the assembly language level, as long as no peripherals or memories are used...
In case they have different memory sizes, the part with larger memory must be a superset of the part with smaller memory and they must map memory to the same addresses.
All hardware peripherals used must be identical and any peripheral routing registers used must also be identical. Please note that the very same core of the same family but with a different package and pin routing might mean that peripheral routing registers must be set differently.
There can be no check of MCU partnumber registers etc inside the firmware, nor can there be any in the flash programming equipment.
In general this means that the MCUs must be of the very same family and the manufacturer must guarantee that they are replaceable.
You can very likely switch between different temperature spec parts of the same model and between automotive/non-automotive qual parts of the same model without changing the code.

Difference between ARM Simulator and Verilog Simulator?

Basically , I want to know What an ARM Simulator is ? IS it something like an Assembly language simulator ? If so what are the differences in comparison with Verilog Simulators?
Your question is quite broad/vague. but here goes.
An arm simulator, from the context of what you are asking, is likely an instruction set simulator. Software that just like a processor decodes the instructions, keeps track of the registers, and simulates the execution (if an instruction says add 1 to r1 then you have a variable in software that represents r1 and you add one to it).
A verilog simulator, is not really any different just a different language. verilog is a hardware design language, before you can simulate it you need to compile it. Just like any other high level language it needs to be compiled down to something related to the target. simulators will have their own target logic blocks. The verilog is compiled down to these blocks then that logic is simulated, not unlike the arm simulator. For each clock cycle you update the inputs to each logic element based on the output of the connected block from the prior cycle, then evaluate each logic element and determine the outputs. repeat forever. for each verilog simulator you have a different target at its core, partly why you (can) get different results from each simulator for the same code. Likewise when you compile for the actual target, fpga, asic, etc, it is compiled differently than the simulator (or can be, depends on the environment, simulator, etc).
There is no magic at all to any of these simulators, an instruction set simulator is generally easy to write, a worthwhile task for anyone wanting to get a good strong knowledge of an instruction set or how computers work (start with something small like lc-3, should take less than half an hour). A FAST simulator, that is another story, but a FUNCTIONAL simulator is fairly easy to write. Once compiled to a netlist of simple logic components a verilog simulator is probaby easy as well the biggest task though is the volume of signals and items to evaluate and parsing the code to get at the list of signals and logic functions and who is tied to what. Not as easy as an instruction set simulator, but quite understandable how it works and what the task would be...Verilator is pretty cool as it turns it into lines of C++ code, MANY lines, and a good sized project can take many hours to days to compile even on a screaming machine. (hint turn off waveforms to cut the compile time way down). But the task is understandable when you look at what is going on.

Getting into Embedded [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I'm trying to familiarize myself with the embedded field, but also have limited resources in terms of time and equipment to buy.
What's a good language to wrap my head around embedded, without investing too much time leaning an embedded-specific language? I'm most familiar with PHP, Java, Actionscript, but unfortunately know very little C. I remember reading somewhere that someone used PERL to program embedded systems, but not sure if that's really possible.
Can learning be done without needing to buy chips, etc. via simulators or such?
Can someone recommend a simplified roadmap to show how one would get sarted? I'm a little unsure where to even start.
You need to know C (but every programmer needs to know C !)
Most of these platforms have a simulator/emualtor, but since the point is to learn real applications and real problems ( which are all to do with real world timing issues) then you want a real board.
You probably also want an oscilloscope (a very cheap n'th hand slow analogue scope will do) and have some idea how to use it.
Easiest way in is probably Arduino, perhaps more professional but a little harder is launchpad MSP430
There are a few embedded programming lessons that carry over from one platform and style to another, but it is really a broad field. Different processors can require very different tactics, and different applications can dictate both different firmware design tactics and different microcontrollers. Here's some stuff to get you started....
msp430
Texas Instruments has several very inexpensive USB development kits which they call EZ430 and are based on their MSP430 family of micro-controllers. The simplest one has an msp430 f2013, which has 2K of flash program space, 3x128 bytes of usable user flash (another 128 byte page exists, but it's special), 128 bytes of RAM (yes, 128 bytes but it's enough for lots of things), and 16 CPU registers (some of these are special purpose like the Stack Pointer, Instruction Pointer, Status Register, and maybe one or two more). MSP430s also have several memory mapped special function registers which are used for configuring and controlling the built in peripherals. MSP430s are von Newman processors, so everything lives within one address space. These cost about $20us for both the programmer and a removable tab (pc board) containing the msp430 f2013. For about $10us you can get 3 replacement tabs with msp430 2012, which is pin compatible with the 2013 (mostly) and has a few different peripherals. These tabs have an LED, a button, and several large vias (holes in the pc board) which are connected to the pin of the processor. These vias are easy to solder wires into even if you have never soldered before -- due to capillary action the vias just suck the molten solder up and while it's hot you can just jab the end of your wire in there.
They also have a couple more similar kits with 802.15.4 radios. Even if you aren't interested in the radio you may still be interested in these because their programmer also has a UART pulled over from the removable tab and are compatible with the tabs used on the other kits mentioned above. These kits also contain at least one extra programmable board and a battery pack for it. (one of these kits may contain more, but I don't have mine with me right now, and not going to look it up).
They also have a kit that has a programmable watch as the target platform. I've never had one of these, but they have a display, accelerometers, and several other cool things, but this may overwhelm you for your first project. I'd suggest one of the previous kits to get you started with MSP430s.
You can get free C compilers and development environments for MSP430s in the form of IAR's Embedded Workbench kickstart (4 kb program space limited ) IDE, Code Composer Studio (also limited program size, but higher limit, I think), and gcc/gdb for the MSP430. IAR's kickstart is pretty easy to get started with quickly, though it's not perfect. You may find that you have to shut it down, unplug your USB EZ430, restart IAR, and plug back in to get it going again. Or maybe some different order will work better for you.
TI also provides many examples in badly named files (all of their downloadable files go out of their way to be badly named). Be warned -- similar MSP430s may have different device control register interfaces for similar peripherals, which can be confusing. Make sure that any document or example you are reading really does apply to the microcontroller you are using.
other small systems
There are many many other processors families and kits that you can go with, and you should probably at least know a little bit about them.
AVR -- Atmel's 8/16 bit Harvard architecture. Harvard refers to separate address spaces for code and working memory. It has 32 8 bit registers, some of which may be used in pairs as 16 bit registers. It's a very popular and pretty cool processor. Some of the smallest ones only have registers with no extra RAM, which is scary. Atmel also has an AVR32 which isn't at all the same as the AVR. Unless you make use of an existing bootloader capable of loading your new code you will need to get a JTAG unit for these.
8051 -- This is old as the hills and a pain in the butt to use until you finally understand it. It is an 8/16 bit processor, with many more limits on how you go about doing 16 bit math and only has 1 pair of registers which can act as a pointer. It has 3 separate address spaces (stack, global memory, and code) and lots of odd (compared to other architectures) features. The low level stuff might not mean much to you if your are programming in C except that very simple C operations can turn into much more code than you thought they would. You don't want to start on one of thise, most likely.
propeller -- Parallax's very interesting multi-core processor which is very unlike other processors. It has several cores which act mostly independently and can be used to simulate peripherals or do more traditional computational tasks. I've never used one of these, though I'd like to. Just never had a task that seemed to fit it. They have their own high level language to program them as well as the processor's assembly language.
larger systems
After you get out of the 8/16/24 bit processors you start to blur the lines between embedded and desktop level programming, even if it is technically embedded.
AVR32 -- There are 2 main versions of these. One is a Harvard architecture and the other is von Newman. The von Newman version is essentially a better ARM than ARM, but it's not as popular as ARM. As near as I can tell it was designed with "run Linux" in mind, though not tied to it in any crazy way. You used to be able to get cheap development boards for these and code is often almost as easy to load as copying files from one PC to another, though you will probably make use of uboot and tftp to do some work. JTAG is only needed when you mess up the boot loader. I think all of these have support for native JAVA acceleration. www.AVR32.org
ARM -- The most popular embedded processor. There's many versions of these. Some don't have an MMU (memory management unit) and some do. There's too much to say about them. Some version have native JAVA acceleration, though I think that the ARM lords don't freely tell all of the details of how to use it, so you have to find a JVM which knows how to use it. Many vendors make them, including Atmel, Freescale, Intel, and many others.
MIPS -- A very RISC processor. The RISCiest.
There are many others.
Programming styles
I could write 3 books on this but the general rule is make things as simple as the application can let you. An exception to this is that if you can easily make use of an operating system you might want to make use of it if it simplifies your task.
The first thing you need to know when answering this question is "WHAT IS" an embedded system? A GENERAL definition would be a computer system which is dedicated to a single specific purpose. This doesn't limit the type of hardware you can use, as matter of fact "Embedded PCs" have been used for years. The QNX realtime OS has existed since the early 80s and been used in industrial PCs for embedded applications for years. I've personally used in control systems for steel mills XRAY thickness gages. On the other hand I currently use TI DSPs without any OS support and only using 256K of Ram. Another example would be the key fob for your car. Old ones used to use a PIC microcontroller from Microchip. (That's actually the company's name.)
Some people call the IPhone an embedded system, but due to the fact you can load applications to do just about anything I tend to say it's a palm top computer with phone capabilities. An OLD DUMB cell phone that is just a phone, not PDA is an embedded system. That's just a bit of philosophy.
As a general rule there are a handful of concepts you need to grasp for embedded systems programming, and most of them can be explored on a PC.
EDIT:
The REASON why C or C++ is recommended is C itself was designed to do systems programming. C++ maintains all it's advantages but adds capabilities for OOP programming. Some ASM maybe required in some systems. However a lot of chip vendors, such as TI, provide tools basically make it possible to do your entire system in C++.
:END EDIT
ALOT of simple embedded systems look more or less like this:
While(true) // LOOP FOREVER... There is no command prompt
{
// Typically you want I/O to occur on fixed "timebase."
wait(timerTick);
readDigitalIO(&dioStruct);
readAnalogIO(&aioStruct);
// Combine current system state with input values
// and do some useful calculations. (i.e. Analog input to temperature calc)
Process(dioStruct,aioStruct,&CurrentState);
// This can be a serial output/audio buzzer/leds/motor controller
// or Whatever the system REQUIREMENT call for.
driveOutputs(CurrentState);
// The watchdog timer resets your system if it gets stuck.
petWatchDogTimer();
}
There is nothing here that you can't do using the PC. (Well a PC that still has a parallel port anyway. Which is a more or less just a DIO port.) On a simple system without a os this might be all there is. On a RTOS based system you may have several task that all look somewhat simalar to this, but pass data back and forth between the tasks.
The interesting parts come when you have to interface to the hardware on you're own, the first job I had out of college was writing a device driver for a data acquisition board under QNX.
Basic concepts of dealing with hardware, or device drivers (Which you can experiement with by hacking Linux device drive code which is freely avaliable.), most hardware looks to the programmer like just another memory address. This is called "Memory mapped I/O." What does this mean? Lets use a serial port as an example:
// Serial port registers definition:
typedef struct
{
unsigned int control; // Control bits for the port.
unsigned int baudDiv; // Baud rate divider.
unsigned int status; // READ Status bits/ Write resets fifos;
char TXdata; // The head of the hardware TX fifo.
char RXdata; // The tail of the hardware RX filo.
} serRegs;
// Using the volatile keyword to indicate the hardware can change the value
// independantly from the software.
volatile serRegs *Ser1 = (serRegs *)0x8000; // Hardware exists at a specific location in memory.
volatile serRegs *Ser2 = (serRegs *)0x8010; // Hardware exists at a specific location in memory.
// Bits bits 15-12 enable interupts and select interupt vector,
// bits 11-8 enable,bits 7-4 parity,bits 3-0 stop bits.
Ser1->status = 1; // Reset fifos.
Ser1->baudDiv = CLOCKVALUE / 9600; // Set the baudrate 9600;
Ser1->control = 0x1801; // Enable, 8 data, no parity, 1 stop bit.
// Write out a "OK\r\n" message; (Normally this would be a loop.)
Ser1->Txdata = 'O'; // First byte in fifo Transmission starts.
Ser1->Txdata = 'K'; // Second byte in fifo still transmitting first byte
Ser1->Txdata = '\r'; // Third byte in fifo still transmitting first byte
Ser1->Txdata = '\n'; // Fouth byte in fifo still transmitting first byte
Normally you would have a function or an interrupt handler to handle TXing the data, but for example I wanted to point out that the hardware is working while the software keeps going. Basically hardware works like, I write a value to an address and "STUFF" happens independantly of the software. This is perhaps one of the key concepts for embedded programming, how to make the computer effect a change in the real world.
EDIT:
If you actually want to get a cheap board, the current trend from Micro developers is to put a dev kit on a usb thumb stick. This page has info on several, ranging from 8 bits upto ARM architectures: http://dev.emcelettronica.com/microcontrollers-usb-stick-tool
The Cypress PSOC was one of the first to do this with the "FirstTouch Starter Kit." The PSOC is a very unique part in that it has a micro controller and "Configurable analog and digital blocks" that allow you to plop down a ADC, serial port, or digital I/O using a gui and automatically configures you're C app to use it. The PSOCs also are avaliable in DIP packages which makes them easy to use on a prototyper's breadboard.
Picture your embedded controller sitting in a switched-off circuit...
The Vcc power is applied and the reset circuit asserts reset signal.
Clocks have reached running speeds and voltages stabilized, so reset is de-asserted.
Now your controller sets its instruction pointer to the "reset vector," which is physical address 0xE0000000 on this particular chip. The controller fetches the instruction at that location.
Interrupts are disabled, and the first order of business is to initialize registers such as the stack pointer. On some chips, there are flags bits (e.g., x86 direction flag) which need to be cleared or set.
Once the registers and flag bits are set up correctly, it becomes possible for interrupt service routines to run. By now, we must have run code to about location 0xE0000072 when we get to the code which enables interrupts by first toggling some GPIO pins to the external interrupt controller, then enables the CPU interrupts mask.
At this point, the equivalent of "device drivers" are running in the form of interrupt service routines. Assuming the C environment has a library which matches the interfaces of these routines' data structures, by now our boot-loader code can jump to the main() function of some C object code.
In other words, the code which brought us from power-on to main(), and which handles the low-level I/O, is written in the assembler peculiar to the chip you choose. This means that if you want to be versatile at embedded programming, you must know how to implement assembly code starting at the reset vector.
The reality is that hobbyist embedded programming doesn't allow time for implementing all the ISRs and the boot-loader code. For this reason, many people use standard software frameworks available for specific chips. Others use custom-language chips such as the BASICstamp. The BASICstamp is an embedded chip which hosts a BASIC language interpreter on-board. The interpreter and all the ISRs are pre-written for you. The BASIC environment gives you the ability to control I/O pins, read voltages, everything you could do from assembly with an embedded controller, but a bit slower.
As for the language, C is probably the most important language to know. From Java you should be able to adapt, but just remember that a lot of high level Java will not be available to you. Loads of textbooks out there but I'd recommend the original C programming book by Kernighan and Ritchie http://en.wikipedia.org/wiki/The_C_Programming_Language_(book)
For a good introduction to embedded C you could try a book by Michael J Pont:
http://www.amazon.com/Embedded-C-Michael-J-Pont/dp/020179523X
As for the embedded side of things you could start with Microchip, the IDE is OK to develop in with a reasonable simulator, and the c compilers are free for the slightly limited student editions c18 and c30 compilers, the IDE installer will also ask if you want to install a 3rd party HI-TECH C compiler which you could use. As for the processor I'd recommend selecting a standard 18 series PIC such as the PIC18F4520.
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en019469&part=SW007002
Whatever the chip manufacturer, you have to get to know the datasheets. You don't have to learn it all at once but will need it to hand!
Embedded, like most programming, tends to revolve around:
1) initialising a resource, in this case rather than data being from a data store it is from computer registers. Just include the processor header file (.h) and it will allow you to access these as ports (usually bytes) or pins (bits). Also micro-processors come with useful resources on the chip such as timers, analogue to digital converters (ADCs) and serial communications systems (UARTs). Remember that the chip itself is a resource and needs initialising before anything else.
2) using the resource. C will allow you to make data as global as possible and everything can access everything at every time! Avoid this temptation and keep it modular like Java will have encouraged you to (though for speed you may need to be a little looser on these rules).
But they do have an extra weapon called interrupts which can be used to provide real-time behaviour. These can be thought of a bit like OnClick() events. Interrupts can be generated by external events (e.g. buttons or receiving a byte from another device) and internal (timers, transmissions completed, ADC conversions completed). Keep interrupt service routines (ISRs) short and sweet, use them to handle real-time events (e.g. take a byte received and store it in a buffer then raise a flag) but allow background code to deal with it (e.g. check a received byte flag, if set then read the byte received). And remember the all important volatile for variables used by ISR routines and background routines!
Anyway, read around, I recommend www.ganssle.com for advice in general.
Good luck!
The scope of embedded computing has grown very broad, so the answers somewhat depend on what kind of device you're aiming at. On one end, there are 8-bit controllers with only a few KB of memory, usually programmed entirely in assembly or C. On the other end, processors such as those in your router are fairly powerful (200 MHz and a few MB of RAM is not uncommon) and often run an OS like Linux, which means you can use pretty much any language, though C and Java are the most common.
It's best to buy a real chip and experiment. Most of the work involved is usually in getting to know a device and how to interface with it, so using a simulator kind of defeats the purpose.
What's a good language to wrap my head around embedded, without investing too much time leaning an embedded-specific language?
As everyone will suggest: C. Now depending on how deep are you going to dig into your platform of choice, you may also need some assembly, but don't be scared about that: typically you'll use just a little.
If you are learning C, my personal suggestion is: work as you would do in assembly; the programming language won't give you much abstractions, so think in terms of memory management. When you've learnt how to do it move up towards abstractions and live happy.
C++ is also popular on embedded platforms, but IMHO is difficult unless you know well how to program in C you can also understand what's under the hood of its abstraction.
When you feel confident with C/C++ you can start to mess with embedded operating systems. You'll notice that they can be totally different from your OS of choice (By example not all operating systems have a C standard library, processes and splitting between userspace and kernelspace).
You'll learn how to build a cross compiler, how to mess with linker scripts, the tricks of binary formats and a lot of cool stuff.
For the theoretical point of view there's a lot of stuff as well: if you study Computer Science you can get a master's degree in embedded systems.
Can learning be done without needing to buy chips, etc. via simulators or such?
Yes: many operating systems can be run on simulators like qemu.
Can someone recommend a simplified roadmap to show how one would get sarted? I'm a little unsure where to even start.
Try to get a simple operating system which can be run on emulators, hack it and follow your curiosity. Don't be scared of messing with knotty code.
1) Most of the time for most and usually the lower end embedded system, you need to know C.
And I will still recommend you to get a vanilla development board to get yourself familiar with the work flow and tricky part of working with embedded system like debugging and cross compiling. You will run into trouble if you only rely on emulator.
You can try out The Linux Stamp, it is not expensive and is good for beginner but you do need some prior knowledge on Linux.
2) For high end embedded system, a good example is Smartphone from HTC (CPU speed can reach 1Ghz)or some other Android phone it run fast and you can even code Java on it.
C and the assembly specific to your chip.
No, you really need a real chip. Simulators aren't the real thing. You need to be able to deal with keypress jitter, voltage funkyness, etc.
The Arduino is the current fad for embedded hobbyists. I'm not a big fan of Harvard architecture, personally. But you will find oodles of help out there for it. I use an XCore for my thesis work and I have found it super easy to program multicore stuff. I would suggest starting with an AVR32 and going from there.
As everyone else is saying, you need to know C.
Have a look at AVR butterfly for a cheap development board.
Smileymicros have a simple kit with dev board and book:
http://www.smileymicros.com/index.php?module=pagemaster&PAGE_user_op=view_page&PAGE_id=41
The soon to ship Raspberry Pi board looks like an incredibly cheap way to get into this field.
Yup, Arduino would be the way to go. Agreed.. Cheap (about $20 to start) and has great API to get started with high level functions. C is a must though, can't avoid it. But if you can program in other languages you'll be all good.
My recommendation is to start shopping at http://www.sparkfun.com lots of examples to work from and helpful hints of what devices to buy.

Want to configure a particular peripheral register in ARM9 based chip

I have verilog based verification envirnoment for ARM based chip. I have to write new tests in
C++ to verifiy a peripheral. I have all ARM based GCC tools in place. I do not know how to make a
particular peripheral register visible in C++ based test. I want to write to this register, want to wait for the interrupt from the peripheral and then want to read back status of another peripheral register.
I would like to to know how can it be done? Which documentation from ARM should I refer to.
I tried and find all documentations are for system developers
I need the basic information.
Regards
Manish
You will eventually if not immediately want the ARM ARM (yes ARM twice, once for ARM the second one for Architectural Reference Manual, you can google it and find it for free as a download). Second you want the TRM, Technical Reference Manual for the specific core in your chip. ARM doesn't make chips they make processor cores that other people put in their chips so the company that has the chip may or may not have the TRM included in their documentation. If you have an arm core in verilog then I assume you purchased it and that means you have the specific TRM for the specific core that you purchased available, plus any add ons (like a cache for example).
You can take this with a grain of salt but I have done what you are doing for many years (testing in simulation and later on the real chip) now and my preference is to write my C code as if it were going to be running embedded on the arm. Well in this case perhaps you are running embedded on the arm.
Instead of something like this:
#define SOMEREG (*(volatile unsigned int *)0X12345678)
and then in your code
SOMEREG = 0xabc;
or
somevariable = SOMEREG;
somevariable |= 0x10;
SOMEREG = somevariable;
My C code uses external functions.
extern unsigned int GET32 ( unsigned int address );
extern void PUT32 ( unsigned int address, unsigned int data);
somevariable = GET32(0x12345678);
somevariable|=0x10;
PUT32(0x12345678,somevariable);
When running on the chip in or out of simulation:
.globl PUT32
PUT32:
str r1,[r0]
bx lr ;# or mov pc,lr depending on architecture
.globl PUT16
PUT16:
strh r1,[r0]
bx lr
.globl GET32
GET32:
ldr r0,[r0] ;# I know what the ARM ARM says, this works
bx lr
.globl GET16
GET16
ldrh r0,[r0]
bx lr
Say you name the file it putget.s
arm-something-as putget.s -o putget.o
then link putget.o in with your C/C++ objects.
I have had gcc and pretty much every other compiler fail to get the *volatile thing to work 100%, usually right after you release your code to the manufacturing folks to take your tests and run them on the product is when it fails and you have to stop production and re-write or re-tune a bunch of code to get the compiler not confused again. The external function approach has worked 100% on all compilers, the only drawback is the performance when running embedded, but the benefits of abstraction across all interfaces and operating systems pays you back for that.
I assume you are doing one of two things, either you are running code on the simulated arm trying to talk to something tied to the simulated arm. Eventually I assume the code will be doing that so you will have to get into tools and linker issues, which there are many examples out there, some of my own as well, just like building a gcc cross compiler, trivial once shown the first time. If this is a peripheral that will eventually be tied to an arm, but for now is outside the core but inside the design, meaning it hopefully is memory mapped and is tied to the arms memory interface (amba, axi, etc).
for the first case you have to overcome the embedded hurdle, you will need to build bootable code, probably rom/flash based (read only) as that is likely how the arm/chip will boot, dealing with the linker scripts to separate the rom/ram. Here is my advice on that eventually if not now the hardware engineers will want to simulate the rom timing, which is painfully slow in simulation. Compile your program to run completely from ram (other than the exception table which is a separate topic), compile to a binary format that you are willing to write an ad hoc utility for reading, elf is easy, so is ihex and srec, none as easy as a plain old binary .bin. What you ultimately want to do is write some assembler that boots up on the virtual prom/flash, enables the instruction cache (if they have that implemented and working in simulation, if not then wait on that step) uses the ldm amd stm instructions in a loop to copy as many words at a time as you can to ram, then branch to ram. I have a host based utility that takes the .bin file creates an assembler program that includes the assembler that copies the binary to ram and embed the binary itself as .words in the assembler, then assemble and link that program to a format the simulation can use. Do not let the hardware engineers convince you that you have to re-build the verilog every time, you can use a $readmemh() or some other such thing in verilog to read a file at runtime and not have to re-compile the verilog to change the arm binary. You will want to write an ad hoc host based utility to convert your .bin or .elf or whatever to a file that the verilog can read, readmemh is trivial... So I am getting off on a tangent, use the put/get to talk to registers, you have to use the TRM and the ARM ARM to place the interrupt handler code somewhere, you have to enable the interrupt, most likely in more than one place in the arm as well as in the peripheral. The beauty of simulating is that you can watch your code execute and you can see the interrupt leave the peripheral and debug your code based on what you see, with a real chip you dont know if your code is failing to create the interrupt or if your code is failing to enable the interrupt or if the interrupt is working but you made a mistake in the interrupt handler, with a verilog simulator you can see all of this and you should strive to learn to read the waveforms and not rely on the hardware engineers to do it for you. modelsim or cadence or whomever can save the waveforms in .vcd format and you can use a free tool named gtkwave to view the waveforms. Dont let them convince you that they dont have any more licences available for you to look at stuff.
All of that is secondary, if this is an off core but on chip peripheral then you probably want to test that logic without the arm core first. If you dont know verilog, its easy you should just look at the code and you can figure it out. Software engineers can pick it up in a few days or a week if already experienced in languages, particularly C. Either way, the hardware engineer likely has a test bench for the peripheral, you create or have them create a test bench with a register that is similar to what you will see once connected to the arm, either directly on the arm bus or on a test bench interface that simplifies the arm bus. then use vpi, which is ugly but works (google foreign language interface as well as vpi) to connect C code on the host machine running the simulation. Do most of your work in C and verilog minimizing the vpi nightmare. Because this is compiled and linked to the simulation in a sense you do not want to have to re-build the sim every time you want to change your test program. So use something like sockets or some other IPC interface so that you can separate from the vpi code. Then write some host code that implements put32 and get32 (put8, put16, whatever functions you want to implement). so now you take your test program that can run on the arm if compiled that way and instead compile it on the lost linking it to the put/get/whatever abstraction layer. Now you can write programs that for now run on the host but interact with the peripheral in simulation as if it were real hardware and as if your host programs were embedded programs in the arm. the interrupt is likely trivial in this environment as all you have to do is either look for it in the waveforms or have the vpi code print something on the console when the signal changes states or something like that.
Oh, the reason for copying from rom to ram then running from ram is that on average your sim times will be significantly shorter, fives and tens of minutes instead of hours. simulating the peripheral by itself without the arm using a foreign language interface to bridge to/from the host, cuts your sim time from fives of minutes to seconds depending on what you are doing. If you use some sort of abstraction like my put/get you can write your peripheral code one time in one file, linking it different ways that one file/program/function can be used with the perhipheral only in simulation for quickly developing your code, then run with the arm in place in simulation adding the complexity of the arm exceptions and arm interrupt system, and later on the real chip as you were running on the simulated chip. and then later that code can hopefully be used as is in a driver or application space using mmap, etc.

Run time Data and Code memory size estimate

I am working on a project, C programing language, to develop an application, that can be ported on to a number of different microcontroller platforms, such as ARM\Freescale\PIC microcontroller. I am developing this application on Linux now and then I will have to port it to the above said platforms.
I would like to know, are there any tools (open source preferably), using which I can determine the "code" and the data memory footprint\size, before porting it to the new platform.
I have been searching on "Google" for it and have not found anything so far, not even for Linux as well.
any help from you will greatly help me.
-Vikas
For a small program, much of the size is determined by the libraries/DLL your program depends on. Since you refer to ARM/Freescale/Pic I assume you're dealing with compact, embedded applications where data size is measured in bytes rather than MBytes.
For your own code, size differences will determined by:
word size (i.e. 32bit programs tend to be a bit larger /more data than 8 bit)
architecture (i.e. Intel code versus ARM, freescale, PIC)
In your case, I expect that PIC is the most critical part (for RAM/ROM constraints). So propably monitoring the PIC compile size during PC development is sufficient. The linker output will contain info on TEXT/DATA/BSS size, which you can monitor.
I generally work on embedded systems. In my work much of the data size is known at design time (i.e. number of buffers * buffer size). For code size, I have rules of thumb on different architectures which help me to do a sanity check at design time. For instance, I define a suite of some exising-code libraries, for which I know performance and size numbers for each architecture. This way I know what kind of ratio I can expect at design time. If the PC program has 1 MBytes of data, it won't fit in an 8-bit PIC.....
Nothing can tell you how much memory your application will need. You'll have to make some assumptions about how it will be used and try your application under different scenarios.
As you're testing, you can monitor the memory usage stats in the /proc file system or use the ps command to do the same.
The size of your text/code segment will depend on optimization level and back-end. GCC can be configured to generate that information for you.
Run-time is a little more difficult as Jeremy said. Besides his suggestion, you also might want to try gcov and/or gprof in order to analyse your program in the context of your most common use scenarios. This kind of instrumentation is focussed on complexity rather than size but at least you'll know better where to focus your memory analysis.
Your compiler can/will generate a map file. The map file will, generally speaking, have code and data size (or location ranges). There may be differences between different compilers for the different targets. And as pointed out in other posts here, your dependencies on supplied libraries will also impact overall memory usage.

Resources