Electronics > Microcontrollers

How dead are 4bit MCUs?

<< < (18/19) > >>

free_electron:

--- Quote from: gnuarm on June 23, 2022, 04:36:20 am ---I wasn't asking how many programs print.  I was asking how many programs use the C library printf code.  That was the context of the reference to copying data from ROM to RAM.  Then your example clearly prints directly from the ROM.

--- End quote ---
on an 8-bitter with constrained resources like an 8051 and likes ? nobody in his right mind would use the printf library. it is too large. and it most likely cannot handle the duality of printing from rom and ram.
i analysed the C-compilers from Mikroe once. they have a "helper" function that copies the string from rom to a ram buffer, and then pass it to printf. The problem is the variable list of arguments in printf .

printf("blah") <- clearly hardcoded string
const blah_string "Blabla"
print blah_string <- still hardcoded as it is a constant
blabla char[11] = "more blabla \0"  <- this starts getting tricky ... you need to analyse all code to see if blabla ever gets modified. if not, you can plonk it in rom ... otherwise ram

printf ("blabla %1",some_number) <- well.. blabla can be stuffed in rom  while the integer needs a conversion routine to ascii string and that has to be stored somewhere and memory allocated for it... so one portion comes from om , another from ram...

that is getting tricky for the printf library. on a von Neumann machine it doesn't matter, it's all flat memory and there is only one machine language operation for access.. in a Harvard machine the opcodes are different...  it becomes spaghetti very quickly.

So the compiler builders resort to trickery where they allocate ram and build the complete string , constants and all in a ram buffer first.... then send it to a uniform handler that writes it to the output buffer. the problem is ... you only have 128 bytes of ram (or less) on those machines. so you end up eating half of your rom for the printf and half of the ram to send out a string of 80 characters ...

Many programming languages for these machines do not have a printf. you roll your own. and you constrain it enough so that you have a routin to print form rom and one from ram. you do the splitting and optimise it for the least amount of ram usage.

brucehoult:

--- Quote from: free_electron on June 24, 2022, 05:45:11 pm ---that is getting tricky for the printf library. on a von Neumann machine it doesn't matter, it's all flat memory and there is only one machine language operation for access.. in a Harvard machine the opcodes are different...  it becomes spaghetti very quickly.

So the compiler builders resort to trickery where they allocate ram and build the complete string , constants and all in a ram buffer first.... then send it to a uniform handler that writes it to the output buffer. the problem is ... you only have 128 bytes of ram (or less) on those machines. so you end up eating half of your rom for the printf and half of the ram to send out a string of 80 characters ...

Many programming languages for these machines do not have a printf. you roll your own. and you constrain it enough so that you have a routin to print form rom and one from ram. you do the splitting and optimise it for the least amount of ram usage.

--- End quote ---

This is where C++ cout "foo" << someInt << "bar" << endl is better. Properly implemented, this doesn't need to assemble the whole line anywhere, and each part can come from ROM, RAM, or be converted in a minimal buffer as appropriate.

The same goes for the C++ overloaded single-argument print() functions in Arduino, designed for use on microcontrollers with barely any RAM.

People only like actual printf() because it's more convenient to type a format string with %s in it, and it's less code at the caller (only one function call).

When the printf format string is constant, a compiler can split it up into print_literal_string_from_ROM(); print_integer(); print_literal_string_from_ROM();  And then you don't drag in the long long or floating point conversions that you're not using.

SiliconWizard:
There are several ways of handling this problem of data access.

The first obvious (but not efficient as far as RAM use is concerned, which could be a problem on small targets) way is to put all "constants" in data memory (RAM) so that the CPU never has to access anything in, say, Flash memory during normal execution of the code.

This can be "trivially" done. A C compiler isn't required to put constants in Flash memory (or generally speaking, in some kind of read-only memory.)
All that can be done writing an appropriate linker script. Then the "startup code" would have to copy all constants in RAM, just like it does for initializing non-zero global variables, using specific instructions for doing so. Most Harvard architectures used these days are modified Harvard, and there is always some kind of bridge between the different memory areas, even when it's not fully transparent.

The second way, which is what was required on older 8-bit PICs, for instance, is that you need to use specific instructions to access Flash memory - and the compiler needs to handle two types of pointers with specific qualifiers. Not very nice, but the plus side is that you don't waste RAM as in the above solution, and you have full control over memory access. Yes, as inconvenient as it can be, I consider this also a benefit for security reasons.

And that said, using printf() on small targets when all you need are simple formats for displaying integers and maybe floating point numbers, is rarely a good idea. Writing your own conversion functions is not difficult and will be much more efficient. And, once you have written them, you can reuse them as often as you want.

free_electron:

--- Quote from: SiliconWizard on June 25, 2022, 02:03:13 am ---The first obvious (but not efficient as far as RAM use is concerned, which could be a problem on small targets)

--- End quote ---
well that is the problem on these small machines.

printf ('Hello %i world %s : %i' , 128, q , b)
passing a constant integer , a string (could be ram , could be rom...) and a ram integer
very difficult to unroll, so they simply build it in a ram buffer, then pass that off to the output handler. the output handler becomes simple and short because only one source and one target , but you eat memory... of which you have very little


harerod:
A bit late to the show, but closer to the original topic: Has anybody ever worked with the Atmel MARC4? I had my eyes on that one for several projects, but its use was never justified by the expected savings. Atmel discontinued this family in 2015.
https://media.digikey.com/pdf/Data%20Sheets/Atmel%20PDFs/T48C510.pdf
Digikey lists several devices as 0 stock / discontinued. Some MCU core with RF interface.

Navigation

[0] Message Index

[#] Next page

[*] Previous page

There was an error while thanking
Thanking...
Go to full version