Emulating 8051 serial port communication on Linux

The Intel 8051 is a microcontroller architecture that has many applications (from hobbyists to industry) and many incarnations (Atmel, Infineon, NXP, …). It is often necessary to communicate with the microcontroller through a serial port, with a program running on the 8051 and a program running on a computer. In this case, I think it can be useful to emulate the connection without using a real 8051 chip and a physical cable; this would speedup prototyping and development, while easing the debug phase. The trick is to use socat to emulate a serial connection and uCsim to emulate an 8051 chip. We will create a system like the one in figure:

These software components are needed:

socat: connects two communication channels of any type.

SDCC: the Small Device C Compiler.

uCsim: a simulator for many microcontrollers (developed together with SDCC on sourceforge).

screen: among many other things, it connects to a terminal device (minicom or gtkterm can be used instead).

In order to install everything on a Debian-based Linux system (like Ubuntu) run as root:

apt-get install sdcc sdcc-ucsim socat screen

Create a file called serialtest.c that will be the program running inside the 8051 emulator:

#include <mcs51/8051.h> #include <stdio.h> #include <ctype.h> char getchar (void) { char c; while (!RI); /* wait to receive */ c = SBUF; /* receive from serial */ RI = 0; return c; } void putchar (char c) { while (!TI); /* wait end of last transmission */ TI = 0; SBUF = c; /* transmit to serial */ } void UART_Init() { SCON = 0x50; /* configure serial */ TMOD = 0x20; /* configure timer */ TH1 = 0xE6; /* baud rate 1200 */ TL1 = 0xE6; /* baud rate 1200 */ TR1 = 1; /* enable timer */ TI = 1; /* enable transmitting */ RI = 0; /* waiting to receive */ } void main() { UART_Init(); for(;;) { char c; c = getchar(); c = toupper(c); putchar(c); } }

The program receives a byte at a time, and returns it to the sender converted into uppercase.

Compile the C program into a Intel Hex file:

sdcc -mmcs51 serialtest.c -o serialtest.ihx

The following command creates two pseudo-terminals ( tty1 and tty2 ) in the current directory; the terminals are connected with each other like a physical serial cable.

socat -v -x PTY,link=./tty1 PTY,link=./tty2

The “ -v -x ” options print the bytes that are transmitted through the channel, indicating also the direction and the ASCII code.

Open another shell terminal, and execute the serialtest program using the uCsim 8051 simulator:

s51 serialtest.ihx -s ./tty1

The simulator connects to the first pseudo-terminal and then offers a prompt; execute a “ run ” command to start the compiled program.

To connect with the simulator from the other side of the channel, open another shell terminal and run:

screen ./tty2

The program will connect to the second pseudo-terminal and will communicate with the 8051 program through socat . By typing letters inside the screen, the terminal will display that letter uppercased by the 8051 program, and the exchanged data will be displayed in the socat log.

When it’s time to migrate to real hardware the 8051 C program will remain the same, and the computer software (in this case screen) just needs to open a different terminal, like /dev/ttyS0 (if using a RS232 connection) or /dev/ttyUSB0 (if using a USB cable) instead of a pseudo-terminal.

45.447224 8.599690