diff --git a/.gitignore b/.gitignore index 6bdd5c4644..088690722e 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,5 @@ Make.dep .dirlinks .vscode .DS_Store +.nimcache + diff --git a/config.nims b/config.nims index 0d6c4c74cc..ce0d8afb46 100644 --- a/config.nims +++ b/config.nims @@ -26,7 +26,9 @@ switch "mm", "orc" switch "arm.nuttx.gcc.exe", "arm-none-eabi-gcc" switch "arm64.nuttx.gcc.exe", "aarch64-none-elf-gcc" -switch "riscv32.nuttx.gcc.exe", "riscv64-unknown-elf-gcc" +####switch "riscv32.nuttx.gcc.exe", "riscv64-unknown-elf-gcc" +switch "riscv32.nuttx.gcc.exe", "riscv-none-elf-gcc" #### TODO +switch "riscv64.nuttx.gcc.exe", "riscv-none-elf-gcc" #### TODO switch "amd64.nuttx.gcc.exe", "x86_64-linux-gnu-gcc" switch "nimcache", ".nimcache" @@ -57,6 +59,7 @@ proc killoBytes(bytes: int): int = result = (bytes / 1024).int proc read_config(cfg: string): DotConfig = + echo "read_config: " & cfg #### for line in cfg.readFile.splitLines: if not line.startsWith("CONFIG_"): continue @@ -65,12 +68,20 @@ proc read_config(cfg: string): DotConfig = continue case keyval[0] of "ARCH": + echo "line=" & line #### + echo "keyval=" & keyval #### + echo "keyval[1]=" & keyval[1] #### let arch = keyval[1].strip(chars = {'"'}) case arch of "arm", "arm64": result.arch = arch - of "riscv": - result.arch = "riscv32" + of "risc-v": + #### TODO: Check for riscv32 or riscv3 + #### CONFIG_ARCH_RV32=y or CONFIG_ARCH_RV64=y + result.arch = "riscv64" + # switch("passC", "-mcmodel=medany") #### TODO + # switch("passC", "-march=rv64imafdc_zicsr_zifencei") #### TODO + # switch("passC", "-mabi=lp64d") #### TODO of "sim": if defined(amd64): result.arch = "amd64" @@ -78,17 +89,22 @@ proc read_config(cfg: string): DotConfig = result.arch = "arm64" result.isSim = true of "DEBUG_NOOPT": + echo "line=" & line #### result.opt = oNone of "DEBUG_FULLOPT": + echo "line=" & line #### result.opt = oSize of "DEBUG_SYMBOLS": + echo "line=" & line #### result.debugSymbols = true of "RAM_SIZE": + echo "line=" & line #### result.ramSize = keyval[1].parseInt echo "* arch: " & result.arch echo "* opt: " & $result.opt echo "* debug: " & $result.debugSymbols echo "* ramSize: " & $result.ramSize + echo "* isSim: " & $result.isSim func bool2onoff(b: bool): string = result = if b: "on" else: "off" diff --git a/examples/hello/hello_main.c b/examples/hello/hello_main.c index 2cd6cb400a..c3247020b4 100644 --- a/examples/hello/hello_main.c +++ b/examples/hello/hello_main.c @@ -23,7 +23,11 @@ ****************************************************************************/ #include +#include #include +#include + +#include /**************************************************************************** * Public Functions @@ -36,5 +40,46 @@ int main(int argc, FAR char *argv[]) { printf("Hello, World!!\n"); + + // Open the LED Driver + printf("Opening /dev/userleds\n"); + int fd = open("/dev/userleds", O_WRONLY); + if (fd < 0) + { + int errcode = errno; + printf("ERROR: Failed to open /dev/userleds: %d\n", + errcode); + return EXIT_FAILURE; + } + + // Turn on LED + puts("Set LED 0 to 1"); + int ret = ioctl(fd, ULEDIOC_SETALL, 1); + if (ret < 0) + { + int errcode = errno; + printf("ERROR: ioctl(ULEDIOC_SUPPORTED) failed: %d\n", + errcode); + return EXIT_FAILURE; + } + + // Sleep a while + puts("Waiting..."); + usleep(500 * 1000L); + + // Turn off LED + puts("Set LED 0 to 0"); + ret = ioctl(fd, ULEDIOC_SETALL, 0); + if (ret < 0) + { + int errcode = errno; + printf("ERROR: ioctl(ULEDIOC_SUPPORTED) failed: %d\n", + errcode); + return EXIT_FAILURE; + } + + // Close the LED Driver + close(fd); + return 0; } diff --git a/examples/hello_nim/Makefile b/examples/hello_nim/Makefile index 52d306d965..67e9bf9c97 100644 --- a/examples/hello_nim/Makefile +++ b/examples/hello_nim/Makefile @@ -30,8 +30,8 @@ MODULE = $(CONFIG_EXAMPLES_HELLO_NIM) # Hello, World! Example NIMPATH = $(shell choosenim show path) -CFLAGS += -I $(NIMPATH)/lib -I ./.nimcache -CSRCS += $(wildcard .nimcache/*.c) +CFLAGS += -I $(NIMPATH)/lib -I ../../.nimcache +CSRCS += $(wildcard ../../.nimcache/*.c) MAINSRC = hello_nim_main.c diff --git a/examples/hello_nim/hello_nim_async.nim b/examples/hello_nim/hello_nim_async.nim index 580283c17b..4091203bcd 100644 --- a/examples/hello_nim/hello_nim_async.nim +++ b/examples/hello_nim/hello_nim_async.nim @@ -1,3 +1,91 @@ +## Import NuttX Functions and Macros from C. +## Based on https://github.com/nim-lang/Nim/blob/devel/lib/std/syncio.nim +proc c_open(filename: cstring, mode: cint): cint {. + importc: "open", header: "".} +proc c_close(fd: cint): cint {. + importc: "close", header: "", + discardable.} +proc c_ioctl(fd: cint, request: cint): cint {. + importc: "ioctl", header: "", + varargs.} +proc c_usleep(usec: cuint): cint {. + importc: "usleep", header: "", + discardable.} +var O_WRONLY {. + importc: "O_WRONLY", header: "".}: cint +var ULEDIOC_SETALL {. + importc: "ULEDIOC_SETALL", header: "".}: cint + +## Blink the LED +proc blink_led() = + + ## Open the LED Driver + echo "Opening /dev/userleds" + let fd = c_open("/dev/userleds", O_WRONLY) + if fd < 0: + echo "Failed to open /dev/userleds" + return + + ## On Return: Close the LED Driver + defer: c_close(fd) + + ## Turn on LED + echo "Set LED 0 to 1" + var ret = c_ioctl(fd, ULEDIOC_SETALL, 1) + if ret < 0: + echo "ioctl(ULEDIOC_SETALL) failed" + return + + ## Wait a second (literally) + echo "Waiting..." + c_usleep(1000_000) + + ## Turn off LED + echo "Set LED 0 to 0" + ret = c_ioctl(fd, ULEDIOC_SETALL, 0) + if ret < 0: + echo "ioctl(ULEDIOC_SETALL) failed" + return + + ## Wait again + echo "Waiting..." + c_usleep(1000_000) + +## Main Function in Nim +proc hello_nim() {.exportc, cdecl.} = + + ## On Return: Force the Garbage Collection + defer: GC_runOrc() + + ## Print something + echo "Hello Nim!" + + ## Blink the LED 20 times + for loop in 0..19: + blink_led() + +## To test the compilation for NuttX: +# export TOPDIR=/workspaces/bookworm/nuttx +# cd /workspaces/bookworm/apps/examples/hello_nim +# nim c --header hello_nim_async.nim + +## Output Log: +# nsh> hello_nim +# Hello Nim! +# Opening /dev/userleds +# Set LED 0 to 1 +# board_userled_all: ledset=0x1 +# board_userled_all: led=0, val=1 +# board_userled_all: led=1, val=0 +# board_userled_all: led=2, val=0 +# Waiting... +# Set LED 0 to 0 +# board_userled_all: ledset=0x0 +# board_userled_all: led=0, val=0 +# board_userled_all: led=1, val=0 +# board_userled_all: led=2, val=0 + +## Previously: Test for Async Tasks import std/asyncdispatch import std/strformat @@ -13,6 +101,16 @@ proc launch() {.async.} = await sleepAsync(200) await task(3) -proc hello_nim() {.exportc, cdecl.} = - waitFor launch() - GC_runOrc() +# Test in Linux: +# hello_nim() #### +# Output: +# $ ./hello_nim_async +# Hello from task 1! loops: 0 +# Hello from task 2! loops: 0 +# Hello from task 3! loops: 0 +# Hello from task 1! loops: 1 +# Hello from task 2! loops: 1 +# Hello from task 3! loops: 1 +# Hello from task 1! loops: 2 +# Hello from task 2! loops: 2 +# Hello from task 3! loops: 2 diff --git a/examples/hello_nim/hello_nim_main.c b/examples/hello_nim/hello_nim_main.c index 9cad2fd924..df1c910156 100644 --- a/examples/hello_nim/hello_nim_main.c +++ b/examples/hello_nim/hello_nim_main.c @@ -33,9 +33,12 @@ * hello_main ****************************************************************************/ -int main(int argc, FAR char *argv[]) +int main(int argc, char *argv[]) { NimMain(); hello_nim(); return 0; } + +////TODO: Needed by nuttx/arch/risc-v/src/common/riscv_initialize.c +void riscv_netinitialize(void) {} ////TODO