RIOT OS - "stdout" for embedded platforms - c

I'm trying out RIOT OS for the first time. After downloading source, I can build applications pretty easily, including targets that need the ARM toolchain.
The hello-world application runs fine on my Linux build machine (built using BOARD=native) and prints in the terminal.
When I switch to an embedded platform (Nucleo F411 e.g. ARM Cortex M4) where can I expect any puts() or printf() calls to appear? Further, how can I setup printf() to go to UART1 if that's not where it's going already?
Apologies if this is too specific for SO. I'm not familiar with the RIOT OS mailing lists but I'll try there as well.
EDIT: The hello-world example is really bare bones, as follows:
#include <stdio.h>
int main(void)
{
puts("Hello World!");
printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD);
printf("This board features a(n) %s MCU.\n", RIOT_MCU);
return 0;
}
I am compiling with the ARM GNU toolchain, gcc-arm-none-eabi-7-2017-q4, after following install instructions here: link. I figure I am going to need some extra compiler flags, or editing the board init functions outside the application code above. But, at this stage, I don't know where to start. My end goal is to observe "Hello World!" and "You are running..." on pin TX/D1 of my dev kit after configuring it to go there.

In RIOT OS, by default the stdio is mapped to UART0. This can be seen here:
https://github.com/RIOT-OS/RIOT/blob/master/sys/include/stdio_uart.h#L38
By redefining STDIO_UART_DEV you can map the stdio to a different UART. If you want to know which UART is mapped to which pins, have a look in the periph_conf.h of your board, which in case of the Nucleo F411 is here:
https://github.com/RIOT-OS/RIOT/blob/master/boards/nucleo-f411re/include/periph_conf.h#L56

The toolchain you are using uses the Newlib C library (rather than GNU's libc which has POSIX dependencies). To port newlib to your target, some standard functions require re-implementation of at least some of the syscalls stub.
Specifically for stdout to work, you need to implement at least _write_r(). If the UART is the only device you will ever support, you can ignore the file descriptor - for stdout it will always be 1 (0 = stdin, 2 = stderr).
As an aside if you want malloc() et al to work, you need ot implement _sbrk_r().
Bill Gatliff's article on embedded.com provides examples for Newlib porting for uC/OS - the principles are probably similar for RIOT OS, but equally you could make it simpler if your library I/O needs do not need to be that sophisticated.

On embedded systems the user has to implement the function putchar(char chr) to output a single char. This function can use UART for example.
The function should look something like:
int fputc(int ch, FILE *f)
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 100);
return ch;
}
Here you find a more complex example for an STM32F0
https://github.com/bjornfor/stm32-test/blob/master/STM32F0xx_StdPeriph_Lib_V1.0.0/Project/STM32F0xx_StdPeriph_Examples/USART/Printf/main.c

Embedded microcontroller system compilers fall into a category called freestanding implementations. This means that they don't have to provide libraries like stdio.h and you can't expect printf to be available.
There is however a probability that there's a compiler library implementing stdio.h through UART transmission. You will have to check if your compiler implements this or not.
Just for simple tests and "hello world"-like applications, it is far easier just to use GPIO pins. The embedded systems equivalent of "hello world" is to flash a LED.

Related

How does C programming work with no headers?

I'm familiar with the C programming language and z80 assembly and I have made a simple z80 "computer" with just the cpu with 32k of ram, 32k of rom, and an 8255 pia for io control. I have gotten the 8255 to bling an LED with my system through an assembly language subroutine.
So the question is: If there is the SDCC(Small Device C compiler) that can compile a C program into assembly for various small CPUs including the z80, How do you create a C program if there are no stdio libraries or any libraries of any kind because of how custom this system is.
Am i forced to use assembly first then make and call a function as an ASM routine? Am I misunderstanding some sort of key idea? Im quite confused on how this works. I cant just printf() on a system with no output. Not to mention printf() is under the assumption that a terminal is connected of some kind.
You would write a platform specific I/O library that utilises whatever I/O capability your platform has available. On many embedded systems a minimal standard I/O is implemented on a UART serial port so your "console" can be a terminal emulator on a host PC.
Your I/O API need not be as sophisticated as the standard library's stdio. It also need not be written in assembler, register-level access of memory-mapped peripherals is possible (in fact normal) in C - it is a systems level language after all.
All that said, SDCC already includes a standard library subset that includes a subset stdio. So it is not clear why you think you lack that support. You do have to provide low level platform specific support, but to support printf you need only implement putchar() to emit a character on your chosen stdout device. For unbuffered serial output that is rather trivial. A more sophisticated implementation might use interrupt driven, buffered serial output. The porting of the library is described in the SDCC manual.
You are right. An assembly routine contains the actual entry point, where memory initialization is done, and that routine then calls main().
sdcc/device/lib/z80/crt0.s contains the default startup code provided by SDCC.
If your system needs more stuff to be done than that provides, refer to section 3.12.3 of the SDCC manual on how to supply your own.
As for printf(), you just need to supply putchar() somehow. If it's simply an out instruction to some device, you can just chuck it in the crt0.s as well, like this:
.area _CODE
init:
call 0x01B0 ; ROM_CLEAR_SCREEN
;; Initialise global variables
call gsinit
call _main
_exit:
call 0x0200 ; ROM_GET_KEY
jr z, _exit
call 0x01B0 ; ROM_CLEAR_SCREEN
ret
_putchar:
ld hl, #2
add hl, sp
ld a, (hl)
out (0xBC), a
ld hl, #0
ret

Is it possible to modify a C program which is running?

i was wondering if it is possible to modify a piece of C program (or other binary) while it is running ?
I wrote this small C program :
#include <stdio.h>
#include <stdint.h>
static uint32_t gcui32_val_A = 0xAABBCCDD;
int main(int argc, char *argv[]) {
uint32_t ui32_val_B = 0;
uint32_t ui32_cpt = 0;
printf("\n\n Program SHOW\n\n");
while(1) {
if(gcui32_val_A != ui32_val_B) {
printf("Value[%d] of A : %x\n",ui32_cpt,gcui32_val_A);
ui32_val_B = gcui32_val_A;
ui32_cpt++;
}
}
return 0;
}
With a Hex editor i'm able to find "0xAABBCCDD" and modify it when the program is stopped. The modification works when I relauch the program. Cool !
I would like to do this when the program s running is it possible ?
Here is a simple example to understand the phenomena and play a little with it but my true project is bigger.
I have an old DOS game called Dangerous Dave.
I'm able to modify the tiles by simply editing the binary (thanks to http://www.shikadi.net/moddingwiki/Dangerous_Dave)
I developped a small editor that do this pretty well and had fun with it.
I launch the DOS game by using DOSBOX, it works !
I would like to do this dynamically when the game is running. Is it possible ?
PS : I work under Debian 64bit
regards
I was wondering if it is possible to modify a piece of C program (or other binary) while it is running ?
Not in standard (and portable) C11. Read the n1570 specification to check. Notice that most of the time in practice, it is not the C source program (made of several translation units) which is running, but an executable result of some compiler & linker.
However, on Linux (e.g. Debian/Sid/x86-64) you could use some of the following tricks (often with function pointers):
use plugins, so design your program to accept them and define conventions about your plugins. A plugin is a shared object ELF file (some *.so) containing position-independent code (so it should be compiled with specific options). You'll use dlopen(3) & dlsym(3) to do the dynamic loading of the plugin.
use some JIT-compiling library, like GCCJIT or LLVM or libjit or asmjit.
alter your virtual address space (not recommended) manually, using mprotect(2) and mmap(2); then you could overwrite something in a code segment (you really should not do that). This might be tricky (e.g. because of ASLR) and brittle.
perhaps use debug related facilities, either with ptrace(2) or by scripting or extending the gdb debugger.
I suggest to play a bit with /proc/ (see proc(5)) and try at least to run in some terminal the following commands
cat /proc/self/maps
cat /proc/$$/maps
ls /proc/$$/fd/
(and read enough things to understand their outputs) to understand a bit more what a process "is".
So overwriting your text segment (if you really need to do that) is possible, but perhaps more tricky than what you believe !
(do you mind working for several weeks or months simply to improve some old gaming experience?)
Read also about homoiconic programming languages (try Common Lisp with SBCL), about dynamic software updating, about persistence, about application checkpointing, and about operating systems (I recommend: Operating Systems: Three Easy Pieces & OsDev wiki)
I work under Debian 64bit
I suppose you have programming skills and do know C. Then you should read ALP or some newer Linux programming book (and of course look into intro(2) & syscalls(2) & intro(3) and other man pages etc...)
BTW, in your particular case, perhaps the "OS" is DOSBOX (acting as some virtual machine). You might use strace(1) on DOSBOX (or on other commands or processes), or study its source code.
You mention games in your question. If you want to code some, consider libraries like SDL, SFML, Qt, GTK+, ....
Yes you can modify piece of code while running in C. You got to have pointer to your program memory area, and compiled pieces of code that you want to change. Naturally this is considered to be a dangerous practice, with lot of restrictions, and with many possibilities for error. However, this was practice at olden times when the memory was precious.

Difference between printf in Windows and Linux

Actually other than the core C language, there is a C library. And if my understanding is right, functions like printf are part of C library. Now I have programmed in C in Turbo C in Windows as well as using gcc in Linux.
My question is: Are the code implementations of functions like printf the same in both Windows and Linux? Ultimately the printf function has to call a function in core OS (in both cases) that would display ASCII characters onto the screen? So since both the OS are different, will the implementation of code for printf be also different in both the cases?
Of course the implementation (of printf and all functions in <stdio.h>) is different (on Linux and on Windows), but the behavior should be conforming to the specification in the C11 or C99 standard.
Notice that printf does not show characters on the screen, but send them to the standard output (see printf(3)). Something else -e.g. the kernel tty layer and your terminal emulator on Linux- is displaying the characters on your screen (or elsewhere!).
On Linux and POSIX systems, <stdio.h> is ultimately using system calls to write data to a file descriptor. It would be write(2) (for printf) and the list of system calls is available in syscalls(2). Be aware that stdout is usually buffered (notably for performance reasons; making a write syscall for every written byte would be too costly). See fflush(3) & setvbuf(3). Try using strace(1) on your Linux program to understand the actually used syscalls.
On Windows, there is some equivalent thing (except that the list of syscalls on Windows is less documented and is very different).
BTW, GNU/Linux is mostly free software. So read Advanced Linux Programming then study the source code: the libc is often glibc (but could be musl-libc, etc... so you can have several implementations of printf on Linux, but usually you have one libc.so, even if you could have several ones), the kernel source is available on kernel.org.

Taking input without using libc

How would I take input or print output without using libc? I can use system calls, but didn't know if that would help.
There is no platform-independent way to do this. In fact, the whole point of having libc is to have a common interface to a set of functionality that most systems provide, but do so in fundamentally different ways.
Your best option would probably be to consult the documentation for whatever system you are currently using. You could look up your OS's set of interrupts and then try using the asm keyword to write assembly instructions that tell the OS to read input or display output. You could look into libraries provided by the OS for doing input and output on file descriptors, then use those functions instead. Or, you could look at process creation libraries, then spawn off a process to read or write data from the console, where the second program uses libc. None of these are guaranteed to be at all portable, though.
Hope this helps!
I stepped through write(2) with gdb to get an idea of how the system call ABI works.
Anyway, no libc at all. Note that without special tricks, the cc(1) compiler/linker front-end will still link you with libc, but you won't be using it for anything. The C runtime start-up code will make some libc calls, but this program won't.
void mywrite(int fd, const void *b, int c) {
asm("movl $1, %eax");
asm("syscall");
}
int main(void) { const char *s = "Hello world.\n"; return mywrite(1, s, 13), 0; }

Getting the coordinate of mouse click in C

I found this header file on google to perform mouse related events in C program but i am having no idea of int86 union REGS i,o; and what are other int86 type functions available in C? I am using windows OS and Turbo C.
#include<conio.h>
#include<stdio.h>
#include<dos.h>
initmouse();
void showmouseptr();
void restrictmousept(int,int,int,int);
void getmousepos(int *,int *,int *);
void hidemouseptr();
union REGS i,o;
initmouse()
{
i.x.ax=0;
int86(0x33,&i,&o);
return(o.x.ax);
}
void showmouseptr()
{
i.x.ax=1;
int86(0x33,&i,&o);
}
void restrictmouseptr(int x1,int y1,int x2,int y2)
{
i.x.ax=7;
i.x.cx=x1;
i.x.dx=x2;
int86(0x33,&i,&o);
i.x.ax=8;
i.x.cx=y1;
i.x.dx=y2;
int86(0x33,&i,&o);
}
void getmousepos(int *button,int *x,int *y)
{
i.x.ax=3;
int86(0x33,&i,&o);
*button=o.x.bx;
*x=o.x.cx;
*y=o.x.dx;
}
void hidemouseptr()
{
i.x.ax=2;
int86(0x33,&i,&o);
}
This looks like old code for MS-DOS to user the x86 interrupts to call system functions to get mouse coordinates. I would be surprised if this code still works in a command prompt of any modern computer. In fact, the header file at the top including dos.h would give this away.
in86() is how you "interrupt" the CPU in DOS mode. It is sort of the way functions are called in modern day operating systems. More info here: http://wiki.answers.com/Q/What_is_the_INT86_function_in_C_programming
A union is a method in C of defining data which can be accessed in different ways. More here: http://www.go4expert.com/forums/showthread.php?t=15.
It is unclear what you are trying to do, let alone what operating system you are running under. You probably want to pick a language first (C# might be a good start, assuming you are using Windows) and then look at the base class library for WinForms to learn how to respond to mouse events. There are fine tutorials on WinForms which will teach you how to respond to the mouse.
Discard that code: it is old 16-bit DOS which probably is not what you want.
It seems you're rather new to C. In that case, a better advice is to study well the language; check around the site for good learning references. "The C Programming Language", by Dennis Ritchie and Brian Kernighan is a good starting point.
Having said that, there are no int86 functions "in C". These are Borland Turbo C extensions. That was how one could manipulate the mouse in DOS, but nowadays it is different.
Note that the C language is, fundamentally, simply a programming language. It is intended to express algorithms. However, the C language standard also gives you a standard library: a set of predefined types, functions and macros you can use, to save time and portability. This library addresses some basic functionality, and mouse input handling is not one of them.
In other words, after you have studied C, you'll be ready to deal with specific operating system's APIs. This is needed, because the C standard library offers no way to manipulate any sort of input devices. You will also study some fundamentals regarding how input is handled in modern operating systems. For example, to handle mouse input you will most likely need to create a window (or widget) in order to receive mouse events -- implying that you will have to read a bit about the underlying windowing API.
There are some libraries which accesses the system's APIs for you and factor out the differences, offering you a programming alternative. It should be no different, though, from studying and using the system's API directly, except possibly for enhanced portability.
The int86 function calls the DOS Mouse Interrupt 33h. A dos interrupt is specific to the msdos operating system, so your code is only usable under msdos. 'union REGS' are the input and output registers that are used as parameters for the DOS interrupt. A DOS interrupt is similar to a system call in other operating systems.
You could use dosbox if you want to run turbo C programs under Windows/Linux etc
For example, on Windows, just make a desktop link that runs a batch script to run your program in dosbox, this is how the steam version of Doom works I think

Resources