|
| 1 | +/*************************************************************************** |
| 2 | + * apps/examples/xedge_demo/xedge_main.c |
| 3 | + * |
| 4 | + * SPDX-License-Identifier: Apache-2.0 |
| 5 | + * |
| 6 | + * Licensed to the Apache Software Foundation (ASF) under one or more |
| 7 | + * contributor license agreements. See the NOTICE file distributed with |
| 8 | + * this work for additional information regarding copyright ownership. The |
| 9 | + * ASF licenses this file to you under the Apache License, Version 2.0 (the |
| 10 | + * "License"); you may not use this file except in compliance with the |
| 11 | + * License. You may obtain a copy of the License at |
| 12 | + * |
| 13 | + * http://www.apache.org/licenses/LICENSE-2.0 |
| 14 | + * |
| 15 | + * Unless required by applicable law or agreed to in writing, software |
| 16 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 17 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 18 | + * License for the specific language governing permissions and limitations |
| 19 | + * under the License. |
| 20 | + * |
| 21 | + ***************************************************************************/ |
| 22 | + |
| 23 | +/* Xedge NuttX Startup Code (may need adjustments) |
| 24 | + * |
| 25 | + * Additional License Note: Xedge, based on the Barracuda |
| 26 | + * App Server, uses the license options explained here: |
| 27 | + * https://github.com/RealTimeLogic/BAS#license |
| 28 | + * This repo does not include Xedge and the Barracuda App Server |
| 29 | + * library and must be downloaded separately. The dependencies |
| 30 | + * are automatically downloaded in apps/netutils/xedge/. |
| 31 | + */ |
| 32 | + |
| 33 | +/*************************************************************************** |
| 34 | + * Included Files |
| 35 | + ***************************************************************************/ |
| 36 | + |
| 37 | +#include <nuttx/config.h> |
| 38 | +#include <stdio.h> |
| 39 | +#include <stdlib.h> |
| 40 | +#include <signal.h> |
| 41 | +#include <syslog.h> |
| 42 | +#include <pthread.h> |
| 43 | +#include <netutils/ntpclient.h> |
| 44 | +#include <HttpTrace.h> |
| 45 | +#include <BaDiskIo.h> |
| 46 | +#include <BaServerLib.h> |
| 47 | +#include "../../netutils/xedge/BAS/examples/xedge/src/xedge.h" |
| 48 | + |
| 49 | +/*************************************************************************** |
| 50 | + * Pre-processor Definitions |
| 51 | + ***************************************************************************/ |
| 52 | + |
| 53 | +/* The code uses identifiers from the third-party Barracuda App Server |
| 54 | + * library, which follows a camelCase naming style: |
| 55 | + * https://realtimelogic.com/ba/doc/en/C/introduction.html#oo_c |
| 56 | + * These identifiers are used directly and will trigger "Mixed Case" |
| 57 | + * warnings in tools like nxstyle, which are safe to ignore in this case. |
| 58 | + */ |
| 59 | + |
| 60 | +/*************************************************************************** |
| 61 | + * Private Data |
| 62 | + ***************************************************************************/ |
| 63 | + |
| 64 | +static int running = FALSE; /* Running mode: 2 running, 1 exiting, 0 stopped */ |
| 65 | + |
| 66 | +/* BAS is configured to use dlmalloc for NuttX. This is the pool. |
| 67 | + * 2M : recommended minimum |
| 68 | + */ |
| 69 | + |
| 70 | +static char poolbuf[2 * 1024 * 1024]; |
| 71 | + |
| 72 | +extern LThreadMgr ltMgr; /* The LThreadMgr configured in xedge.c */ |
| 73 | + |
| 74 | +/*************************************************************************** |
| 75 | + * External Function Prototypes |
| 76 | + ***************************************************************************/ |
| 77 | + |
| 78 | +/* barracuda(): BAS/examples/xedge/src/xedge.c */ |
| 79 | + |
| 80 | +extern void barracuda(void); |
| 81 | +extern void init_dlmalloc(char *heapstart, char *heapend); /* dlmalloc.c */ |
| 82 | +extern int (*platformInitDiskIo)(DiskIo *io); /* xedge.c */ |
| 83 | + |
| 84 | +/*************************************************************************** |
| 85 | + * Private Functions |
| 86 | + ***************************************************************************/ |
| 87 | + |
| 88 | +/* The following two functions are copied from the example: |
| 89 | + * https://github.com/RealTimeLogic/BAS/blob/main/examples/xedge/src/led.c |
| 90 | + * Details: |
| 91 | + * https://realtimelogic.com/ba/examples/xedge/readme.html#time |
| 92 | + */ |
| 93 | + |
| 94 | +/* This callback is called by one of the threads managed by LThreadMgr |
| 95 | + * when a job is taken off the queue and executed. The callback |
| 96 | + * attempts to find the global Lua function '_XedgeEvent', and if the |
| 97 | + * function is found, it will be executed as follows: _XedgeEvent("sntp") |
| 98 | + */ |
| 99 | + |
| 100 | +static void execevent(ThreadJob *job, int msgh, LThreadMgr *mgr) |
| 101 | +{ |
| 102 | + lua_State *L = job->Lt; |
| 103 | + lua_pushglobaltable(L); |
| 104 | + lua_getfield(L, -1, "_XedgeEvent"); |
| 105 | + |
| 106 | + if (lua_isfunction(L, -1)) |
| 107 | + { |
| 108 | + lua_pushstring(L, "sntp"); |
| 109 | + lua_pcall(L, 1, 0, msgh); |
| 110 | + } |
| 111 | +} |
| 112 | + |
| 113 | +/* Thread started by xedgeOpenAUX() */ |
| 114 | + |
| 115 | +static void *checktimethread(void *arg) |
| 116 | +{ |
| 117 | + ThreadMutex *dm = HttpServer_getMutex(ltMgr.server); |
| 118 | + const char *d = __DATE__; |
| 119 | + char buf[50]; |
| 120 | + |
| 121 | + (void)arg; |
| 122 | + |
| 123 | + if (!(basnprintf(buf, sizeof(buf), "Mon, %c%c %c%c%c %s %s", |
| 124 | + d[4], d[5], d[0], d[1], d[2], d + 7, __TIME__) < 0)) |
| 125 | + { |
| 126 | + BaTime t = baParseDate(buf); |
| 127 | + if (t) |
| 128 | + { |
| 129 | + t -= 24 * 60 * 60; |
| 130 | + while (baGetUnixTime() < t) |
| 131 | + { |
| 132 | + Thread_sleep(500); |
| 133 | + } |
| 134 | + |
| 135 | + ThreadJob *job = ThreadJob_lcreate(sizeof(ThreadJob), execevent); |
| 136 | + ThreadMutex_set(dm); |
| 137 | + LThreadMgr_run(<Mgr, job); |
| 138 | + ThreadMutex_release(dm); |
| 139 | + } |
| 140 | + } |
| 141 | + |
| 142 | + return NULL; |
| 143 | +} |
| 144 | + |
| 145 | +static void panic(BaFatalErrorCodes ecode1, |
| 146 | + unsigned int ecode2, |
| 147 | + const char *file, |
| 148 | + int line) |
| 149 | +{ |
| 150 | + syslog(LOG_ERR, "Fatal error in Barracuda %d %d %s %d\n", |
| 151 | + ecode1, ecode2, file, line); |
| 152 | + exit(1); |
| 153 | +} |
| 154 | + |
| 155 | +/* Redirect server's HttpTrace to syslog. |
| 156 | + * https://realtimelogic.com/ba/doc/en/C/reference/html/structHttpTrace.html |
| 157 | + */ |
| 158 | + |
| 159 | +static void flushtrace(char *buf, int buflen) |
| 160 | +{ |
| 161 | + buf[buflen] = 0; |
| 162 | + syslog(LOG_INFO, "%s", buf); |
| 163 | +} |
| 164 | + |
| 165 | +static void sighandler(int signo) |
| 166 | +{ |
| 167 | + if (running) |
| 168 | + { |
| 169 | + printf("\nGot SIGTERM; exiting...\n"); |
| 170 | + setDispExit(); |
| 171 | + |
| 172 | + /* NuttX feature: Must wait for socket select() to return */ |
| 173 | + |
| 174 | + Thread_sleep(2000); |
| 175 | + } |
| 176 | +} |
| 177 | + |
| 178 | +/*************************************************************************** |
| 179 | + * Public Functions |
| 180 | + ***************************************************************************/ |
| 181 | + |
| 182 | +/* xedge.c calls this to initialize the IO. |
| 183 | + * Change "/mnt/lfs" to your preference. |
| 184 | + */ |
| 185 | + |
| 186 | +int xedgeInitDiskIo(DiskIo *io) |
| 187 | +{ |
| 188 | + if (DiskIo_setRootDir(io, "/mnt/lfs")) |
| 189 | + { |
| 190 | + syslog(LOG_ERR, "Error: cannot set root to /mnt/lfs\n"); |
| 191 | + return -1; |
| 192 | + } |
| 193 | + |
| 194 | + return 0; |
| 195 | +} |
| 196 | + |
| 197 | +/* xedge.c calls this; include your Lua bindings here. |
| 198 | + * Tutorial: https://tutorial.realtimelogic.com/Lua-Bindings.lsp |
| 199 | + */ |
| 200 | + |
| 201 | +int xedgeOpenAUX(XedgeOpenAUX *aux) |
| 202 | +{ |
| 203 | + pthread_t thread; |
| 204 | + pthread_attr_t attr; |
| 205 | + struct sched_param param; |
| 206 | + |
| 207 | + (void)aux; |
| 208 | + |
| 209 | + pthread_attr_init(&attr); |
| 210 | + pthread_attr_setstacksize(&attr, 4096); |
| 211 | + param.sched_priority = SCHED_PRIORITY_DEFAULT; |
| 212 | + pthread_attr_setschedparam(&attr, ¶m); |
| 213 | + pthread_create(&thread, &attr, checktimethread, NULL); |
| 214 | + |
| 215 | + return 0; |
| 216 | +} |
| 217 | + |
| 218 | +int main(int argc, FAR char *argv[]) |
| 219 | +{ |
| 220 | + if (running) |
| 221 | + { |
| 222 | + printf("Already running!\n"); |
| 223 | + return 1; |
| 224 | + } |
| 225 | + |
| 226 | + signal(SIGINT, sighandler); |
| 227 | + signal(SIGTERM, sighandler); |
| 228 | + |
| 229 | + ntpc_start(); |
| 230 | + init_dlmalloc(poolbuf, poolbuf + sizeof(poolbuf)); |
| 231 | + HttpTrace_setFLushCallback(flushtrace); |
| 232 | + HttpServer_setErrHnd(panic); |
| 233 | + |
| 234 | + running = TRUE; |
| 235 | + barracuda(); |
| 236 | + running = FALSE; |
| 237 | + |
| 238 | + printf("Exiting Xedge\n"); |
| 239 | + return 0; |
| 240 | +} |
0 commit comments