Skip to content

Commit

Permalink
Changes for FreeRTOS/LwIP Port for the ESP32 (ESP-IDF) (nim-lang#15250)
Browse files Browse the repository at this point in the history
* Changes for FreeRTOS/LwIP Port for the ESP32 (ESP-IDF)

Adding FreeRTOS/LwIP to compiler:

* adding freertos option
* dyncalls for freertos
* add freertos to posix os list
* adding lwip option

Setting up networking FreeRTOS/LwIP Port:

* setting up lwip network for freertos
* fixing posix / networking for freertos
* disable setInheritable for freerots
* using lwip for net control items

* Fix builds by ignoring lib/posix/posix_freertos_consts.nim similar to lib/posix/posix_other_consts.nim
  • Loading branch information
elcritch authored and mildred committed Jan 11, 2021
1 parent 50fd994 commit e8a454b
Show file tree
Hide file tree
Showing 11 changed files with 589 additions and 32 deletions.
6 changes: 5 additions & 1 deletion compiler/options.nim
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ proc isDefined*(conf: ConfigRef; symbol: string): bool =
osQnx, osAtari, osAix,
osHaiku, osVxWorks, osSolaris, osNetbsd,
osFreebsd, osOpenbsd, osDragonfly, osMacosx, osIos,
osAndroid, osNintendoSwitch}
osAndroid, osNintendoSwitch, osFreeRTOS}
of "linux":
result = conf.target.targetOS in {osLinux, osAndroid}
of "bsd":
Expand All @@ -510,6 +510,10 @@ proc isDefined*(conf: ConfigRef; symbol: string): bool =
of "sunos": result = conf.target.targetOS == osSolaris
of "nintendoswitch":
result = conf.target.targetOS == osNintendoSwitch
of "freertos":
result = conf.target.targetOS == osFreeRTOS
of "lwip":
result = conf.target.targetOS in {osFreeRTOS}
of "littleendian": result = CPU[conf.target.targetCPU].endian == platform.littleEndian
of "bigendian": result = CPU[conf.target.targetCPU].endian == platform.bigEndian
of "cpu8": result = CPU[conf.target.targetCPU].bit == 8
Expand Down
9 changes: 7 additions & 2 deletions compiler/platform.nim
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type
osNone, osDos, osWindows, osOs2, osLinux, osMorphos, osSkyos, osSolaris,
osIrix, osNetbsd, osFreebsd, osOpenbsd, osDragonfly, osAix, osPalmos, osQnx,
osAmiga, osAtari, osNetware, osMacos, osMacosx, osIos, osHaiku, osAndroid, osVxWorks
osGenode, osJS, osNimVM, osStandalone, osNintendoSwitch, osAny
osGenode, osJS, osNimVM, osStandalone, osNintendoSwitch, osFreeRTOS, osAny

type
TInfoOSProp* = enum
Expand Down Expand Up @@ -177,6 +177,10 @@ const
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: ".elf", extSep: ".",
props: {ospNeedsPIC, ospPosix}),
(name: "FreeRTOS", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: ".elf", extSep: ".",
props: {ospPosix}),
(name: "Any", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
Expand All @@ -189,7 +193,7 @@ type
cpuNone, cpuI386, cpuM68k, cpuAlpha, cpuPowerpc, cpuPowerpc64,
cpuPowerpc64el, cpuSparc, cpuVm, cpuHppa, cpuIa64, cpuAmd64, cpuMips,
cpuMipsel, cpuArm, cpuArm64, cpuJS, cpuNimVM, cpuAVR, cpuMSP430,
cpuSparc64, cpuMips64, cpuMips64el, cpuRiscV64, cpuWasm32
cpuSparc64, cpuMips64, cpuMips64el, cpuRiscV64, cpuEsp, cpuWasm32

type
TEndian* = enum
Expand Down Expand Up @@ -223,6 +227,7 @@ const
(name: "mips64", intSize: 64, endian: bigEndian, floatSize: 64, bit: 64),
(name: "mips64el", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64),
(name: "riscv64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64),
(name: "esp", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
(name: "wasm32", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32)]

type
Expand Down
17 changes: 12 additions & 5 deletions lib/posix/posix.nim
Original file line number Diff line number Diff line change
Expand Up @@ -962,9 +962,15 @@ proc IN6_IS_ADDR_LINKLOCAL* (a1: ptr In6Addr): cint {.
proc IN6_IS_ADDR_SITELOCAL* (a1: ptr In6Addr): cint {.
importc, header: "<netinet/in.h>".}
## Unicast site-local address.
proc IN6_IS_ADDR_V4MAPPED* (a1: ptr In6Addr): cint {.
importc, header: "<netinet/in.h>".}
## IPv4 mapped address.
when defined(lwip):
proc IN6_IS_ADDR_V4MAPPED*(ipv6_address: ptr In6Addr): cint =
var bits32: ptr array[4, uint32] = cast[ptr array[4, uint32]](ipv6_address)
return (bits32[1] == 0'u32 and bits32[2] == htonl(0x0000FFFF)).cint
else:
proc IN6_IS_ADDR_V4MAPPED* (a1: ptr In6Addr): cint {.
importc, header: "<netinet/in.h>".}
## IPv4 mapped address.

proc IN6_IS_ADDR_V4COMPAT* (a1: ptr In6Addr): cint {.
importc, header: "<netinet/in.h>".}
## IPv4-compatible address.
Expand Down Expand Up @@ -1026,8 +1032,9 @@ proc setnetent*(a1: cint) {.importc, header: "<netdb.h>".}
proc setprotoent*(a1: cint) {.importc, header: "<netdb.h>".}
proc setservent*(a1: cint) {.importc, header: "<netdb.h>".}

proc poll*(a1: ptr TPollfd, a2: Tnfds, a3: int): cint {.
importc, header: "<poll.h>", sideEffect.}
when not defined(lwip):
proc poll*(a1: ptr TPollfd, a2: Tnfds, a3: int): cint {.
importc, header: "<poll.h>", sideEffect.}

proc realpath*(name, resolved: cstring): cstring {.
importc: "realpath", header: "<stdlib.h>".}
Expand Down
488 changes: 488 additions & 0 deletions lib/posix/posix_freertos_consts.nim

Large diffs are not rendered by default.

80 changes: 62 additions & 18 deletions lib/posix/posix_other.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@
when defined(nimHasStyleChecks):
{.push styleChecks: off.}

const
hasSpawnH = true # should exist for every Posix system nowadays
hasAioH = defined(linux)
when defined(freertos):
const
hasSpawnH = false # should exist for every Posix system nowadays
hasAioH = false
else:
const
hasSpawnH = true # should exist for every Posix system nowadays
hasAioH = defined(linux)

when defined(linux) and not defined(android):
# On Linux:
Expand Down Expand Up @@ -397,21 +402,55 @@ type
SockLen* {.importc: "socklen_t", header: "<sys/socket.h>".} = cuint
TSa_Family* {.importc: "sa_family_t", header: "<sys/socket.h>".} = cushort

SockAddr* {.importc: "struct sockaddr", header: "<sys/socket.h>",
pure, final.} = object ## struct sockaddr
sa_family*: TSa_Family ## Address family.
sa_data*: array[0..255, char] ## Socket address (variable-length data).
when defined(lwip):
type
SockAddr* {.importc: "struct sockaddr", header: "<sys/socket.h>",
pure, final.} = object ## struct sockaddr
sa_len*: uint8 ## Address family.
sa_family*: TSa_Family ## Address family.
sa_data*: array[0..255, char] ## Socket address (variable-length data).
else:
type
SockAddr* {.importc: "struct sockaddr", header: "<sys/socket.h>",
pure, final.} = object ## struct sockaddr
sa_family*: TSa_Family ## Address family.
sa_data*: array[0..255, char] ## Socket address (variable-length data).

type
Sockaddr_un* {.importc: "struct sockaddr_un", header: "<sys/un.h>",
pure, final.} = object ## struct sockaddr_un
sun_family*: TSa_Family ## Address family.
sun_path*: array[0..Sockaddr_un_path_length-1, char] ## Socket path

Sockaddr_storage* {.importc: "struct sockaddr_storage",
header: "<sys/socket.h>",
pure, final.} = object ## struct sockaddr_storage
ss_family*: TSa_Family ## Address family.

when defined(lwip):
when not defined(lwip6):
type
Sockaddr_storage* {.importc: "struct sockaddr_storage",
header: "<sys/socket.h>",
pure, final.} = object ## struct sockaddr_storage
s2_len*: uint8 ## Address family.
ss_family*: TSa_Family ## Address family.
s2_data1*: array[2, char] ## Address family.
s2_data2*: array[3, uint32] ## Address family.
else:
type
Sockaddr_storage* {.importc: "struct sockaddr_storage",
header: "<sys/socket.h>",
pure, final.} = object ## struct sockaddr_storage
s2_len*: uint8 ## Address family.
ss_family*: TSa_Family ## Address family.
s2_data1*: array[2, char] ## Address family.
s2_data2*: array[3, uint32] ## Address family.
s2_data3*: array[3, uint32] ## Address family.
else:
type
Sockaddr_storage* {.importc: "struct sockaddr_storage",
header: "<sys/socket.h>",
pure, final.} = object ## struct sockaddr_storage
ss_family*: TSa_Family ## Address family.

type
Tif_nameindex* {.importc: "struct if_nameindex", final,
pure, header: "<net/if.h>".} = object ## struct if_nameindex
if_index*: cint ## Numeric index of the interface.
Expand Down Expand Up @@ -530,13 +569,15 @@ type
ai_canonname*: cstring ## Canonical name of service location.
ai_next*: ptr AddrInfo ## Pointer to next in list.

TPollfd* {.importc: "struct pollfd", pure, final,
header: "<poll.h>".} = object ## struct pollfd
fd*: cint ## The following descriptor being polled.
events*: cshort ## The input event flags (see below).
revents*: cshort ## The output event flags (see below).
when not defined(lwip):
type
TPollfd* {.importc: "struct pollfd", pure, final,
header: "<poll.h>".} = object ## struct pollfd
fd*: cint ## The following descriptor being polled.
events*: cshort ## The input event flags (see below).
revents*: cshort ## The output event flags (see below).

Tnfds* {.importc: "nfds_t", header: "<poll.h>".} = cint
Tnfds* {.importc: "nfds_t", header: "<poll.h>".} = cint

var
errno* {.importc, header: "<errno.h>".}: cint ## error variable
Expand All @@ -545,7 +586,10 @@ var
timezone* {.importc, header: "<time.h>".}: int

# Regenerate using detect.nim!
include posix_other_consts
when defined(lwip):
include posix_freertos_consts
else:
include posix_other_consts

when defined(linux):
var
Expand Down
2 changes: 1 addition & 1 deletion lib/pure/ioselects/ioselectors_select.nim
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ proc selectInto*[T](s: Selector[T], timeout: int,
verifySelectParams(timeout)

if timeout != -1:
when defined(genode):
when defined(genode) or defined(freertos):
tv.tv_sec = Time(timeout div 1_000)
else:
tv.tv_sec = timeout.int32 div 1_000
Expand Down
2 changes: 1 addition & 1 deletion lib/pure/nativesockets.nim
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ proc getAddrInfo*(address: string, port: Port, domain: Domain = AF_INET,
let socketPort = if sockType == SOCK_RAW: "" else: $port
var gaiResult = getaddrinfo(address, socketPort, addr(hints), result)
if gaiResult != 0'i32:
when useWinVersion:
when useWinVersion or defined(freertos):
raiseOSError(osLastError())
else:
raiseOSError(osLastError(), $gai_strerror(gaiResult))
Expand Down
2 changes: 2 additions & 0 deletions lib/pure/selectors.nim
Original file line number Diff line number Diff line change
Expand Up @@ -332,5 +332,7 @@ else:
include ioselects/ioselectors_select # TODO: use the native VFS layer
elif defined(nintendoswitch):
include ioselects/ioselectors_select
elif defined(freertos) or defined(lwip):
include ioselects/ioselectors_select
else:
include ioselects/ioselectors_poll
2 changes: 1 addition & 1 deletion lib/system/dyncalls.nim
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ elif defined(genode):
proc nimGetProcAddr(lib: LibHandle, name: cstring): ProcAddr {.
error: "nimGetProcAddr not implemented".}

elif defined(nintendoswitch):
elif defined(nintendoswitch) or defined(freertos):
proc nimUnloadLibrary(lib: LibHandle) =
cstderr.rawWrite("nimUnLoadLibrary not implemented")
cstderr.rawWrite("\n")
Expand Down
12 changes: 9 additions & 3 deletions lib/system/io.nim
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ when SupportIoctlInheritCtl:

proc c_ioctl(fd: cint, request: cint): cint {.
importc: "ioctl", header: "<sys/ioctl.h>", varargs.}
elif defined(posix) and not defined(nimscript):
elif defined(posix) and not defined(lwip) and not defined(nimscript):
var
F_GETFD {.importc, header: "<fcntl.h>".}: cint
F_SETFD {.importc, header: "<fcntl.h>".}: cint
Expand Down Expand Up @@ -336,6 +336,8 @@ when defined(nimdoc) or (defined(posix) and not defined(nimscript)) or defined(w
## availability with `declared() <system.html#declared,untyped>`.
when SupportIoctlInheritCtl:
result = c_ioctl(f, if inheritable: FIONCLEX else: FIOCLEX) != -1
elif defined(freertos):
result = true
elif defined(posix):
var flags = c_fcntl(f, F_GETFD)
if flags == -1:
Expand Down Expand Up @@ -767,6 +769,10 @@ when declared(stdout):
var echoLock: SysLock
initSysLock echoLock

const stdOutLock = not defined(windows) and not defined(android) and
not defined(nintendoswitch) and not defined(freertos) and
hostOS != "any"

proc echoBinSafe(args: openArray[string]) {.compilerproc.} =
when defined(androidNDK):
var s = ""
Expand All @@ -775,7 +781,7 @@ when declared(stdout):
android_log_print(ANDROID_LOG_VERBOSE, "nim", s)
else:
# flockfile deadlocks some versions of Android 5.x.x
when not defined(windows) and not defined(android) and not defined(nintendoswitch) and hostOS != "any":
when stdOutLock:
proc flockfile(f: File) {.importc, nodecl.}
proc funlockfile(f: File) {.importc, nodecl.}
flockfile(stdout)
Expand All @@ -789,7 +795,7 @@ when declared(stdout):
const linefeed = "\n"
discard c_fwrite(linefeed.cstring, linefeed.len, 1, stdout)
discard c_fflush(stdout)
when not defined(windows) and not defined(android) and not defined(nintendoswitch) and hostOS != "any":
when stdOutLock:
funlockfile(stdout)
when defined(windows) and compileOption("threads"):
releaseSys echoLock
Expand Down
1 change: 1 addition & 0 deletions tools/kochdocs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ lib/posix/posix_nintendoswitch_consts.nim
lib/posix/posix_linux_amd64.nim
lib/posix/posix_linux_amd64_consts.nim
lib/posix/posix_other_consts.nim
lib/posix/posix_freertos_consts.nim
lib/posix/posix_openbsd_amd64.nim
lib/posix/posix_haiku.nim
lib/js/jsre.nim
Expand Down

0 comments on commit e8a454b

Please sign in to comment.