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.

File browser example

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 :

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

The file headers are currently 6-bytes wide. These bytes correspond to :

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.