Hardware
Controller
This device is controlled by an ATmega328P programmed on an Arduino Uno for prototyping. It will be detached from the board on later stages of development.
I/O
User input comes from a 16 buttons membrane keypad. Software currently only supports a single button pressed at a time, it will be improved as new functionalities are added.
The output is a simple 16 character × 2 lines LCD display.
Peripherals and pins
The buttons and the display are connected directly to the Arduino board for now. I will later use chips like serial registers to free some I/O pins.
Storage
Data and file storage is kept in MCU's EEPROM. The first prototype is still under development so a simple 1024 kB memory storage is enough but data will ultimately be stored in an external EEPROM or SD card.

Software : Operating System and Code Execution
The Operating System programmed on the controller implements a fully custom file system, a file browser, a code editor and a code executor. The whole Arduino project is available freely on my github, I'm always working on it.
Task Resources
The microcontroller's dynamic memory can store 2048 bytes of data. Let's say half of that is used by the operating system itself, then 1024 bytes can be used as user memory for programs. I want programs to be able to call other programs, to use them as functions for example. Programs will be able to allocate chunks of memory within these 1024 available bytes.
Task Abilities
Programs can use the kernel for certain operations using system calls :
- Input using buttons
- Output using the screen display
- Input/Output using on-board pins (or maybe serial registers)
- File access
- Execution of other programs
Emulated Programming Language
Programming language is based on Instruction List (IL). General instructions are written in uppercase whereas system calls are written in lowercase.
I programmed most of the instructions and I've been able to execute simple programs with arithmetics and logic, and interracting with the screen display and the buttons.
I often change my mind about how the device is supposed to work. Latest details about the operating system are available on the project's Github, in the docs folder on the dev branch.
The instructions as of 20/03/23 are as follow :
General Instructions
I
: 1-byte Integer
Load and Store Instructions
Code | Keyword | Description |
---|---|---|
1 |
LD I |
Load value into accumulator (acc ) |
20 |
LD.. I |
Load register at double redirection of I into acc () |
2 |
ST I |
Store acc value into specified register |
Logic Instructions
Code | Keyword | Description |
---|---|---|
3 |
AND I |
Perform a bitwise AND operation with acc |
4 |
OR I |
Perform a bitwise OR operation with acc |
5 |
NOT |
Perform a bitwise NOT operation on acc |
6 |
XOR I |
Perform a bitwise XOR operation with acc |
Arithmetic Instructions
Code | Keyword | Description |
---|---|---|
7 |
ADD I |
Add value to acc |
8 |
SUB I |
Substract value from acc |
9 |
MUL I |
Muliply value with acc |
10 |
DIV I |
Divide value by acc (integer) |
11 |
MOD I |
Return the remainder of the division of acc by I |
Comparison Instructions
Code | Keyword | Description |
---|---|---|
12 |
EQ I |
Test if acc is equal to I |
13 |
GT I |
Test if acc is greater than I |
14 |
LT I |
Test if acc is lesser than I |
15 |
GE I |
Test if acc is greater than or equal to I |
16 |
LE I |
Test if acc is lesser than or equal to I |
Jump Instructions
Code | Keyword | Description |
---|---|---|
17 |
JMP I |
Ignore a specified number of bytes |
18 |
JMPC I |
Jump if test is TRUE |
19 |
JMPNC I |
Jump if test is FALSE |
System calls :
General
Code | Keyword | Description |
---|---|---|
-1 |
ext |
exit program |
-2 |
slp I I |
sleep for a specified amount of time (in milliseconds) (2-byte integer, Most Significant Byte first) |
-3 |
lab I |
place a label for syscall jumps |
-4 |
jmp I |
go to label |
-5 |
ldm I1 I2 |
load the next I1 bytes of program memory to variable memory at address I2 |
Screen Display
Code | Keyword | Description |
---|---|---|
-6 |
pch I1 I2 |
print char I1 on the screen at slot I2 |
-7 |
pst I1 I2 |
print string of length I2 stored in memory at I1 |
Button Input
Code | Keyword | Description |
---|---|---|
-8 |
gch |
get raw input |
-9 |
tch I |
translate raw input to char |
-10 |
gst I1 I2 |
get string of size I2 and write at address I1 |
GPIO
Code | Keyword | Description |
---|---|---|
-11 |
rpn I |
read pin I |
-12 |
wpn I |
write pin I |
File system
Code | Keyword | Description |
---|---|---|
-13 |
opn STR |
open file at path STR |
-14 |
clo |
close file |
-15 |
ldd I I |
load next I bytes of data from open file to memory at adress I |
-16 |
opp STR |
prepare execution of program at path STR by allocating its memory. Values can be entered before its execution |
-17 |
exe |
execute loaded program |
-18 |
pss |
end current program then execute loaded program |
Data Organization
The file system aims to be very simple and lightweight. There is no file owner, no timestamp, no permissions, just a file name and pointers to related files (see #File Hierarchy).
The memory is split into three areas :
- File headers
- Block map
- Block area
File headers
The file headers are currently 6-bytes wide. These bytes correspond to :
- 1 : File flags
- 2 : Data Pointer
- 3 : Parent File Pointer
- 4 : Child File Pointer
- 5 : Previous File Pointer
- 6 : Next File Pointer
File Flags
The most significant bit of the flags byte is used to mark the file header as free (0) or reserved (1). The second bit marks directories. The third bit marks executables. Other bits do not have a purpose yet.
Data Pointer
This byte represents a data block ID (See ##Block Area). A file only points to one data block, the others are chained together from this first data block. The file name is located in the first data block of a file, so even directories have an allocated data block.
Related Files Pointers
The other bytes are pointers to parent
, child
, previous
and next
files (See #File Hierarchy), specifically pointers to their file headers. A file header pointer corresponds to the target file's header ID. That means the file header of ID 13 is at memory address 6*13 (13th 6-byte header)
Block Map
The block map keeps track of available and reserved data blocks. Each bit of the block map represents a data block. 1 is reserved and 0 is free.
Block Area
The Block Area contains the data blocks, which stores files' data. The first two bytes of the block store previous block's and next block's ID. A null ID is considered not linked to another block. This is not a problem because the block of ID 0 is reserved for the root directory.
File names are stored in the first data block as the first string of the file (until the first null byte).
File hierarchy
To easily implement the concept of file hierarchy. Each file/directory may have four related files :
+------+
|Parent|
| File |
+------+
|
+------+ +-------+ +------+
| Prev |__|Current|__| Next |
| File | | File | | File |
+------+ +-------+ +------+
|
+------+
|Child |
| File |
+------+
Note : A file normaly cannot be related to four other files at once.
A directory registers only one of the file it contains. This file is registered as the directory's child file. All other files in the directory are chained together with the next/previous file relations. They do however all have the directory as their parent file.
Example :
Usual representation :
dir/
+---dir2/
| +---file4
| \---file5
+---file1
+---file2
\---file3
Headers links :
+------+
| dir |
+------+ dir dir dir
| | | |
+------+ +-------+ +-------+ +-------+
| dir2 |--| file1 |--| file2 |--| file3 |
+------+ +-------+ +-------+ +-------+
|
| dir2
| |
+-------+ +-------+
| file3 |--| file4 |
+-------+ +-------+
Note that this representation can be used 'illegaly' to implement simlinks for example.
Root directory and invalid IDs
When a file do not have a child, next or previous file, the pointer is 0. The header with ID 0 does exist and stores the root directory. This is not a problem because the root directory cannot be a next, previous or child file of any file. It can however be a parent file, but every file has to have a parent file so this is not a problem.