I am trying to make a sensor that runs on Contiki OS to execute a new binary and replace the current one, if an event occurs.
I am using Cooja simulator and sky note and I uploaded the binary into the coffee file system of the node(using cooja script) and I want to execute the hello-world.ce
To compile my current program(reboot.c) that i will dynamicaly load a module from I used the following commands:
make TARGET=sky clean CLEAN=symbols.?
make reboot.sky TARGET=sky
make CORE=reboot.sky TARGET=sky reboot.sky
And for the hello-world that will be loaded I used:
make TARGET=sky hello-world.ce
Here is part of my code (reboot.c) from where i am trying to execute hello-world
#include "contiki.h"
#include "core/loader/elfloader.h"
#include "cfs/cfs.h"
PROCESS(hello_world_process, "Reboot process");
AUTOSTART_PROCESSES(&hello_world_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(hello_world_process, ev, data)
{
PROCESS_BEGIN();
int i;
int binFile,ret;
elfloader_init();
binFile=cfs_open("hello-world.ce",CFS_READ);
printf("cfs_open:%d\n",binFile); //returns 0 so the file is opened
ret=elfloader_load(binFile);
cfs_close(binFile);
printf("loader returned: %d\n",ret); //returns 0 ->meaning everything is ok
if(ret == ELFLOADER_OK){
printf("elf OK\n");
for(i=0; elfloader_autostart_processes[i] != NULL; i++) {
printf("exec: starting process %s. \n", elfloader_autostart_processes[i]->name);
}
autostart_start(elfloader_autostart_processes);
}
printf("end of rebooting program\n”);
PROCESS_END();
}
It seems that the elfloader_autostart_processes is set to null since the print statement is not executed in the for loop. The program continues and prints "end of rebooting program" and I was expecting it to print hello-world as an indicator that the binary has been loaded and started.
Can you provide any help?
I manage to achieve it using another build in library of Contiki. Specifically I used shell-exec.c that is responsible to execute files and I gave it as an argument the file that I wanted to be executed on run-time. I used a Cooja script to upload the file on the sensor in Cooja simulator.
#include "contiki.h"
#include "shell-exec.c"
#include "serial-shell.h"
#include "cfs/cfs.h"
#include <stdio.h> /* For printf() */
/*---------------------------------------------------------------------------*/
PROCESS(rebooting, "Reboot process");
AUTOSTART_PROCESSES(&rebooting);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(rebooting, ev, data)
{
PROCESS_BEGIN();
static struct etimer et;
/* Allow some time for the file to upload using cooja. */
etimer_set(&et, 10 * CLOCK_SECOND);
PROCESS_WAIT_UNTIL(etimer_expired(&et));
process_start(&shell_exec_process,"hello-world.ce\0");
PROCESS_END();
}
Cooja Script
WAIT_UNTIL(msg.startsWith('Starting'));
log.log("Mote started\n");
mymote = mote; /* store mote reference */
fs = mote.getFilesystem();
DIR="~/hello-world"; /* Directory that the binary is stored in the host machine running cooja */
mote_file=DIR+ "hello-world.ce";
ret=fs.insertFile(mote_file);
log.log("inserted");
Related
I have created my own event loop in Tcl as below. When i run the below code using tclsh interactively, CPU Utilization is close to 0% and when i run the same run using bsub, CPU Utilization shoots up to 100%.
I have even tried making read call blocking using below and that doesn't help too.
int flag = fcntl(0, F_GETFL);
flag = flag & (~O_NONBLOCK);
(void) fcntl(0, F_SETFL, (long)flag);
What is the reason here and how do i solve this problem?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <tcl.h>
#include <errno.h>
#include <fcntl.h>
void fwStdinKeyHandler(ClientData clientData, int mask)
{
unsigned char c = 0;
int rc = read(STDIN_FILENO, &c, 1);
//printf("rc is : %d\n",rc);
while (rc < 1 && errno == EINTR) {}
}
static void MainLoop(void)
{
Tcl_CreateFileHandler(STDIN_FILENO, TCL_READABLE, fwStdinKeyHandler, NULL);
while (1) {
Tcl_DoOneEvent(0);
}
fprintf(stdout,"Exit MainLoop\n");
fflush(stdout);
}
static int Hello_Cmd(ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
Tcl_SetMainLoop(MainLoop);
return TCL_OK;
}
/*
* Hello_Init -- Called when Tcl loads your extension.
*/
int DLLEXPORT Cmd_Init(Tcl_Interp *interp)
{
if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) {
return TCL_ERROR;
}
/* changed this to check for an error - GPS */
if (Tcl_PkgProvide(interp, "Hello", "1.0") == TCL_ERROR) {
return TCL_ERROR;
}
Tcl_CreateObjCommand(interp, "doone_loop", Hello_Cmd, NULL, NULL);
return TCL_OK;
}
How to make?
1. File saved in,say, hello.c
2. gcc -fpic -c hello.c -I/usr/local/include
3. gcc -shared hello.o -o libcmd.so
How to run?
runme file contains:
load libcmd.so
doone_loop
/usr/bin/tclsh runme => CPU Utilization close to 0%
bsub -q interactive -m "/usr/bin/tclsh runme" => CPU Utilization close to 100%
I think the problem is that when the command is run inside (the system that) bsub (talks to), it is run non-interactively. In particular, stdin is probably coming from either a file or /dev/null, both of which are always readable to the notifier (which is a tamed version of a bunch of low level system calls). That means your code is called back into a lot, almost as if it is busy-looping, generating a lot of CPU usage.
Since this is an operating system level behaviour, your approach simply won't work. You'll need to detect if you are in this situation (perhaps with isatty()?) and not install the event handler if it won't work right.
For non-interactive shell, there is no terminal and hence, no stdin channel, so read call returns zero. So, we need to add below code in fwStdinkeyhandler after read returns 0.
if(rc==0) {
Tcl_DeleteFileHandler(0);
}
The galactic imperium plans to send a star destroyer to attack the rebel‘s base. This star destroyer shall host 1024 imperial clone warriors.
At t=0 there is just one soldier availabe: the captain. From his first birthday on, a clone warrior is able to clone once a year. The imperator wants to get the star destroyer ready for action in short time.
The imperial command structure is very simple:
Every warrior sends commands to his clones
there is no communication to the superior
Write a Linux C-Programm with the following requirements:
Every clone warrior has to be represented by a separate process
Commands have to be transmitted via uniquely (!) named message queues
*There is an existing message queue /Imperator from the Imperator to the captain
After the cloning phase, every clone warrior has to wait for commands to receive and to transmit to his inferiors
Hints and requirements:
Consider, how many soldiers are available in which year: t=0 –just the captain, t=1 –captain and his first clone, etc.
Don‘t worry about error handling
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <mqueue.h>
#include <errno.h>
// Exercise „clone warriors“
#define NUM 10
#define SIZE_MSGBUF 500
#define MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH |S_IWOTH)
mqd_t QueueArray[NUM]; // queues to my clones
void cleanQueueArray(void) { // support function for init: start with no queues
for (int i=0; i<NUM; i++) QueueArray[i] = 0;
}
int main(void) {
char cNameBossQueue[100] = "/Imperator"; // boss queue‘s default name
mqd_t BossQueue; // boss queue to receive commands of the father‘s process
struct mq_attr attr;
attr.mq_maxmsg = 10;
attr.mq_msgsize = SIZE_MSGBUF;
attr.mq_flags = 0;
int nPrio=0;
char cMsgbuf[SIZE_MSGBUF+1] = "";
cleanQueueArray(); // init: no queues to any clones at the beginning
// phase 1 / clone phase takes NUM years:
for (int i=0; i<NUM; i++) {
pid_t npid_child = fork();
if (npid_child > 0) { // Father. Create + store command channel to clone:
char cQueue[100];
sprintf(cQueue, "/Queue%d", npid_child);
QueueArray[i] = mq_open(cQueue, O_CREAT|O_WRONLY, MODE, &attr);
} else { // Child. Remember the name of the boss queue:
sprintf(cNameBossQueue, "/Queue%d", getpid());
cleanQueueArray(); // Child has no queues to clones currently
}
}
// Phase 2 / battle phase. Receive and transmit orders:
BossQueue = mq_open(cNameBossQueue, O_RDONLY, MODE, &attr);
mq_receive(BossQueue, cMsgbuf, SIZE_MSGBUF, &nPrio);
// Send orders to all of my clones:
for (int i=0; i<NUM; i++) {
if (QueueArray[i] > 0) {
mq_send (QueueArray[i], cMsgbuf, strlen(cMsgbuf), 0);
}
}
// Cleanup work...
return 0;
}
I tried running this using
gcc -o Wall clonew clonew.c -lrt"
./clonew
but I get no output
Your commandline (without the trailing ", which I consider a posting accident)
gcc -o Wall clonew clonew.c -lrt
means
compile clonew and clonew.c
into an executable named "Wall"
using the rt lib
I am not sure why the use of "clonew" (first in the compile command, later in the execution attempt) does not trigger any warning.
Clearly you intend to create and execute that file. But it is used as input file and should, even if it exists but is not a C syntax file, cause some complaint.
However, the reason why you do not get the expected output when trying to execute clonew is that your compile command cannot have resulted in the creation of an executable clonew.
Why the attempt to execute something, which either does not exist yet or is a C code file, does not result in any warnings, errors or any other output is a mystery.
If it already exists as an executable but silent program, it should also trigger a complaint.
I have a embedded device running Linux Angstrom. I need to detect a USB drive. So when a USB drive is inserted, I need to automatically copy data from the USB to internal memory of the embedded device.
To detect the USB, I am using below code:
DIR* dir = opendir("/media/sda1/");
if (dir)
{
printf("USB detected\n");
//rest of the code
//to copy data from the USB
}
This works normally but sometimes after copying is done, I remove the USB but the name of the mount point (sda1) remains there. So after removing the USB, it again try to copy the data (because sda1 is there in media) and then shows error because physical no USB is connected. What is the best way to detect if USB is connected and if connected then after copying how to eject it properly. Here I cannot use udisks because its not available for the linux angstrom I am using for this embedded device. So only generic linux commands will work.
Any help. Thanks
One naive approach is the following:
execute mount | grep /dev/sda1
parse the output: if there is no output, that means that sda1 is not mounted
You may have to adapt the code to your specific platform.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
/* launch a command and gets its output */
FILE *f = popen("mount | grep /dev/sda1", "r");
if (NULL != f)
{
/* test if something has been outputed by
the command */
if (EOF == fgetc(f))
{
puts("/dev/sda1 is NOT mounted");
}
else
{
puts("/dev/sda1 is mounted");
}
/* close the command file */
pclose(f);
}
return 0;
}
Hi I have a class assignment that requires me to intercept an open call then read the file and edit the output without editing the file itself this is all done in a loadable module in the kernel space. When I say editing I mean like changing the word she to _he replacing the s with an underscore it changes every instance of the word she to _he well that's the desired result. I have looked online for days trying to figure this out I thought I found a suitable example but it kept giving me an error. As soon as I enter the module into the kernel it instantly says killed then it says I cannot remove it because it is in use when it isn't this forces me to restart my virtual machine. Below is the code. Any help would be appreciated thank you.
#include <linux/module.h> // Needed by all modules
#include <linux/kernel.h> // Needed for KERN_INFO
#include <linux/fs.h> // Needed by filp
#include <asm/uaccess.h> // Needed by segment descriptors
int init_module(void)
{
// Create variables
struct file *f;
char buf[128];
mm_segment_t fs;
int i;
// Init the buffer with 0
for(i=0;i<128;i++)
buf[i] = 0;
// To see in /var/log/messages that the module is operating
printk(KERN_INFO "My module is loaded\n");
// I am using Fedora and for the test I have chosen following file
// Obviously it is much smaller than the 128 bytes, but hell with it =)
f = filp_open("/etc/fedora-release", O_RDONLY, 0);
if(f == NULL)
printk(KERN_ALERT "filp_open error!!.\n");
else{
// Get current segment descriptor
fs = get_fs();
// Set segment descriptor associated to kernel space
set_fs(get_ds());
// Read the file
f->f_op->read(f, buf, 128, &f->f_pos);
// Restore segment descriptor
set_fs(fs);
// See what we read from file
printk(KERN_INFO "buf:%s\n",buf);
}
filp_close(f,NULL);
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO "My module is unloaded\n");
}
module_init(init_module);
module_exit(cleanup_module);
Regarding reading and writing to a file from the kernel, I would suggest that you will read the following article and look into the code snippests in it:
Driving Me Nuts - Things You Never Should Do in the Kernel
Linux Journal 2005, Greg Kroah-Hartman
http://m.linuxjournal.com/article/8110
I do not understand the meaning of the function "process_poll(&serial_line_process); " which is used in core/dev/serial-line.c file of Contiki OS. i've read on the wiki pages that it sets the needspoll variable in the process control block enabling the kernel to poll this process when an interrupt occurs. If someone could shed light on how and when this process gets called, i would be highly obliged.
I came across this problem while trying to read serial input using contiki specific mechanism as explained on the wiki pages. The characters are read from the serial port and I verified that program control reached process_poll( &serial_line_process) ; statement in function int serial_line_input_byte(unsigned char c); in file serial-line.c. This has been set as a callback for the serial input drivers for the platform. But after that nothing happened. It seems that the process serial_input_process initially executed PROCESS_YIELD(); statement and hasn't been called since then. The following is the code for the process i used for testing.
#include "contiki.h"
#include "dev/serial-line.h"
#include <stdio.h>
PROCESS(test_serial, "Serial line test process");
AUTOSTART_PROCESSES(&test_serial);
PROCESS_THREAD(test_serial, ev, data)
{
PROCESS_BEGIN();
for(;;) {
PROCESS_YIELD();
if(ev == serial_line_event_message) {
printf("received line: %s\n", (char *)data);
}
}
PROCESS_END();
}
A process_poll() will invoke your pollhandler, eg
PROCESS_POLLHANDLER(pollhandler());
The process will be sent the PROCESS_EVENT_POLL event, so if you prefer you can wait for it like this:
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_POLL);
Maneesh, the problem is not with process_poll function. After struggling for weeks with this problem, I found that the problem is that process_init needs to be called before serial_line_init function in main(). Otherwise the serial_line_process will not be added in the process_list and calling process_poll will be useless.