I've been experimenting with writing very basic operating system-like programs on the Arduino, and so far I have been running user-defined programs on a small virtual machine I wrote. This has been an interesting experience, but the VM runs on an assembly-like language and not C.
I want to be able to do something more. I would like to be able to write a core OS, and then install new programs, written in C. The core OS would get user input for which program to run, and then jump to that program.
Now, I know that I can do this trivially by writing the OS along with all of the programs into a single sketch. The programs are then just functions, and the OS just calls those functions. However, I want to do this with functions I've written after I've burned the main OS.
From what I can tell, this is just a bootloader with additional user functionality. However, I don't think that's quite right for two reasons:
First, I keep hearing that you can't write to progmem at runtime. But isn't that what a bootloader does? Which is correct?
Second, once a user program ends, I should return to the OS. As far as I understand it, on the ATMega, once the main function terminates it jumps into a no-operation function and that's that. I'd need it to jump back to the bootloader and continue the bootloader's operation. Is that even possible?
-
1If this is what you want to do you have chosen the wrong MCU. Find something that can run from RAM, even if a bit inefficiently - competing ARM Cortex MCUs typically can. Also understand that this "C" code you speak of gets compiled to machine instructions before it runs - you can compile C to instructions for a virtual machine, too.Chris Stratton– Chris Stratton2016年12月08日 15:40:51 +00:00Commented Dec 8, 2016 at 15:40
-
Yes, you're right, and I've got an M0 that I can play around with. However, I am using the AVR for a few reasons. First, I'm familiar with it. Second, because it doesn't just automatically have facilities to run like this I have to create them all myself. My goal with these projects is to learn HOW those facilities are developed, not to get anything useful out of them. So I chose a limited chip and made my own workarounds so that I understand how the more advanced chips do it all natively.Michael Stachowsky– Michael Stachowsky2016年12月08日 17:22:33 +00:00Commented Dec 8, 2016 at 17:22
-
Your workaround might be an interesting puzzle, but it's not really how more capable chips would do it at all, but rather a workaround for the anachronistic limitations of the avr.Chris Stratton– Chris Stratton2016年12月08日 18:37:35 +00:00Commented Dec 8, 2016 at 18:37
-
Seems you can fool the protectionGerben– Gerben2016年12月08日 18:43:18 +00:00Commented Dec 8, 2016 at 18:43
-
@ChrisStratton: yes, you're right. But doing it on my own means I get to make my own file system, loader style thing etc. However, I'm actually probably going to just avoid it all and use a Cortex now that I know they CAN execute from RAM. I guess it pays to do your homeworkMichael Stachowsky– Michael Stachowsky2016年12月08日 20:39:38 +00:00Commented Dec 8, 2016 at 20:39
1 Answer 1
First, I keep hearing that you can't write to progmem at runtime. But isn't that what a bootloader does?
Indeed. My understanding is that non-bootloader code cannot write to the Flash, except on the smallest AVRs. You may need to check the datasheet of your target MCU.
Second, once a user program ends, I should return to the OS.
You could require for the user programs to be linked against a library
you provide. Just implement void exit(int status)
in that library and
it will automatically override the version from avr-libc.
-
Yes, a quick datasheet dive reveals the following: There are three sections in flash. Boot is a special section where code running can actively modify progmem. No-Read-While-Write is a section that does not allow for code to run while it is being updated (the CPU is halted). Read-While-Write does allow for code to run while it is being updated, BUT the code that runs can only run from the NRWW section. So it looks like I can write the OS to have an "installer" in BOOT, kernelspace in NRWW, and userspace in RWW.Michael Stachowsky– Michael Stachowsky2016年12月08日 14:40:08 +00:00Commented Dec 8, 2016 at 14:40