examples: Added watcher and watched examples.
This commit is contained in:
parent
b97395dee1
commit
c3494c310a
35
examples/watched/Kconfig
Normal file
35
examples/watched/Kconfig
Normal file
@ -0,0 +1,35 @@
|
||||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||
#
|
||||
|
||||
config EXAMPLES_WATCHED
|
||||
tristate "Watched example"
|
||||
default y
|
||||
depends on EXAMPLES_WATCHER
|
||||
---help---
|
||||
This application works with the watcher example and plays
|
||||
the role of the watched task. This process will create 2
|
||||
watched tasks. These tasks will subscribe to be watched.
|
||||
One task will feed the dog and the other will starve the dog.
|
||||
So, the watchdog timer will expire and the offending task will
|
||||
be printed.
|
||||
|
||||
if EXAMPLES_WATCHED
|
||||
|
||||
config EXAMPLES_WATCHED_PROGNAME
|
||||
string "Program name"
|
||||
default "watched"
|
||||
---help---
|
||||
This is the name of the program that will be used when the NSH ELF
|
||||
program is installed.
|
||||
|
||||
config EXAMPLES_WATCHED_PRIORITY
|
||||
int "Watched task priority"
|
||||
default 100
|
||||
|
||||
config EXAMPLES_WATCHED_STACKSIZE
|
||||
int "Watched stack size"
|
||||
default DEFAULT_TASK_STACKSIZE
|
||||
|
||||
endif
|
24
examples/watched/Make.defs
Normal file
24
examples/watched/Make.defs
Normal file
@ -0,0 +1,24 @@
|
||||
############################################################################
|
||||
# apps/examples/watched/Make.defs
|
||||
# Adds selected applications to apps/ build
|
||||
#
|
||||
# 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_WATCHED),)
|
||||
CONFIGURED_APPS += $(APPDIR)/examples/watched
|
||||
endif
|
35
examples/watched/Makefile
Normal file
35
examples/watched/Makefile
Normal file
@ -0,0 +1,35 @@
|
||||
############################################################################
|
||||
# examples/watched/Makefile
|
||||
#
|
||||
# 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
|
||||
|
||||
# Watched built-in application info
|
||||
|
||||
PROGNAME = $(CONFIG_EXAMPLES_WATCHED_PROGNAME)
|
||||
PRIORITY = $(CONFIG_EXAMPLES_WATCHED_PRIORITY)
|
||||
STACKSIZE = $(CONFIG_EXAMPLES_WATCHED_STACKSIZE)
|
||||
MODULE = $(CONFIG_EXAMPLES_WATCHED)
|
||||
|
||||
# Watched Example
|
||||
|
||||
CSRCS = watched.c
|
||||
MAINSRC = watched_main.c
|
||||
|
||||
include $(APPDIR)/Application.mk
|
176
examples/watched/watched.c
Normal file
176
examples/watched/watched.c
Normal file
@ -0,0 +1,176 @@
|
||||
/****************************************************************************
|
||||
* examples/watched/watched.c
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "watched.h"
|
||||
#include <signal.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Private Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct watcher_info_s g_watcher_info =
|
||||
{
|
||||
.watcher_pid = -1,
|
||||
.info_file_name = "/mnt/watcher/info.txt"
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
bool watched_is_watcher_on(void)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
/* Check if the watcher has already been initialized */
|
||||
|
||||
fp = fopen(g_watcher_info.info_file_name, "r");
|
||||
if (fp)
|
||||
{
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int watched_read_watcher_info(struct watched_info_s *info)
|
||||
{
|
||||
int ret = OK;
|
||||
int watched_pid = getpid();
|
||||
FILE *fp;
|
||||
|
||||
/* Load Watcher Info in case it was not loaded yet */
|
||||
|
||||
if (g_watcher_info.watcher_pid < 0)
|
||||
{
|
||||
/* Reading watcher value from file */
|
||||
|
||||
fp = fopen(g_watcher_info.info_file_name, "r");
|
||||
if (fp == NULL)
|
||||
{
|
||||
int errcode = errno;
|
||||
fprintf(stderr, "ERROR: Failed to open %s: %d\n",
|
||||
g_watcher_info.info_file_name, errcode);
|
||||
ret = errcode;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
fscanf(fp, "%d %d %d %d %d", (int *)&(g_watcher_info.watcher_pid),
|
||||
&(g_watcher_info.signal), &(g_watcher_info.sub_cmd),
|
||||
&(g_watcher_info.feed_cmd), &(g_watcher_info.unsub_cmd));
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/* Initialize Wacthed Info */
|
||||
|
||||
info->sub_request.task_id = watched_pid;
|
||||
info->sub_request.code = g_watcher_info.sub_cmd;
|
||||
info->sub_value.sival_ptr = &(info->sub_request);
|
||||
|
||||
info->unsub_request.task_id = watched_pid;
|
||||
info->unsub_request.code = g_watcher_info.unsub_cmd;
|
||||
info->unsub_value.sival_ptr = &(info->unsub_request);
|
||||
|
||||
info->feed_request.task_id = watched_pid;
|
||||
info->feed_request.code = g_watcher_info.feed_cmd;
|
||||
info->feed_value.sival_ptr = &(info->feed_request);
|
||||
|
||||
errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int watched_subscribe(struct watched_info_s *info)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Signal watcher = Request to subscribe */
|
||||
|
||||
ret =
|
||||
sigqueue(g_watcher_info.watcher_pid, g_watcher_info.signal,
|
||||
info->sub_value);
|
||||
if (ret == ERROR)
|
||||
{
|
||||
int errcode = errno;
|
||||
fprintf(stderr, "subscribe: error %d\n", errcode);
|
||||
ret = errcode;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int watched_unsubscribe(struct watched_info_s *info)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Signal watcher = Request to unsubscribe */
|
||||
|
||||
ret =
|
||||
sigqueue(g_watcher_info.watcher_pid, g_watcher_info.signal,
|
||||
info->unsub_value);
|
||||
if (ret == ERROR)
|
||||
{
|
||||
int errcode = errno;
|
||||
fprintf(stderr, "unsubscribe: error %d\n", errcode);
|
||||
ret = errcode;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int feed_dog(struct watched_info_s *info)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Signal watcher = Request to feed the dog */
|
||||
|
||||
ret =
|
||||
sigqueue(g_watcher_info.watcher_pid, g_watcher_info.signal,
|
||||
info->feed_value);
|
||||
if (ret == ERROR)
|
||||
{
|
||||
int errcode = errno;
|
||||
fprintf(stderr, "feed_dog: error %d\n", errcode);
|
||||
ret = errcode;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
79
examples/watched/watched.h
Normal file
79
examples/watched/watched.h
Normal file
@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
* examples/watched/watched.h
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __EXAMPLES_WATCHER_WATCHED_H
|
||||
#define __EXAMPLES_WATCHER_WATCHED_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <signal.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
struct watcher_info_s
|
||||
{
|
||||
int sub_cmd;
|
||||
int unsub_cmd;
|
||||
int feed_cmd;
|
||||
int signal;
|
||||
pid_t watcher_pid;
|
||||
const char info_file_name[];
|
||||
};
|
||||
|
||||
struct request_s
|
||||
{
|
||||
pid_t task_id;
|
||||
volatile int code;
|
||||
};
|
||||
|
||||
struct watched_info_s
|
||||
{
|
||||
struct request_s sub_request;
|
||||
struct request_s unsub_request;
|
||||
struct request_s feed_request;
|
||||
union sigval sub_value;
|
||||
union sigval unsub_value;
|
||||
union sigval feed_value;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
bool watched_is_watcher_on(void);
|
||||
int watched_read_watcher_info(struct watched_info_s *info);
|
||||
int watched_subscribe(struct watched_info_s *info);
|
||||
int watched_unsubscribe(struct watched_info_s *info);
|
||||
int feed_dog(struct watched_info_s *info);
|
||||
|
||||
#endif /* __EXAMPLES_WATCHER_WATCHED_H */
|
180
examples/watched/watched_main.c
Normal file
180
examples/watched/watched_main.c
Normal file
@ -0,0 +1,180 @@
|
||||
/****************************************************************************
|
||||
* examples/watched/watched_main.c
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include "watched.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: Task that feeds the dog
|
||||
****************************************************************************/
|
||||
|
||||
static int task1(int argc, FAR char *argv[])
|
||||
{
|
||||
struct watched_info_s watched_info;
|
||||
|
||||
/* Get the necessary information from watcher */
|
||||
|
||||
watched_read_watcher_info(&watched_info);
|
||||
|
||||
watched_subscribe(&watched_info);
|
||||
|
||||
for (; ; )
|
||||
{
|
||||
feed_dog(&watched_info);
|
||||
sleep(3);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: Task that doesn't feed the dog
|
||||
****************************************************************************/
|
||||
|
||||
static int task2(int argc, FAR char *argv[])
|
||||
{
|
||||
int counter = 0;
|
||||
struct watched_info_s watched_info;
|
||||
|
||||
/* Get the necessary information from watcher */
|
||||
|
||||
watched_read_watcher_info(&watched_info);
|
||||
|
||||
watched_subscribe(&watched_info);
|
||||
|
||||
for (; ; )
|
||||
{
|
||||
sleep((CONFIG_EXAMPLES_WATCHER_TIMEOUT) / 1000);
|
||||
counter++;
|
||||
if (counter == 5)
|
||||
{
|
||||
watched_unsubscribe(&watched_info);
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: null_main
|
||||
****************************************************************************/
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret = OK;
|
||||
|
||||
/* Check if the watcher has already been initialized */
|
||||
|
||||
if (!watched_is_watcher_on())
|
||||
{
|
||||
printf("Please, enable the watcher service \
|
||||
before subscribing tasks!\n");
|
||||
ret = ENOENT;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
printf("Starting watched tasks\n");
|
||||
|
||||
/* Starting Tasks Tasks 1 and 4 will subscribe, but they will not feed the
|
||||
* dog. Tasks 2 and 3 will subscribe and will feed the dog each 3 secs.
|
||||
*/
|
||||
|
||||
printf("Creating Watched Task 1 - It will not feed the dog\n");
|
||||
|
||||
ret = task_create("Watched Task 1", CONFIG_EXAMPLES_WATCHED_PRIORITY,
|
||||
CONFIG_EXAMPLES_WATCHED_STACKSIZE, task2, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
printf("watched_main: ERROR: Failed to start Watched Task 1: %d\n",
|
||||
errcode);
|
||||
ret = errcode;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
printf("Creating Watched Task 2 - It will feed the dog\n");
|
||||
|
||||
ret = task_create("Watched Task 2", CONFIG_EXAMPLES_WATCHED_PRIORITY,
|
||||
CONFIG_EXAMPLES_WATCHED_STACKSIZE, task1, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
printf("watched_main: ERROR: Failed to start Watched Task 2: %d\n",
|
||||
errcode);
|
||||
ret = errcode;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
printf("Creating Watched Task 3 - It will feed the dog\n");
|
||||
|
||||
ret = task_create("Watched Task 3", CONFIG_EXAMPLES_WATCHED_PRIORITY,
|
||||
CONFIG_EXAMPLES_WATCHED_STACKSIZE, task1, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
printf("watched_main: ERROR: Failed to start Watched Task 3: %d\n",
|
||||
errcode);
|
||||
ret = errcode;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
printf("Creating Watched Task 4 - It will not feed the dog\n");
|
||||
|
||||
ret = task_create("Watched Task 4", CONFIG_EXAMPLES_WATCHED_PRIORITY,
|
||||
CONFIG_EXAMPLES_WATCHED_STACKSIZE, task2, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
printf("watched_main: ERROR: Failed to start Watched Task 4: %d\n",
|
||||
errcode);
|
||||
ret = errcode;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
errout:
|
||||
return ret;
|
||||
}
|
49
examples/watcher/Kconfig
Normal file
49
examples/watcher/Kconfig
Normal file
@ -0,0 +1,49 @@
|
||||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||
#
|
||||
|
||||
config EXAMPLES_WATCHER
|
||||
tristate "Watcher example"
|
||||
default n
|
||||
---help---
|
||||
Enable the watcher example. The watcher is a task that will monitor
|
||||
other tasks that have previously subscribed to be watched. If the
|
||||
watched tasks don't signal the watcher during the watchdog time period,
|
||||
the watchdog timer will expire and the watcher will print the tasks that
|
||||
did not signal and the ones that signaled. This example will only be supported
|
||||
by the chips that supports interrupt on timeout, i.e., which have the \"capture\"
|
||||
command implemented.
|
||||
|
||||
if EXAMPLES_WATCHER
|
||||
|
||||
config EXAMPLES_WATCHER_PROGNAME
|
||||
string "Program name"
|
||||
default "watcher"
|
||||
---help---
|
||||
This is the name of the program that will be used when the NSH ELF
|
||||
program is installed.
|
||||
|
||||
config EXAMPLES_WATCHER_PRIORITY
|
||||
int "Watcher task priority"
|
||||
default 100
|
||||
|
||||
config EXAMPLES_WATCHER_STACKSIZE
|
||||
int "Watcher stack size"
|
||||
default DEFAULT_TASK_STACKSIZE
|
||||
|
||||
config EXAMPLES_WATCHER_DEVPATH
|
||||
string "Watchdog device path"
|
||||
default "/dev/watchdog0"
|
||||
|
||||
config EXAMPLES_WATCHER_TIMEOUT
|
||||
int "Watchdog timeout in ms"
|
||||
default 5000
|
||||
|
||||
config EXAMPLES_WATCHER_SIGNAL
|
||||
int "Signal Number for communication"
|
||||
default 17
|
||||
---help---
|
||||
This is the Signal Number used for communication between the watcher task and the watched tasks.
|
||||
|
||||
endif
|
23
examples/watcher/Make.defs
Normal file
23
examples/watcher/Make.defs
Normal file
@ -0,0 +1,23 @@
|
||||
############################################################################
|
||||
# apps/examples/watcher/Make.defs
|
||||
#
|
||||
# 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_WATCHER),)
|
||||
CONFIGURED_APPS += $(APPDIR)/examples/watcher
|
||||
endif
|
35
examples/watcher/Makefile
Normal file
35
examples/watcher/Makefile
Normal file
@ -0,0 +1,35 @@
|
||||
############################################################################
|
||||
# apps/examples/watcher/Make.defs
|
||||
#
|
||||
# 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
|
||||
|
||||
# Watcher built-in application info
|
||||
|
||||
PROGNAME = $(CONFIG_EXAMPLES_WATCHER_PROGNAME)
|
||||
PRIORITY = $(CONFIG_EXAMPLES_WATCHER_PRIORITY)
|
||||
STACKSIZE = $(CONFIG_EXAMPLES_WATCHER_STACKSIZE)
|
||||
MODULE = $(CONFIG_EXAMPLES_WATCHER)
|
||||
|
||||
# Watcher Example
|
||||
|
||||
CSRCS = ramdisk.c wdt.c task_mn.c
|
||||
MAINSRC = watcher_main.c
|
||||
|
||||
include $(APPDIR)/Application.mk
|
138
examples/watcher/ramdisk.c
Normal file
138
examples/watcher/ramdisk.c
Normal file
@ -0,0 +1,138 @@
|
||||
/****************************************************************************
|
||||
* examples/watcher/ramdisk.c
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/boardctl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mount.h>
|
||||
#include <nuttx/drivers/ramdisk.h>
|
||||
|
||||
#include "fsutils/mkfatfs.h"
|
||||
#include "ramdisk.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define BUFFER_SIZE \
|
||||
(NSECTORS * SECTORSIZE)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct fat_format_s g_fmt = FAT_FORMAT_INITIALIZER;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
static const char g_source[] = MOUNT_DEVNAME;
|
||||
static const char g_filesystemtype[] = "vfat";
|
||||
static const char g_target[] = "/mnt/watcher";
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: create_ramdisk
|
||||
*
|
||||
* Description:
|
||||
* Create a RAM disk of the specified size formatting with a FAT file
|
||||
* system
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Return:
|
||||
* Zero on success, a negated errno on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int create_ramdisk(void)
|
||||
{
|
||||
struct boardioc_mkrd_s desc;
|
||||
int ret;
|
||||
|
||||
/* Create a RAMDISK device to manage */
|
||||
|
||||
desc.minor = MINOR; /* Minor device number of the RAM disk. */
|
||||
desc.nsectors = NSECTORS; /* The number of sectors in the RAM disk. */
|
||||
desc.sectsize = SECTORSIZE; /* The size of one sector in bytes. */
|
||||
desc.rdflags = RDFLAG_WRENABLED | RDFLAG_FUNLINK; /* See ramdisk.h. */
|
||||
|
||||
ret = boardctl(BOARDIOC_MKRD, (uintptr_t) & desc);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("create_ramdisk: Failed to create ramdisk at %s: %d\n",
|
||||
g_source, -ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Create a FAT filesystem on the ramdisk */
|
||||
|
||||
ret = mkfatfs(g_source, &g_fmt);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("mkfatfs: Failed to create FAT filesystem on ramdisk at %s\n",
|
||||
g_source);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int prepare_fs(void)
|
||||
{
|
||||
int ret;
|
||||
ret = create_ramdisk();
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
fprintf(stderr,
|
||||
"create_ramdisk: failed on creating RAM disk \
|
||||
and formatting it: %d\n",
|
||||
errcode);
|
||||
ret = errcode;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
ret = mount(g_source, g_target, g_filesystemtype, 0, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
fprintf(stderr, "mount: Failed to mount FS: %d\n", errcode);
|
||||
ret = errcode;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
errout:
|
||||
return ret;
|
||||
}
|
56
examples/watcher/ramdisk.h
Normal file
56
examples/watcher/ramdisk.h
Normal file
@ -0,0 +1,56 @@
|
||||
/****************************************************************************
|
||||
* examples/watcher/ramdisk.h
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __EXAMPLES_WATCHER_RAMDISK_H
|
||||
#define __EXAMPLES_WATCHER_RAMDISK_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define NSECTORS 64
|
||||
#define SECTORSIZE 512
|
||||
#define MINOR 0
|
||||
#define STR_MACRO(m) #m
|
||||
#define MKMOUNT_DEVNAME(m) "/dev/ram" STR_MACRO(m)
|
||||
#define MOUNT_DEVNAME MKMOUNT_DEVNAME(MINOR)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
int create_ramdisk(void);
|
||||
int prepare_fs(void);
|
||||
|
||||
#endif /* __EXAMPLES_WATCHER_RAMDISK_H */
|
313
examples/watcher/task_mn.c
Normal file
313
examples/watcher/task_mn.c
Normal file
@ -0,0 +1,313 @@
|
||||
/****************************************************************************
|
||||
* examples/watcher/task_mn.c
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/boardctl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <nuttx/note/noteram_driver.h>
|
||||
#include "task_mn.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
volatile struct request_s request;
|
||||
struct task_list_s watched_tasks =
|
||||
{
|
||||
.head = NULL,
|
||||
.tail = NULL
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
void task_mn_print_tasks_status(void)
|
||||
{
|
||||
int notefd;
|
||||
struct noteram_get_taskname_s task;
|
||||
struct task_node_s *node;
|
||||
|
||||
/* If the list is not empty */
|
||||
|
||||
if (watched_tasks.head != NULL)
|
||||
{
|
||||
/* Open the note driver */
|
||||
|
||||
notefd = open("/dev/note", O_RDONLY);
|
||||
if (notefd < 0)
|
||||
{
|
||||
fprintf(stderr, "trace: cannot open /dev/note\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Print all the nodes */
|
||||
|
||||
for (node = watched_tasks.head; node != NULL; node = node->next)
|
||||
{
|
||||
task.pid = node->task_id;
|
||||
ioctl(notefd, NOTERAM_GETTASKNAME, (unsigned long)&task);
|
||||
printf("%s ", task.taskname);
|
||||
if (node->reset)
|
||||
{
|
||||
printf("fed the dog.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("starved the dog.\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the note driver */
|
||||
|
||||
close(notefd);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "watcher: List is empty to print\n");
|
||||
}
|
||||
}
|
||||
|
||||
void task_mn_reset_all(void)
|
||||
{
|
||||
struct task_node_s *node;
|
||||
|
||||
for (node = watched_tasks.head; node != NULL; node = node->next)
|
||||
{
|
||||
node->reset = false;
|
||||
}
|
||||
}
|
||||
|
||||
struct task_node_s *task_mn_is_task_subscribed(pid_t id)
|
||||
{
|
||||
struct task_node_s *node;
|
||||
|
||||
/* If list is not empty */
|
||||
|
||||
if (watched_tasks.head != NULL)
|
||||
{
|
||||
/* Search for the node */
|
||||
|
||||
for (node = watched_tasks.head; node != NULL; node = node->next)
|
||||
{
|
||||
if (node->task_id == id)
|
||||
{
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void task_mn_add_to_list(pid_t id)
|
||||
{
|
||||
struct task_node_s *node;
|
||||
|
||||
/* Alloc the node */
|
||||
|
||||
node = malloc(sizeof(struct task_node_s));
|
||||
if (node == NULL)
|
||||
{
|
||||
fprintf(stderr, "watcher daemon: Couldn't alloc a node to list\n");
|
||||
return;
|
||||
}
|
||||
|
||||
node->task_id = id;
|
||||
|
||||
/* NOTE: Once a task is subscribed, its initial status is that it fed the
|
||||
* dog. This approach was used first to avoid a false-positive result,
|
||||
* e.g., the task has been subscribed immediately before the watchdog
|
||||
* expiration and it did not feed the dog within this interval,
|
||||
* so the wdt handler would be triggered even if the subscribed
|
||||
* task would feed the dog in time.
|
||||
* The second reason is that we can consider the subscription request
|
||||
* itself an advertisement that the watched task is alive and not stuck.
|
||||
*/
|
||||
|
||||
node->reset = true;
|
||||
node->next = NULL;
|
||||
|
||||
/* If list is not empty */
|
||||
|
||||
if (watched_tasks.head != NULL)
|
||||
{
|
||||
watched_tasks.tail->next = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
watched_tasks.head = node;
|
||||
}
|
||||
|
||||
watched_tasks.tail = node;
|
||||
}
|
||||
|
||||
void task_mn_remove_from_list(pid_t id)
|
||||
{
|
||||
struct task_node_s *prev;
|
||||
struct task_node_s *current;
|
||||
|
||||
/* If list is empty */
|
||||
|
||||
if (watched_tasks.head == NULL)
|
||||
{
|
||||
fprintf(stderr, "watcher daemon: List is empty\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* First element */
|
||||
|
||||
else if (watched_tasks.head->task_id == id)
|
||||
{
|
||||
if (watched_tasks.head == watched_tasks.tail)
|
||||
{
|
||||
free(watched_tasks.head);
|
||||
watched_tasks.head = NULL;
|
||||
watched_tasks.tail = NULL;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = watched_tasks.head;
|
||||
watched_tasks.head = prev->next;
|
||||
free(prev);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Search the node */
|
||||
|
||||
prev = watched_tasks.head;
|
||||
current = prev->next;
|
||||
while (current != NULL)
|
||||
{
|
||||
if (current->task_id == id)
|
||||
{
|
||||
prev->next = current->next;
|
||||
|
||||
/* In case the one that will be removed is the tail */
|
||||
|
||||
if (prev->next == NULL)
|
||||
{
|
||||
watched_tasks.tail = prev;
|
||||
}
|
||||
|
||||
free(current);
|
||||
return;
|
||||
}
|
||||
|
||||
prev = prev->next;
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "watcher daemon: This node is not in the list.\n");
|
||||
}
|
||||
|
||||
void task_mn_get_task_name(struct noteram_get_taskname_s *task)
|
||||
{
|
||||
int notefd;
|
||||
|
||||
notefd = open("/dev/note", O_RDONLY);
|
||||
if (notefd < 0)
|
||||
{
|
||||
fprintf(stderr, "trace: cannot open /dev/note\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ioctl(notefd, NOTERAM_GETTASKNAME, (unsigned long)task);
|
||||
close(notefd);
|
||||
}
|
||||
|
||||
void task_mn_subscribe(pid_t id)
|
||||
{
|
||||
struct noteram_get_taskname_s task;
|
||||
|
||||
/* Verify if the task exists in the list */
|
||||
|
||||
if (task_mn_is_task_subscribed(id) != NULL)
|
||||
{
|
||||
task.pid = id;
|
||||
task_mn_get_task_name(&task);
|
||||
printf("Task %s was already subscribed\n", task.taskname);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If it doesn't, include it to the list */
|
||||
|
||||
task_mn_add_to_list(id);
|
||||
}
|
||||
}
|
||||
|
||||
void task_mn_unsubscribe(pid_t id)
|
||||
{
|
||||
struct noteram_get_taskname_s task;
|
||||
|
||||
/* Verify if the task exists in the list */
|
||||
|
||||
if (task_mn_is_task_subscribed(id) != NULL)
|
||||
{
|
||||
/* If it does, remove it from the list */
|
||||
|
||||
task_mn_remove_from_list(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
task.pid = id;
|
||||
task_mn_get_task_name(&task);
|
||||
printf("Task %s is not subscribed\n", task.taskname);
|
||||
}
|
||||
}
|
||||
|
||||
bool task_mn_all_tasks_fed(void)
|
||||
{
|
||||
struct task_node_s *node;
|
||||
|
||||
for (node = watched_tasks.head; node != NULL; node = node->next)
|
||||
{
|
||||
/* If at least one did not feed the dog, return false */
|
||||
|
||||
if (node->reset == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
79
examples/watcher/task_mn.h
Normal file
79
examples/watcher/task_mn.h
Normal file
@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
* examples/watcher/task_mn.h
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __EXAMPLES_WATCHER_TASK_MN_H
|
||||
#define __EXAMPLES_WATCHER_TASK_MN_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/note/noteram_driver.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
struct request_s
|
||||
{
|
||||
pid_t task_id;
|
||||
int code;
|
||||
};
|
||||
|
||||
struct task_node_s
|
||||
{
|
||||
pid_t task_id;
|
||||
bool reset;
|
||||
struct task_node_s *next;
|
||||
};
|
||||
|
||||
struct task_list_s
|
||||
{
|
||||
struct task_node_s *head;
|
||||
struct task_node_s *tail;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
extern volatile struct request_s request;
|
||||
extern struct task_list_s watched_tasks;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
void task_mn_print_tasks_status(void);
|
||||
void task_mn_reset_all(void);
|
||||
struct task_node_s *task_mn_is_task_subscribed(pid_t id);
|
||||
void task_mn_add_to_list(pid_t id);
|
||||
void task_mn_remove_from_list(pid_t id);
|
||||
void task_mn_get_task_name(struct noteram_get_taskname_s *task);
|
||||
void task_mn_subscribe(pid_t id);
|
||||
void task_mn_unsubscribe(pid_t id);
|
||||
bool task_mn_all_tasks_fed(void);
|
||||
|
||||
#endif /* __EXAMPLES_WATCHER_TASK_MN_H */
|
234
examples/watcher/watcher_main.c
Normal file
234
examples/watcher/watcher_main.c
Normal file
@ -0,0 +1,234 @@
|
||||
/****************************************************************************
|
||||
* examples/watcher/watcher_main.c
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <sched.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "ramdisk.h"
|
||||
#include "wdt.h"
|
||||
#include "task_mn.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define SUBSCRIBE_CMD 1
|
||||
#define UNSUSBCRIBE_CMD -1
|
||||
#define FEED_CMD 2
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const char g_info_file_name[] = "/mnt/watcher/info.txt";
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void feed_sighandler(int signo, FAR siginfo_t * siginfo,
|
||||
FAR void *context)
|
||||
{
|
||||
struct task_node_s *node;
|
||||
request = *(struct request_s *)siginfo->si_value.sival_ptr;
|
||||
|
||||
switch (request.code)
|
||||
{
|
||||
case FEED_CMD:
|
||||
|
||||
/* Update the current requester task status */
|
||||
|
||||
node = task_mn_is_task_subscribed(request.task_id);
|
||||
if (node != NULL)
|
||||
{
|
||||
node->reset = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,
|
||||
"watcher daemon: task is not subscribed to feed dog.\n");
|
||||
}
|
||||
|
||||
/* Verify if all tasks requested to feed the dog */
|
||||
|
||||
if (task_mn_all_tasks_fed())
|
||||
{
|
||||
/* If all tasks required, reset it and reset all tasks' status" */
|
||||
|
||||
wdt_feed_the_dog();
|
||||
task_mn_reset_all();
|
||||
}
|
||||
|
||||
break;
|
||||
case SUBSCRIBE_CMD:
|
||||
|
||||
/* Include the current requester task to the watched tasks list */
|
||||
|
||||
task_mn_subscribe(request.task_id);
|
||||
break;
|
||||
case UNSUSBCRIBE_CMD:
|
||||
|
||||
/* Excludes the current requester task from the watched tasks list */
|
||||
|
||||
task_mn_unsubscribe(request.task_id);
|
||||
|
||||
/* Verify if all tasks has already requested to feed the dog in this
|
||||
* round. Because maybe the watcher was only expecting the task that
|
||||
* was unsubscribed to finally reset the dog.
|
||||
* If this task is no longer being watched and the others have already
|
||||
* sent a feed request, so it's time to feed the dog.
|
||||
*/
|
||||
|
||||
if (task_mn_all_tasks_fed())
|
||||
{
|
||||
/* If all tasks required, reset it and reset all tasks' status" */
|
||||
|
||||
wdt_feed_the_dog();
|
||||
task_mn_reset_all();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "watcher daemon: Invalid command\n");
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: watcher_daemon
|
||||
****************************************************************************/
|
||||
|
||||
static int watcher_daemon(int argc, FAR char *argv[])
|
||||
{
|
||||
int ret;
|
||||
struct sigaction act;
|
||||
pid_t watcher_pid;
|
||||
FILE *fp;
|
||||
|
||||
printf("Watcher Daemon has started!\n");
|
||||
|
||||
/* Configuring a signal action */
|
||||
|
||||
act.sa_sigaction = feed_sighandler; /* The handler to be triggered when
|
||||
* receiving a signal */
|
||||
act.sa_flags = SA_SIGINFO; /* Invoke the signal-catching function */
|
||||
sigfillset(&act.sa_mask);
|
||||
sigdelset(&act.sa_mask, CONFIG_EXAMPLES_WATCHER_SIGNAL); /* Block all
|
||||
* other
|
||||
* signals less
|
||||
* this one */
|
||||
|
||||
ret = sigaction(CONFIG_EXAMPLES_WATCHER_SIGNAL, &act, NULL);
|
||||
if (ret != OK)
|
||||
{
|
||||
int errcode = errno;
|
||||
fprintf(stderr, "ERROR: sigaction failed: %d\n", errcode);
|
||||
ret = errcode;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Collecting the necessary information of the current task */
|
||||
|
||||
watcher_pid = getpid();
|
||||
|
||||
/* Writing PID, SIGNAL NUMBER, and COMMANDS' value to a file */
|
||||
|
||||
fp = fopen(g_info_file_name, "w+");
|
||||
if (fp == NULL)
|
||||
{
|
||||
int errcode = errno;
|
||||
fprintf(stderr, "ERROR: Failed to open %s: %d\n",
|
||||
g_info_file_name, errcode);
|
||||
ret = errcode;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
fprintf(fp, "%d %d %d %d %d\n", (int)watcher_pid,
|
||||
(int)CONFIG_EXAMPLES_WATCHER_SIGNAL, (int)SUBSCRIBE_CMD,
|
||||
(int)FEED_CMD, (int)UNSUSBCRIBE_CMD);
|
||||
fclose(fp);
|
||||
|
||||
/* Suspends the calling thread until delivery of a non-blocked signal. */
|
||||
|
||||
while (1)
|
||||
{
|
||||
pause();
|
||||
}
|
||||
|
||||
errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* watcher_main
|
||||
****************************************************************************/
|
||||
|
||||
int main(int argc, FAR char *argv[])
|
||||
{
|
||||
int ret;
|
||||
FILE *fp;
|
||||
|
||||
/* Check if the watcher has already been initialized */
|
||||
|
||||
fp = fopen(g_info_file_name, "r");
|
||||
if (fp)
|
||||
{
|
||||
fclose(fp);
|
||||
printf("Watcher is already running.\n");
|
||||
ret = EBUSY;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Create a RAMDISK device, format it and mount it */
|
||||
|
||||
prepare_fs();
|
||||
|
||||
/* Initialize and configure the wdt */
|
||||
|
||||
wdt_init();
|
||||
|
||||
/* Start Daemon */
|
||||
|
||||
ret = task_create("watcher_daemon", CONFIG_EXAMPLES_WATCHER_PRIORITY,
|
||||
CONFIG_EXAMPLES_WATCHER_STACKSIZE, watcher_daemon, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
printf("watcher_main: ERROR: Failed to start watcher_daemon: %d\n",
|
||||
errcode);
|
||||
ret = errcode;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
errout:
|
||||
return ret;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
162
examples/watcher/wdt.c
Normal file
162
examples/watcher/wdt.c
Normal file
@ -0,0 +1,162 @@
|
||||
/****************************************************************************
|
||||
* examples/watcher/wdt.c
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/boardctl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "wdt.h"
|
||||
#include "task_mn.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Definitions
|
||||
****************************************************************************/
|
||||
|
||||
static int wdt_print_handler(int irq, FAR void *context, FAR void *arg);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct wdog_params_s wdog =
|
||||
{.timeout = CONFIG_EXAMPLES_WATCHER_TIMEOUT,
|
||||
.handlers.oldhandler = NULL,
|
||||
.handlers.newhandler = wdt_print_handler
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: wdt_print_handler
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int wdt_print_handler(int irq, FAR void *context, FAR void *arg)
|
||||
{
|
||||
if (watched_tasks.head != NULL)
|
||||
{
|
||||
printf("*** Printing Tasks Status ***\n");
|
||||
task_mn_print_tasks_status();
|
||||
task_mn_reset_all();
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
int wdt_init(void)
|
||||
{
|
||||
int fd;
|
||||
int ret;
|
||||
strcpy(wdog.devname, CONFIG_EXAMPLES_WATCHER_DEVPATH);
|
||||
|
||||
/* Open the watchdog device for reading */
|
||||
|
||||
fd = open(wdog.devname, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
printf("wdt_init: open %s failed: %d\n", wdog.devname, errcode);
|
||||
ret = errcode;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Set the watchdog timeout */
|
||||
|
||||
ret = ioctl(fd, WDIOC_SETTIMEOUT, (unsigned long)wdog.timeout);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
printf("wdt_init: ioctl(WDIOC_SETTIMEOUT) failed: %d\n", errcode);
|
||||
ret = errcode;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Register the expiration callback to be triggered on timeout */
|
||||
|
||||
ret =
|
||||
ioctl(fd, WDIOC_CAPTURE, (unsigned long)((uintptr_t) & (wdog.handlers)));
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
printf("wdt_init: ioctl(WDIOC_CAPTURE) failed: %d\n", errcode);
|
||||
ret = errcode;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Then start the watchdog timer. */
|
||||
|
||||
ret = ioctl(fd, WDIOC_START, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
int errcode = errno;
|
||||
printf("wdt_init: ioctl(WDIOC_START) failed: %d\n", errcode);
|
||||
ret = errcode;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void wdt_feed_the_dog(void)
|
||||
{
|
||||
int fd;
|
||||
int ret;
|
||||
|
||||
fd = open(wdog.devname, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
fprintf(stderr, "trace: cannot open %s\n", wdog.devname);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = ioctl(fd, WDIOC_KEEPALIVE, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("watcher: ioctl(WDIOC_KEEPALIVE) failed: %d\n", ret);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
59
examples/watcher/wdt.h
Normal file
59
examples/watcher/wdt.h
Normal file
@ -0,0 +1,59 @@
|
||||
/****************************************************************************
|
||||
* examples/watcher/wdt.h
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __EXAMPLES_WATCHER_WDT_H
|
||||
#define __EXAMPLES_WATCHER_WDT_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/timers/watchdog.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define DEVNAME_SIZE 16
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
struct wdog_params_s
|
||||
{
|
||||
uint32_t timeout;
|
||||
char devname[DEVNAME_SIZE];
|
||||
struct watchdog_capture_s handlers;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
int wdt_init(void);
|
||||
void wdt_feed_the_dog(void);
|
||||
|
||||
#endif /* __EXAMPLES_WATCHER_WDT_H */
|
Loading…
x
Reference in New Issue
Block a user