-
Notifications
You must be signed in to change notification settings - Fork 4
Description
As mentioned in the FOSDEM presentation something should probably be done around the proc main() {.exportc.} and noMain which are currently required to get the really small code sizes that Ratel enjoys. After a nice conversation with @yglukhov about this and some preliminary testing it seems that what is actually causing the extra size even without global memory and such is the use of volatile in NimMain and friends. The reason why it uses volatile is to make sure that parts of the code isn't inlined as it tries to set the stack frame to scan for the mark and sweep pass of the GC. This is however not required for ARC which we're using at the moment. It might be required by ORC however. I will probably make a PR to the main Nim repository in the coming days which adds in a check for the C code generation that avoids creating the volatile part. I manually wrote a small NimMain which did the same things for my module, but avoided those and the code size was the same as it is currently. I'm basically just writing this issue to track progress on this issue. This would allow the example code to simply be written as:
import board
import board / [times, serial, progmem]
Serial.init(9600.Hz)
Serial.send p"Hello world\n"
Led.output()
while true:
Led.high()
Serial.send p"Led is on\n"
delayMs(1000)
Led.low()
Serial.send p"Led is off\n"
delayMs(1000)The second part of this issue is that while true loop. Some platform (the ESP8266 for example) has a hardware watchdog in order to make sure that they don't accidentally enter an infinite loop. This means that code like the above would run until the watchdog fired and then the board would reboot (assuming that delayMs didn't feed the watchdog and sleep the system in a more logical way, which it probably would). I plan on adding a loop construct which would essentially do the same thing as the while true loop, but have small template calls which would bind to templates in the board definition and allow it to insert logic before the loop, and before and after each loop iteration. This should provide the necessary flexibility to implement such boards, but comments are appreciated if you see other issues with this. The final resulting code would then look like this:
import board
import board / [times, serial, progmem]
Serial.init(9600.Hz)
Serial.send p"Hello world\n"
Led.output()
loop:
Led.high()
Serial.send p"Led is on\n"
delayMs(1000)
Led.low()
Serial.send p"Led is off\n"
delayMs(1000)With NimMain working properly it should also allow modules to have their own initialisation logic in the global scope, if e.g. a board requires some particular things to be done on boot. These should then of course be put behind a compile-time switch if the user wished to do these things manually instead.