3

I am writing my first Forth (on ARM). I want it on bare metal, since I think that is the whole point of Forth. However, I was unable to find information and examples on how to write KEY, EMIT and friends (essentially, handle the keyboard) without Linux syscalls. I also tried to read a bootloader source (U-Boot), but it's clearly out of my depth.

Can you please help me write a keyboard handler loop and REPL in bare metal ARM assembly? something like that, but for ARM. I am using a Cortex-A8 CPU (ARMv7).

Raoul
  • 1,872
  • 3
  • 26
  • 48
  • 4
    It depends on how exactly keyboards are supported on your computer, but it probably involves writing a USB stack. Note the example given in the answer to the question you linked isn't "bare metal" but uses the firmware (BIOS) to read the keyboard. – Ross Ridge Sep 24 '18 at 21:18
  • @RossRidge So essentially, there is no way short of writing my own bootloader or using an existing one? Does a bootloader such as U-Boot have equivalents to Linux syscalls? – Raoul Sep 24 '18 at 21:26
  • 1
    Bootloaders usually specialize into only loading the kernel binary into memory, they implement next to none services. In x86 world they often also switch the machine into target mode and do some basic memory mapping settings, etc, but the less OS-specific bootloader is, the more different kernels it can support. Doesn't your machine have some BIOS firmware providing already the USB keyboard driver? That would made it lot more simpler, writing of own USB firmware is quite some project... (if you have USB keyboard, but I guess you probably have? Or is the default keyboard connected other way?) – Ped7g Sep 24 '18 at 21:50
  • 1
    @Ped7g I am trying to use a BeagleBone Black. So it has a flashable boot sector, and it seems the bootloader handles peripherals (from what I read). – Raoul Sep 24 '18 at 22:27
  • 4
    I think you are confusing what baremetal is. That means write your own stuff if it doesnt exist. If you want to just make calls to some api then just put an operating system on it. u-boot is damn near almost an operating itself, and is doing much of the work that you would be doing baremetal. understandable though as a number of things in u-boot are not documented for NDA reasons for a particular vendor so you would have to reverse engineer the u-boot source code anyway or find info from someone who has. – old_timer Sep 24 '18 at 22:52
  • 5
    if you want baremetal input use the uart and a dumb terminal. – old_timer Sep 24 '18 at 22:53
  • You can also have a look at a cool implementation of Forth on ARM: [Mecrisp-Stellaris](http://mecrisp.sourceforge.net/). I tried it on [1-Bitsy](https://1bitsy.org/overview/introduction/) - but note that the baud rate is 357,149, not 115,200 due to the different crystal oscillator frequencies (8 MHz vs. 25 MHz). Luckily, the standard baud rate 360,000 is close enough (0.8% deviation) to work. Pasting in the terminal has issues (e.g. using PuTTY) as the terminal program needs to wait for the "ok" from Forth (otherwise the input buffer overflows) - or alternatively slow down character rate. – Peter Mortensen Oct 07 '18 at 21:18
  • Note that the whole flash memory ***really must be cleared*** before flashing Mecrisp-Stallaris... Also, 1-Bitsy is capable of 168 MHz (by PLL clock multiplication). This will raise the baud rate to 2,419,200 (2.4 Mbit/s). A workaround is to lower the baud rate at 360,000 directly from Forth, drop to that lower speed in the terminal, set the PLL for 168 MHz, and connect at the new baud rate. As far as I know these changes can easily be made permanent (so they only need to be done once), but I haven't tried that yet. – Peter Mortensen Oct 07 '18 at 21:30

1 Answers1

5

Given that your target is a BeagleBone Black (mentioned in a comment), I assume you're thinking of a USB keyboard. If so, old_timer's comment that you're 'confusing what baremetal is' is entirely correct. If you're really coding on bare metal, then you don't have a USB driver stack, so you're not going to be reading from a USB keyboard.

It is possible that whatever bootloader you choose to employ could include drivers for hardware components on the board, but then you're not really on bare metal any more.

If you want to stick with bare metal, you'll be interacting directly with hardware peripherals, and by far the simplest communications peripheral to work with is a serial port (UART), to which you can connect from another machine. This would also solve the output problem, which you haven't mentioned but which is potentially significantly bigger than the input problem (driving a screen from bare metal is a challenge!).

cooperised
  • 2,404
  • 1
  • 15
  • 18