Use printf in embedded c - c

I work on the Aurix microcontroller on eclipse
i need to display unsigned char values on the console,
I did like that
printf ("% hhx", tab [j]);
but I had this error:
error: AppKit_TC277TFT_TimeDemo.elf section `.inttab' will not fit in
region `PMI_PSPR'
error: region `PMI_PSPR' overflowed by 16788 bytes
Is there anyone who could help me

Searching for PMI_PSPR Aurix in a well-known search service brings up this forum post.
Apparently you are linking your code to run from RAM. Change the linker settings to link it to flash, and run from there.

First try to isolate what is the cause. Two thoughts are:
Check if the stdout stream works.
Check if a memory issue (as the error suggests).
1. stdout check:
Try using the stdout stream without using printf formatter. The formatter is bloated as people suggest and generally not a good idea on embedded systems. Also have you setup where the stdout stream goes (is it mapped to some UART code, normally on embedded systems you need to write or configure this)? Test by using putch('.'), putchar('.') or even puts("Hello").
2. memory check:
Try building the code that uses sprintf() by itself without stdout. If that doesn't build either then it is likely the formatter. Some embedded compilers allow configuring the formatter library as smaller options to get around this issue (doesn't support the full implementation).

Use printf in embedded c
One way is to use UART communication.
Convert numeric value to printable ascii form and send to UART so that one may see on console.
For simple applications you may consider storing printable characters to some array buffer and at the end of activity print the array buffer to UART

Related

How could I get input inside my kernel inside a freestanding environment?

I am making an operating system in assembly and I just integrated c. I want to get input but you can include stdio.h inside a freestanding environment. How would I go about getting user input inside a freestanding environment
A simple approach would be to read your CPU's architecture manual to check for the entry in the IDT corresponding to the keyboard (9th entry if I recall correctly in x86).
And add a pointer to the function handling your keyboard input.
Usually what you want in that function is to store each input in a buffer accessible to other kernel functions. In order to "speak" to the device, you will have to follow a protocol. Usually, for simple examples it is PS/2. You'll find extensive documentation over https://wiki.osdev.org/PS/2_Keyboard.
Also, you can check this simple example here: https://github.com/TretornESP/StolenOS/blob/main/keyboard.asm
Basically what install_handler does is to alter the IDT to point the 9th entry to the function keyboardHandler.
keyboardHandler searches for a specific code in the device's memory. If found, uses a keyboard map file to translate ps/2 codes to ASCII characters and stores them in a buffer until the return key is pressed.
This approach is as simple as it gets without polling.

writing hex file to RAM in ARM Cortex-M

I am doing an ongoing project to write a simplified OS for hobby/learning purposes. I can generate hex files, and now I want to write a script on the chip to accept them via serial, load them into RAM, then execute them. For simplicity I'm writing in assembly so that all of the startup code is up to me. Where do I start here? I know that the hex file format is well documented, but is it as simple as reading the headers for each line, aligning the addresses, then putting the data into RAM and jumping to the address? It sounds like I need a lot more than that, but this is a problem that most people don't even try to solve. Any help would be great.
way too vague, there are many different file formats and at least two really popular ones that use text with the data in hex. So not really helping us here.
writing a script on chip means you have an operating system running on your microcontroller? what operating system is it and what does the command line look like, etc.
assembly is not required to completely control everything (basically baremetal) can use asm to bootstrap C and then the rest in C, not a problem.
Are you wanting to download to ram and run or wanting to download and then burn to flash to reset into in some way?
Basically what you are making is a bootloader. And yes we write bootloaders all the time, one for each platform, sometimes borrowing code from a prior platform sometimes not.
First off on your development computer, windows, mac, linux, whatever, write a program (in C or Pascal ideally, something you can easily port to the microcontroller) that reads the whole file into an array, then write some code that basically accepts one byte at a time like you would if you were receiving it serially. Parse through that file format whatever format you choose (initially, then perhaps change formats if you decide you no longer like it) take real programs that you have built which the disassembler or other tools should have other output options to show you what bytes or words should be landing at what addresses. Parse this data, printf out the address/byte or address/word items you find, and then compare that to what the toolchain showed. carve the parsing tool out and replace the printf with write to memory at that address. and then yes you jump to the entry point if you can figure that out and/or you as the designer decide all programs must have a specific entry point.
Intel hex and motorola s-record are good choices (-O ihex or -O srec, my current favorite is --srec-forceS3 -O srec), both are documented at wikipedia. and at least the gnu tools will produce both, you can use a dumb terminal program (minicom) to dump the file into your microcontroller and hopefully parse and write to ram as it comes in. If you cant handle that flow you might think of a raw binary (-O binary) and implement an xmodem receiver in your bootloader.

C printf to custom hardware [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have existing code with various debug messages. Our embedded system does not have an external connection for a terminal. I want to modify the printf so that its output goes to a memory location, rather than STDOUT, which is mapped to a FIFO. I guess I need to find write my own outbyte/outnum. Just cant seem to find the GNU code where I can grab things.
I am running a microblaze processor inside an Xilinx FPGA. All print statements are for debugging. We are running GNU tools (Xilinx SDK). For development, was able stick an UART in the design and wire the uart to a few test points.
As we get ready to deploy, I will no longer have this visibility. We do have a USB-to-Serial connecton, but it looks like a fifo, not a serial port to the embedded system. We have a protocol for sending messages over this link. I was thinking of adding a debug message to our protocol. I would like to redirect my print statement to a buffer, and then process this buffer.
I was trying to take the existing printf (xil_printf) and create my own cc_printf, by rewriting the outbyte code, but just not able to dig down in the code far enough to see how to do it. (Frankly, I am VHDL/hardware guy).
Overall code size is tens of thousands of lines of C code. My section is maybe 3-4 thousand lines of code. The basic operation is for software/hardware updates of the system to come in via the USB port and moved to FLASH memory. My code parses incoming packets coming over the USB-to-serial link. Basically there is a bit set that tells me that there is a packet ready in a receive buffer. I process the packet and write to FLASH. As part of the protocol, there are ACK/NACKs/ABorts. I currently use the printf to printout statuses to my lab bench version of the system.
As stated, I would like to embed these printouts into our protocol. I am not married to printf, and would use some other print-function. I would like to print out messages and data. If something else would be a better starting point, I am fine with that. It seems that the biggest issue for me is grabbing the output of the print and directing it where to go.
Don't use printf directly, for debugging purposes.
Use a macro, perhaps something like
#define DEBUGPRINTF(Fmt,...) do \
{printf("%s:%d: " Fmt "\n", __FILE__, __LINE__, __VA_ARGS__);} while(0)
Then, once you have converted all your debug printf (and only these) to DEBUGPRINTF you just need to change the definition of that macro (e.g. on the embedded system, perhaps using snprintf ...).
So in the rest of your code, replace a printf("debugging x=%d\n", x); with DEBUGPRINTF("debugging x=%d", x); but do that only for debugging prints. BTWK 4KLOC (for your part) is really tiny, and even 200KLOC (for the whole thing) is small enough to make that replacement doable "by hand" (e.g. Emacs "find & replace interactively").
(I am guessing that you are first developing a small piece of code -a few thousand lines- on your laptop, and later porting it to the embedded system)
Once you have converted all your debug printf to DEBUGPRINTF (and only the debugging prints!) you can redefine that macro, perhaps inspired by
#define DEBUGPRINTF(Fmt,...) do \
{snprintf(debugbuffer, sizeof(debugbuffer), Fmt, __VA_ARGS__); } while(0)
(I guess that you'll need to add something more in that macro -probably before the closing brace- to actually send the debug output -that is the content of debugbuffer- somewhere, but how to do that is implementation & system specific)
But more likely you'll disable the debug printf with
#define DEBUGPRINTF(Fmt,...) do{}while(0)
BTW, the embedded target system might not even have any snprintf ...
If you want to study some readable C standard library implementation (on Linux) consider looking inside musl-libc source code. You'll need to understand what system calls are.
Actually, you should in fact write and debug your code on your laptop (e.g. running Linux) and only put on the embedded system something which you believe has no bugs. In practice, avoid deploying code with debug printfs (or think in advance of something much better). See also this.
It seems that the biggest issue for me is grabbing the output of the print and directing it where to go.
Probably use snprintf then "send" the debugbuffer to the appropriate place using appropriate primitives. With snprintf you know the size of the message (e.g. with the return value from snprintf and/or using %n in the format control string). Or have your own logging or debugging variadic function (using <stdarg.h> and va_start etc ....)
Do not confuse debugging messages with logging messages. If you want logging, design it carefully. But debugging messages should probably be removed at deployment time.
The Posix function fmemopen allows you to open a memory buffer like a file and returns a FILE * that can be used with the standard IO functions, like fprintf. As far as printing to a device that's not a serial port, I don't know what OS (of any) you are running on, but if present you could write a stream device driver for that custom device and set your stdout and stderr (and maybe stdin) to that. If you're running without an OS then somewhere someone has created a FILE structure that in interfacing with the serial port somehow, and printf is using that.

What are the benefits to using BIO_printf() instead of printf()?

I have been reviewing example code for using OpenSSL and in every example I locate, the creator has chosen to use BIO_printf() to write things to stdout instead of printf().
I have taken their code, removed the openssl/bio.h header declaration, and changed all calls to BIO_printf() to regular printf() statements. The programs ran with identical results.
The problem I'm grasping with is why these coders use BIO_printf() when it takes a lot more to setup than just using printf(). You have to include another header (which will increase program size), you need to set the file pointer to the stream you want to write to. Then you can print your message to stdout. It seems a lot more complicated than using printf().
When I do a search on BIO_printf() it lists possible man pages for BIO_printf (3), but none of the pages actually contain any information!
I decided to do a benchmark test on both methods. I looped printf("Hey\n"); 1,000,000 times. Then I did it for BIO_printf(fp, "Hey\n");. I only timed the BIO_printf() statement and not the setting up of the file pointer (which would have increased the time). The difference came out to printf() being ~4.7x faster than using BIO_printf().
Why are they using it? What is the benefit? It's my understanding that in programming you either want code to be simple or efficient, and in the case of BIO_printf() it's neither.
In general, a BIO might not be writing to stdout.
You can have a BIO that writes to a file, or null, or a socket, or a network drive, or another BIO, etc.
By using the BIO_printf family, the code can easily be changed to have its output sent to a different location or another BIO which might do some further filtering and then pass the output onto wherever else.
As pointed by others, BIO can be stacked contrary to FILE. snprintf() and vnsprintf() were added in C99. OpenSSL/SSLeay is older than this. Hence, the SSLeay developpers had to write their own implementation. Unfortunately, having a little used implementation leads to the performance issues described by the OP or to CVE-2016-0799.

C - Read Directly From the Keyboard Buffer

This is a question in the C programming language.
How do I directly read the data in the keyboard buffer?
I want to directly access the data and store it in a variable. Of what data type should the variable be?
I need it for an operating system our institute is currently developing. It's called ICS-OS and I am not quite sure about the specifics. It runs on x86, 32-bit machines (we run it on QEMU in a Linux box). Here is the link for the Google Code http://code.google.com/p/ics-os/. I hope that's sufficient enough information.
The operating system does not support the conio.h library so kbhit is not an option.
This is really platform dependent.
If this is for Windows, the most direct access to a "keyboard buffer" is using WM_INPUT and GetRawInputData. See Using raw input with example for both keyboard and mouse.
Another DOS / Windows specific way are conio.h functions getch() / kbhit().
Portable library is called Curses and has ports for both Linux and Windows.
However, as you are targeting quite specific OS, you need to check the docs for that OS.
The most direct platform independent way is getchar / scanf / anything which reads from stdin, but stdin is line buffered, therefore you will get no data until enter is pressed. You may be able to change the buffering settings, but again, this is platform dependent and may be not possible on some platform. See a related discussion of setbuf(stdin,NULL).
Have you tried looking at the source code of the linux kernel for the keyboard driver?
Take a look at /drivers/input/keyboard/xtkbd.* for a simple XT keyboard driver.
Also, here's an article which briefly explains how it's done.
if you want to directly read data from keyboard buffer then you can user getchar or getc!
This is read from keyboard buffer
scanf("%d",&myvariable);
but you have to use
"%d" for int ,"%f" for float ,%e for double ,"%c" for char , "%s" for strings to identifing type which has to match type of your variable.

Resources