Add support for NuttX RTOS. (#21372)

* Add support for NuttX RTOS.

Signed-off-by: Takeyoshi Kikuchi <kikuchi@centurysys.co.jp>

* lib: pure: asyncdispatch: assign to result.

Signed-off-by: Takeyoshi Kikuchi <kikuchi@centurysys.co.jp>

* lib: std: typedthreads: add support for parameters to adjust Thread Stack Size.

Like FreeRTOS/Zephyr, add support for following configurations.

  -d:nimThreadStackSize=xxxxx
  -d:nimThreadStackGuard=yyyy

Signed-off-by: Takeyoshi Kikuchi <kikuchi@centurysys.co.jp>

---------

Signed-off-by: Takeyoshi Kikuchi <kikuchi@centurysys.co.jp>
This commit is contained in:
Century Systems 2023-02-16 21:47:52 +09:00 • committed by GitHub
commit 3b9e9fd7b2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 52 additions and 17 deletions

View file

@ -621,7 +621,7 @@ proc isDefined*(conf: ConfigRef; symbol: string): bool =
osQnx, osAtari, osAix, osQnx, osAtari, osAix,
osHaiku, osVxWorks, osSolaris, osNetbsd, osHaiku, osVxWorks, osSolaris, osNetbsd,
osFreebsd, osOpenbsd, osDragonfly, osMacosx, osIos, osFreebsd, osOpenbsd, osDragonfly, osMacosx, osIos,
osAndroid, osNintendoSwitch, osFreeRTOS, osCrossos, osZephyr} osAndroid, osNintendoSwitch, osFreeRTOS, osCrossos, osZephyr, osNuttX}
of "linux": of "linux":
result = conf.target.targetOS in {osLinux, osAndroid} result = conf.target.targetOS in {osLinux, osAndroid}
of "bsd": of "bsd":
@ -643,6 +643,8 @@ proc isDefined*(conf: ConfigRef; symbol: string): bool =
result = conf.target.targetOS == osFreeRTOS result = conf.target.targetOS == osFreeRTOS
of "zephyr": of "zephyr":
result = conf.target.targetOS == osZephyr result = conf.target.targetOS == osZephyr
of "nuttx":
result = conf.target.targetOS == osNuttX
of "littleendian": result = CPU[conf.target.targetCPU].endian == littleEndian of "littleendian": result = CPU[conf.target.targetCPU].endian == littleEndian
of "bigendian": result = CPU[conf.target.targetCPU].endian == bigEndian of "bigendian": result = CPU[conf.target.targetCPU].endian == bigEndian
of "cpu8": result = CPU[conf.target.targetCPU].bit == 8 of "cpu8": result = CPU[conf.target.targetCPU].bit == 8

View file

@ -26,7 +26,8 @@ type
osNone, osDos, osWindows, osOs2, osLinux, osMorphos, osSkyos, osSolaris, osNone, osDos, osWindows, osOs2, osLinux, osMorphos, osSkyos, osSolaris,
osIrix, osNetbsd, osFreebsd, osOpenbsd, osDragonfly, osCrossos, osAix, osPalmos, osQnx, osIrix, osNetbsd, osFreebsd, osOpenbsd, osDragonfly, osCrossos, osAix, osPalmos, osQnx,
osAmiga, osAtari, osNetware, osMacos, osMacosx, osIos, osHaiku, osAndroid, osVxWorks osAmiga, osAtari, osNetware, osMacos, osMacosx, osIos, osHaiku, osAndroid, osVxWorks
osGenode, osJS, osNimVM, osStandalone, osNintendoSwitch, osFreeRTOS, osZephyr, osAny osGenode, osJS, osNimVM, osStandalone, osNintendoSwitch, osFreeRTOS, osZephyr,
osNuttX, osAny
type type
TInfoOSProp* = enum TInfoOSProp* = enum
@ -193,6 +194,10 @@ const
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
props: {ospPosix}), props: {ospPosix}),
(name: "NuttX", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
props: {ospPosix}),
(name: "Any", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", (name: "Any", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",

View file

@ -10,7 +10,7 @@
when defined(nimHasStyleChecks): when defined(nimHasStyleChecks):
{.push styleChecks: off.} {.push styleChecks: off.}
when defined(freertos) or defined(zephyr): when defined(freertos) or defined(zephyr) or defined(nuttx):
const const
hasSpawnH = false # should exist for every Posix system nowadays hasSpawnH = false # should exist for every Posix system nowadays
hasAioH = false hasAioH = false
@ -640,6 +640,9 @@ when defined(linux) or defined(nimdoc):
## or UDP packets. (Requires Linux kernel > 3.9) ## or UDP packets. (Requires Linux kernel > 3.9)
else: else:
const SO_REUSEPORT* = cint(15) const SO_REUSEPORT* = cint(15)
elif defined(nuttx):
# Not supported, use SO_REUSEADDR to avoid compilation errors.
var SO_REUSEPORT* {.importc: "SO_REUSEADDR", header: "<sys/socket.h>".}: cint
else: else:
var SO_REUSEPORT* {.importc, header: "<sys/socket.h>".}: cint var SO_REUSEPORT* {.importc, header: "<sys/socket.h>".}: cint

View file

@ -99,7 +99,10 @@ var EXDEV* {.importc: "EXDEV", header: "<errno.h>".}: cint
# <fcntl.h> # <fcntl.h>
var F_DUPFD* {.importc: "F_DUPFD", header: "<fcntl.h>".}: cint var F_DUPFD* {.importc: "F_DUPFD", header: "<fcntl.h>".}: cint
var F_DUPFD_CLOEXEC* {.importc: "F_DUPFD", header: "<fcntl.h>".}: cint when defined(nuttx):
var F_DUPFD_CLOEXEC* {.importc: "F_DUPFD_CLOEXEC", header: "<fcntl.h>".}: cint
else:
var F_DUPFD_CLOEXEC* {.importc: "F_DUPFD", header: "<fcntl.h>".}: cint
var F_GETFD* {.importc: "F_GETFD", header: "<fcntl.h>".}: cint var F_GETFD* {.importc: "F_GETFD", header: "<fcntl.h>".}: cint
var F_SETFD* {.importc: "F_SETFD", header: "<fcntl.h>".}: cint var F_SETFD* {.importc: "F_SETFD", header: "<fcntl.h>".}: cint
var F_GETFL* {.importc: "F_GETFL", header: "<fcntl.h>".}: cint var F_GETFL* {.importc: "F_GETFL", header: "<fcntl.h>".}: cint
@ -127,6 +130,11 @@ var O_RDONLY* {.importc: "O_RDONLY", header: "<fcntl.h>".}: cint
var O_RDWR* {.importc: "O_RDWR", header: "<fcntl.h>".}: cint var O_RDWR* {.importc: "O_RDWR", header: "<fcntl.h>".}: cint
var O_WRONLY* {.importc: "O_WRONLY", header: "<fcntl.h>".}: cint var O_WRONLY* {.importc: "O_WRONLY", header: "<fcntl.h>".}: cint
var O_CLOEXEC* {.importc: "O_CLOEXEC", header: "<fcntl.h>".}: cint var O_CLOEXEC* {.importc: "O_CLOEXEC", header: "<fcntl.h>".}: cint
when defined(nuttx):
var O_DIRECT* {.importc: "O_DIRECT", header: "<fcntl.h>".}: cint
var O_PATH* {.importc: "O_PATH", header: "<fcntl.h>".}: cint
var O_NOATIME* {.importc: "O_NOATIME", header: "<fcntl.h>".}: cint
var O_TMPFILE* {.importc: "O_TMPFILE", header: "<fcntl.h>".}: cint
var POSIX_FADV_NORMAL* {.importc: "POSIX_FADV_NORMAL", header: "<fcntl.h>".}: cint var POSIX_FADV_NORMAL* {.importc: "POSIX_FADV_NORMAL", header: "<fcntl.h>".}: cint
var POSIX_FADV_SEQUENTIAL* {.importc: "POSIX_FADV_SEQUENTIAL", header: "<fcntl.h>".}: cint var POSIX_FADV_SEQUENTIAL* {.importc: "POSIX_FADV_SEQUENTIAL", header: "<fcntl.h>".}: cint
var POSIX_FADV_RANDOM* {.importc: "POSIX_FADV_RANDOM", header: "<fcntl.h>".}: cint var POSIX_FADV_RANDOM* {.importc: "POSIX_FADV_RANDOM", header: "<fcntl.h>".}: cint
@ -465,6 +473,9 @@ var FD_SETSIZE* {.importc: "FD_SETSIZE", header: "<sys/select.h>".}: cint
when defined(zephyr): when defined(zephyr):
# Zephyr specific hardcoded value # Zephyr specific hardcoded value
var FD_MAX* {.importc: "CONFIG_POSIX_MAX_FDS ", header: "<sys/select.h>".}: cint var FD_MAX* {.importc: "CONFIG_POSIX_MAX_FDS ", header: "<sys/select.h>".}: cint
elif defined(nuttx):
# NuttX specific user configuration value
var NACTIVESOCKETS* {.importc: "CONFIG_NET_NACTIVESOCKETS", header: "<nuttx/config.h>".}: cint
# <sys/socket.h> # <sys/socket.h>
var MSG_CTRUNC* {.importc: "MSG_CTRUNC", header: "<sys/socket.h>".}: cint var MSG_CTRUNC* {.importc: "MSG_CTRUNC", header: "<sys/socket.h>".}: cint

View file

@ -2024,7 +2024,7 @@ when defined(posix):
import posix import posix
when defined(linux) or defined(windows) or defined(macosx) or defined(bsd) or when defined(linux) or defined(windows) or defined(macosx) or defined(bsd) or
defined(solaris) or defined(zephyr) or defined(freertos): defined(solaris) or defined(zephyr) or defined(freertos) or defined(nuttx):
proc maxDescriptors*(): int {.raises: OSError.} = proc maxDescriptors*(): int {.raises: OSError.} =
## Returns the maximum number of active file descriptors for the current ## Returns the maximum number of active file descriptors for the current
## process. This involves a system call. For now `maxDescriptors` is ## process. This involves a system call. For now `maxDescriptors` is
@ -2033,6 +2033,9 @@ when defined(linux) or defined(windows) or defined(macosx) or defined(bsd) or
result = 16_700_000 result = 16_700_000
elif defined(zephyr) or defined(freertos): elif defined(zephyr) or defined(freertos):
result = FD_MAX result = FD_MAX
elif defined(nuttx):
# The maximum number of concurrently active UDP and TCP ports.
result = NACTIVESOCKETS
else: else:
var fdLim: RLimit var fdLim: RLimit
if getrlimit(RLIMIT_NOFILE, fdLim) < 0: if getrlimit(RLIMIT_NOFILE, fdLim) < 0:

View file

@ -387,8 +387,9 @@ proc listen*(server: AsyncHttpServer; port: Port; address = ""; domain = AF_INET
server.socket = newAsyncSocket(domain) server.socket = newAsyncSocket(domain)
if server.reuseAddr: if server.reuseAddr:
server.socket.setSockOpt(OptReuseAddr, true) server.socket.setSockOpt(OptReuseAddr, true)
if server.reusePort: when not defined(nuttx):
server.socket.setSockOpt(OptReusePort, true) if server.reusePort:
server.socket.setSockOpt(OptReusePort, true)
server.socket.bindAddr(port, address) server.socket.bindAddr(port, address)
server.socket.listen() server.socket.listen()

View file

@ -106,7 +106,8 @@ export SOBool
# TODO: Remove duplication introduced by PR #4683. # TODO: Remove duplication introduced by PR #4683.
const defineSsl = defined(ssl) or defined(nimdoc) const defineSsl = defined(ssl) or defined(nimdoc)
const useNimNetLite = defined(nimNetLite) or defined(freertos) or defined(zephyr) const useNimNetLite = defined(nimNetLite) or defined(freertos) or defined(zephyr) or
defined(nuttx)
when defineSsl: when defineSsl:
import openssl import openssl

View file

@ -313,7 +313,7 @@ proc selectInto*[T](s: Selector[T], timeout: int,
verifySelectParams(timeout) verifySelectParams(timeout)
if timeout != -1: if timeout != -1:
when defined(genode) or defined(freertos) or defined(zephyr): when defined(genode) or defined(freertos) or defined(zephyr) or defined(nuttx):
tv.tv_sec = Time(timeout div 1_000) tv.tv_sec = Time(timeout div 1_000)
else: else:
tv.tv_sec = timeout.int32 div 1_000 tv.tv_sec = timeout.int32 div 1_000

View file

@ -23,7 +23,8 @@ when hostOS == "solaris":
{.passl: "-lsocket -lnsl".} {.passl: "-lsocket -lnsl".}
const useWinVersion = defined(windows) or defined(nimdoc) const useWinVersion = defined(windows) or defined(nimdoc)
const useNimNetLite = defined(nimNetLite) or defined(freertos) or defined(zephyr) const useNimNetLite = defined(nimNetLite) or defined(freertos) or defined(zephyr) or
defined(nuttx)
when useWinVersion: when useWinVersion:
import winlean import winlean
@ -304,7 +305,7 @@ proc getAddrInfo*(address: string, port: Port, domain: Domain = AF_INET,
let socketPort = if sockType == SOCK_RAW: "" else: $port let socketPort = if sockType == SOCK_RAW: "" else: $port
var gaiResult = getaddrinfo(address, socketPort.cstring, addr(hints), result) var gaiResult = getaddrinfo(address, socketPort.cstring, addr(hints), result)
if gaiResult != 0'i32: if gaiResult != 0'i32:
when useWinVersion or defined(freertos): when useWinVersion or defined(freertos) or defined(nuttx):
raiseOSError(osLastError()) raiseOSError(osLastError())
else: else:
raiseOSError(osLastError(), $gai_strerror(gaiResult)) raiseOSError(osLastError(), $gai_strerror(gaiResult))
@ -351,7 +352,7 @@ proc getSockDomain*(socket: SocketHandle): Domain =
else: else:
raise newException(IOError, "Unknown socket family in getSockDomain") raise newException(IOError, "Unknown socket family in getSockDomain")
when not useNimNetLite: when not useNimNetLite:
proc getServByName*(name, proto: string): Servent {.tags: [ReadIOEffect].} = proc getServByName*(name, proto: string): Servent {.tags: [ReadIOEffect].} =
## Searches the database from the beginning and finds the first entry for ## Searches the database from the beginning and finds the first entry for
## which the service name specified by `name` matches the s_name member ## which the service name specified by `name` matches the s_name member

View file

@ -100,7 +100,8 @@ export nativesockets.Port, nativesockets.`$`, nativesockets.`==`
export Domain, SockType, Protocol export Domain, SockType, Protocol
const useWinVersion = defined(windows) or defined(nimdoc) const useWinVersion = defined(windows) or defined(nimdoc)
const useNimNetLite = defined(nimNetLite) or defined(freertos) or defined(zephyr) const useNimNetLite = defined(nimNetLite) or defined(freertos) or defined(zephyr) or
defined(nuttx)
const defineSsl = defined(ssl) or defined(nimdoc) const defineSsl = defined(ssl) or defined(nimdoc)
when useWinVersion: when useWinVersion:

View file

@ -37,7 +37,7 @@ const hasThreadSupport = compileOption("threads") and defined(threadsafe)
const ioselSupportedPlatform* = defined(macosx) or defined(freebsd) or const ioselSupportedPlatform* = defined(macosx) or defined(freebsd) or
defined(netbsd) or defined(openbsd) or defined(netbsd) or defined(openbsd) or
defined(dragonfly) or defined(dragonfly) or defined(nuttx) or
(defined(linux) and not defined(android) and not defined(emscripten)) (defined(linux) and not defined(android) and not defined(emscripten))
## This constant is used to determine whether the destination platform is ## This constant is used to determine whether the destination platform is
## fully supported by `ioselectors` module. ## fully supported by `ioselectors` module.
@ -328,7 +328,7 @@ else:
doAssert(timeout >= -1, "Cannot select with a negative value, got: " & $timeout) doAssert(timeout >= -1, "Cannot select with a negative value, got: " & $timeout)
when defined(linux) or defined(windows) or defined(macosx) or defined(bsd) or when defined(linux) or defined(windows) or defined(macosx) or defined(bsd) or
defined(solaris) or defined(zephyr) or defined(freertos): defined(solaris) or defined(zephyr) or defined(freertos) or defined(nuttx):
template maxDescriptors*(): int = template maxDescriptors*(): int =
## Returns the maximum number of active file descriptors for the current ## Returns the maximum number of active file descriptors for the current
## process. This involves a system call. For now `maxDescriptors` is ## process. This involves a system call. For now `maxDescriptors` is
@ -337,6 +337,9 @@ else:
16_700_000 16_700_000
elif defined(zephyr) or defined(freertos): elif defined(zephyr) or defined(freertos):
FD_MAX FD_MAX
elif defined(nuttx):
# The maximum number of concurrently active UDP and TCP ports.
NACTIVESOCKETS
else: else:
var fdLim: RLimit var fdLim: RLimit
var res = int(getrlimit(RLIMIT_NOFILE, fdLim)) var res = int(getrlimit(RLIMIT_NOFILE, fdLim))
@ -360,5 +363,7 @@ else:
include ioselects/ioselectors_select include ioselects/ioselectors_select
elif defined(zephyr): elif defined(zephyr):
include ioselects/ioselectors_poll include ioselects/ioselectors_poll
elif defined(nuttx):
include ioselects/ioselectors_epoll
else: else:
include ioselects/ioselectors_poll include ioselects/ioselectors_poll

View file

@ -46,7 +46,8 @@ when defined(genode):
import genode/env import genode/env
when hasAllocStack or defined(zephyr) or defined(freertos) or defined(cpu16) or defined(cpu8): when hasAllocStack or defined(zephyr) or defined(freertos) or defined(nuttx) or
defined(cpu16) or defined(cpu8):
const const
nimThreadStackSize {.intdefine.} = 8192 nimThreadStackSize {.intdefine.} = 8192
nimThreadStackGuard {.intdefine.} = 128 nimThreadStackGuard {.intdefine.} = 128

View file

@ -2688,6 +2688,7 @@ when notJSnotNims:
not defined(nintendoswitch) and not defined(nintendoswitch) and
not defined(freertos) and not defined(freertos) and
not defined(zephyr) and not defined(zephyr) and
not defined(nuttx) and
hostOS != "any" hostOS != "any"
proc raiseEIO(msg: string) {.noinline, noreturn.} = proc raiseEIO(msg: string) {.noinline, noreturn.} =

View file

@ -176,7 +176,7 @@ elif defined(genode):
proc nimGetProcAddr(lib: LibHandle, name: cstring): ProcAddr = proc nimGetProcAddr(lib: LibHandle, name: cstring): ProcAddr =
raiseAssert("nimGetProcAddr not implemented") raiseAssert("nimGetProcAddr not implemented")
elif defined(nintendoswitch) or defined(freertos) or defined(zephyr): elif defined(nintendoswitch) or defined(freertos) or defined(zephyr) or defined(nuttx):
proc nimUnloadLibrary(lib: LibHandle) = proc nimUnloadLibrary(lib: LibHandle) =
cstderr.rawWrite("nimUnLoadLibrary not implemented") cstderr.rawWrite("nimUnLoadLibrary not implemented")
cstderr.rawWrite("\n") cstderr.rawWrite("\n")