examples/xedge_demo: Add Xedge IoT Toolkit with BAS integration

Add support for Xedge, an embedded software toolkit for IoT applications
 using Lua scripting with HTTP(S), WebSockets, MQTT, and device I/O.

* netutils/xedge: Dependency manager that downloads BAS library
  and BAS-Resources, generates XedgeZip.c during build

* examples/xedge_demo: Complete example showing Xedge integration
  with HTTP server, Lua runtime, and SNTP time synchronization

Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
This commit is contained in:
RTL 2025-05-20 08:52:09 +02:00 committed by Alan C. Assis
parent 72668d7234
commit 2de49b8b22
8 changed files with 495 additions and 0 deletions

View file

@ -0,0 +1,41 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
config EXAMPLES_XEDGE_DEMO
tristate "Xedge IoT Toolkit Demo"
depends on NETUTILS_XEDGE && ALLOW_GPL_COMPONENTS
default n
---help---
Simple demonstration of the Xedge IoT Toolkit library.
This example shows how to integrate and use the Xedge library
in your NuttX application. Xedge provides a high-level development
environment for creating IoT and industrial device applications
using Lua scripting with access to HTTP(S), WebSockets, MQTT,
file system, and device I/O.
Note: This example requires the NETUTILS_XEDGE library to be enabled.
if EXAMPLES_XEDGE_DEMO
config EXAMPLES_XEDGE_DEMO_PROGNAME
string "Program name"
default "xedge_demo"
---help---
This is the name of the ELF executable for the Xedge demo application in NSH.
config EXAMPLES_XEDGE_DEMO_PRIORITY
int "Xedge demo task priority"
default 100
---help---
Set the task priority for the Xedge demo application.
config EXAMPLES_XEDGE_DEMO_STACKSIZE
int "Xedge demo stack size"
default 20000
---help---
Set the stack size for the Xedge demo application.
endif

View file

@ -0,0 +1,25 @@
############################################################################
# apps/examples/xedge_demo/Make.defs
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
ifneq ($(CONFIG_EXAMPLES_XEDGE_DEMO),)
CONFIGURED_APPS += $(APPDIR)/examples/xedge_demo
endif

View file

@ -0,0 +1,33 @@
# ##############################################################################
# apps/examples/xedge_demo/CMakeLists.txt
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
# license agreements. See the NOTICE file distributed with this work for
# additional information regarding copyright ownership. The ASF licenses this
# file to you under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
#
# ##############################################################################
include $(APPDIR)/Make.defs
PROGNAME = $(CONFIG_EXAMPLES_XEDGE_DEMO_PROGNAME)
PRIORITY = $(CONFIG_EXAMPLES_XEDGE_DEMO_PRIORITY)
STACKSIZE = $(CONFIG_EXAMPLES_XEDGE_DEMO_STACKSIZE)
MODULE = $(CONFIG_EXAMPLES_XEDGE_DEMO)
MAINSRC = xedge_main.c
include $(APPDIR)/Application.mk

View file

@ -0,0 +1,240 @@
/***************************************************************************
* apps/examples/xedge_demo/xedge_main.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
***************************************************************************/
/* Xedge NuttX Startup Code (may need adjustments)
*
* Additional License Note: Xedge, based on the Barracuda
* App Server, uses the license options explained here:
* https://github.com/RealTimeLogic/BAS#license
* This repo does not include Xedge and the Barracuda App Server
* library and must be downloaded separately. The dependencies
* are automatically downloaded in apps/netutils/xedge/.
*/
/***************************************************************************
* Included Files
***************************************************************************/
#include <nuttx/config.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <syslog.h>
#include <pthread.h>
#include <netutils/ntpclient.h>
#include <HttpTrace.h>
#include <BaDiskIo.h>
#include <BaServerLib.h>
#include "../../netutils/xedge/BAS/examples/xedge/src/xedge.h"
/***************************************************************************
* Pre-processor Definitions
***************************************************************************/
/* The code uses identifiers from the third-party Barracuda App Server
* library, which follows a camelCase naming style:
* https://realtimelogic.com/ba/doc/en/C/introduction.html#oo_c
* These identifiers are used directly and will trigger "Mixed Case"
* warnings in tools like nxstyle, which are safe to ignore in this case.
*/
/***************************************************************************
* Private Data
***************************************************************************/
static int running = FALSE; /* Running mode: 2 running, 1 exiting, 0 stopped */
/* BAS is configured to use dlmalloc for NuttX. This is the pool.
* 2M : recommended minimum
*/
static char poolbuf[2 * 1024 * 1024];
extern LThreadMgr ltMgr; /* The LThreadMgr configured in xedge.c */
/***************************************************************************
* External Function Prototypes
***************************************************************************/
/* barracuda(): BAS/examples/xedge/src/xedge.c */
extern void barracuda(void);
extern void init_dlmalloc(char *heapstart, char *heapend); /* dlmalloc.c */
extern int (*platformInitDiskIo)(DiskIo *io); /* xedge.c */
/***************************************************************************
* Private Functions
***************************************************************************/
/* The following two functions are copied from the example:
* https://github.com/RealTimeLogic/BAS/blob/main/examples/xedge/src/led.c
* Details:
* https://realtimelogic.com/ba/examples/xedge/readme.html#time
*/
/* This callback is called by one of the threads managed by LThreadMgr
* when a job is taken off the queue and executed. The callback
* attempts to find the global Lua function '_XedgeEvent', and if the
* function is found, it will be executed as follows: _XedgeEvent("sntp")
*/
static void execevent(ThreadJob *job, int msgh, LThreadMgr *mgr)
{
lua_State *L = job->Lt;
lua_pushglobaltable(L);
lua_getfield(L, -1, "_XedgeEvent");
if (lua_isfunction(L, -1))
{
lua_pushstring(L, "sntp");
lua_pcall(L, 1, 0, msgh);
}
}
/* Thread started by xedgeOpenAUX() */
static void *checktimethread(void *arg)
{
ThreadMutex *dm = HttpServer_getMutex(ltMgr.server);
const char *d = __DATE__;
char buf[50];
(void)arg;
if (!(basnprintf(buf, sizeof(buf), "Mon, %c%c %c%c%c %s %s",
d[4], d[5], d[0], d[1], d[2], d + 7, __TIME__) < 0))
{
BaTime t = baParseDate(buf);
if (t)
{
t -= 24 * 60 * 60;
while (baGetUnixTime() < t)
{
Thread_sleep(500);
}
ThreadJob *job = ThreadJob_lcreate(sizeof(ThreadJob), execevent);
ThreadMutex_set(dm);
LThreadMgr_run(&ltMgr, job);
ThreadMutex_release(dm);
}
}
return NULL;
}
static void panic(BaFatalErrorCodes ecode1,
unsigned int ecode2,
const char *file,
int line)
{
syslog(LOG_ERR, "Fatal error in Barracuda %d %d %s %d\n",
ecode1, ecode2, file, line);
exit(1);
}
/* Redirect server's HttpTrace to syslog.
* https://realtimelogic.com/ba/doc/en/C/reference/html/structHttpTrace.html
*/
static void flushtrace(char *buf, int buflen)
{
buf[buflen] = 0;
syslog(LOG_INFO, "%s", buf);
}
static void sighandler(int signo)
{
if (running)
{
printf("\nGot SIGTERM; exiting...\n");
setDispExit();
/* NuttX feature: Must wait for socket select() to return */
Thread_sleep(2000);
}
}
/***************************************************************************
* Public Functions
***************************************************************************/
/* xedge.c calls this to initialize the IO.
* Change "/mnt/lfs" to your preference.
*/
int xedgeInitDiskIo(DiskIo *io)
{
if (DiskIo_setRootDir(io, "/mnt/lfs"))
{
syslog(LOG_ERR, "Error: cannot set root to /mnt/lfs\n");
return -1;
}
return 0;
}
/* xedge.c calls this; include your Lua bindings here.
* Tutorial: https://tutorial.realtimelogic.com/Lua-Bindings.lsp
*/
int xedgeOpenAUX(XedgeOpenAUX *aux)
{
pthread_t thread;
pthread_attr_t attr;
struct sched_param param;
(void)aux;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 4096);
param.sched_priority = SCHED_PRIORITY_DEFAULT;
pthread_attr_setschedparam(&attr, &param);
pthread_create(&thread, &attr, checktimethread, NULL);
return 0;
}
int main(int argc, FAR char *argv[])
{
if (running)
{
printf("Already running!\n");
return 1;
}
signal(SIGINT, sighandler);
signal(SIGTERM, sighandler);
ntpc_start();
init_dlmalloc(poolbuf, poolbuf + sizeof(poolbuf));
HttpTrace_setFLushCallback(flushtrace);
HttpServer_setErrHnd(panic);
running = TRUE;
barracuda();
running = FALSE;
printf("Exiting Xedge\n");
return 0;
}

3
netutils/xedge/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/BAS
/BAS-Resources
/*.o

23
netutils/xedge/Kconfig Normal file
View file

@ -0,0 +1,23 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
config NETUTILS_XEDGE
tristate "Xedge IoT Toolkit Dependencies"
depends on ALLOW_GPL_COMPONENTS
default n
---help---
Download and prepare Xedge IoT Toolkit dependencies (BAS and BAS-Resources).
Xedge is an embedded software toolkit designed to enable high-level developers
(e.g., web and Lua programmers) to create sophisticated, secure IoT and industrial
device applications. It abstracts low-level embedded development through a lightweight
runtime built on top of the Barracuda App Server and Lua.
This option will download the required Barracuda App Server and BAS-Resources
repositories during the build process, making them available for applications
that want to use Xedge.
After enabling this, you can use the examples/xedge_demo as a reference
for integrating Xedge into your own applications.

35
netutils/xedge/Make.defs Normal file
View file

@ -0,0 +1,35 @@
############################################################################
# apps/netutils/xedge/Make.defs
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
ifneq ($(CONFIG_NETUTILS_XEDGE),)
CONFIGURED_APPS += $(APPDIR)/netutils/xedge
CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/netutils/xedge/BAS/inc
CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/netutils/xedge/BAS/inc/arch/Posix
CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/netutils/xedge/BAS/inc/arch/NET/Posix
CFLAGS += -DNO_INIT_DISK_IO
CFLAGS += -DUSE_DBGMON=1
CFLAGS += -DUSE_IPV6
endif

95
netutils/xedge/Makefile Normal file
View file

@ -0,0 +1,95 @@
############################################################################
# apps/netutils/xedge/Makefile
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
# license agreements. See the NOTICE file distributed with this work for
# additional information regarding copyright ownership. The ASF licenses this
# file to you under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
#
# ##############################################################################
include $(APPDIR)/Make.defs
BAS_UNPACKNAME = BAS
BAS_HASH = 9f74a2f778b002ad8441471b8a7a5b13172dbe76
BAS_RESOURCES_UNPACKNAME = BAS-Resources
BAS_RESOURCES_HASH = 227a4b998300fa4cfde871dc7dac92c09e1636c2
BAS_ZIP_URL = https://github.com/RealTimeLogic/BAS/archive/$(BAS_HASH).zip
BAS_RESOURCES_ZIP_URL = https://github.com/RealTimeLogic/BAS-Resources/archive/$(BAS_RESOURCES_HASH).zip
XEDGEZIP = BAS/examples/xedge/XedgeZip.c
BAS_SRC = $(BAS_UNPACKNAME)$(DELIM)src
BAS_ARCH_SRC = $(BAS_SRC)$(DELIM)arch$(DELIM)Posix
BAS_NET_SRC = $(BAS_SRC)$(DELIM)arch$(DELIM)NET$(DELIM)generic
BAS_DISKIO_SRC = $(BAS_SRC)$(DELIM)DiskIo$(DELIM)posix
BAS_XEDGE_SRC = $(BAS_UNPACKNAME)$(DELIM)examples$(DELIM)xedge$(DELIM)src
VPATH += $(BAS_SRC)
VPATH += $(BAS_ARCH_SRC)
VPATH += $(BAS_NET_SRC)
VPATH += $(BAS_DISKIO_SRC)
VPATH += $(BAS_XEDGE_SRC)
VPATH += $(BAS_UNPACKNAME)/examples/xedge
CSRCS = BAS.c dlmalloc.c ThreadLib.c SoDisp.c BaFile.c xedge.c XedgeZip.c
# Download and prepare BAS and BAS-Resources
xedge-deps:
# ############################################################################
# Config and Fetch xedge
# ############################################################################
@if [ ! -d $(BAS_UNPACKNAME) ]; then \
echo "Downloading BAS from hash $(BAS_HASH)..."; \
curl -f -L $(BAS_ZIP_URL) -o bas-temp.zip || \
(echo "Error downloading BAS"; exit 1); \
unzip -q bas-temp.zip; \
mv BAS-$(BAS_HASH) $(BAS_UNPACKNAME); \
rm -f bas-temp.zip; \
fi
@if [ ! -d $(BAS_RESOURCES_UNPACKNAME) ]; then \
echo "Downloading BAS-Resources from hash $(BAS_RESOURCES_HASH)..."; \
curl -f -L $(BAS_RESOURCES_ZIP_URL) -o resources-temp.zip || \
(echo "Error downloading BAS-Resources"; exit 1); \
unzip -q resources-temp.zip; \
mv BAS-Resources-$(BAS_RESOURCES_HASH) $(BAS_RESOURCES_UNPACKNAME); \
rm -f resources-temp.zip; \
fi
# ############################################################################
# Library Configuration
# ############################################################################
@if [ ! -f "$(XEDGEZIP)" ]; then \
echo "Creating XedgeZip.c"; \
cd $(BAS_RESOURCES_UNPACKNAME)/build/ && \
printf "n\nl\nn\n" | bash Xedge.sh > /dev/null && \
cp XedgeZip.c ../../$(BAS_UNPACKNAME)/examples/xedge/ || exit 1; \
fi
$(CSRCS:.c=$(OBJEXT)): xedge-deps
ifeq ($(wildcard $(BAS_UNPACKNAME)/.git),)
distclean:: xedge-deps
$(call DELDIR, $(BAS_UNPACKNAME))
$(call DELDIR, $(BAS_RESOURCES_UNPACKNAME))
context:: xedge-deps
endif
include $(APPDIR)/Application.mk