Start user app by invoking .rbf file (via added ioctl on usbdev)

This commit is contained in:
Michal Moskal 2017-07-27 14:31:23 +01:00
parent 34db42b469
commit b16f659ea1
4 changed files with 74 additions and 73 deletions

View File

@ -5,6 +5,6 @@ cd /mnt/ramdisk/prjs/ko
#echo 3 > /proc/sys/kernel/printk #echo 3 > /proc/sys/kernel/printk
insmod ./nbd.ko insmod ./nbd.ko
sleep 1 sleep 1
./uf2d > /tmp/uf2d.log 2> /tmp/uf2derr.log ./uf2d /dev/nbd1 > /tmp/uf2d.log 2> /tmp/uf2derr.log
sleep 1 sleep 1
insmod ./d_usbdev.ko file=/dev/nbd0 HostStr=EV3 SerialStr=0016535543af insmod ./d_usbdev.ko file=/dev/nbd1 HostStr=EV3 SerialStr=0016535543af

View File

@ -543,12 +543,27 @@ static int Device1Mmap(struct file *filp, struct vm_area_struct *vma)
return (ret); return (ret);
} }
#define FEED_DATA _IOC(_IOC_WRITE, 't', 108, 1024)
static int Device1Ioctl(struct inode *pNode, struct file *File, unsigned int Request, unsigned long Pointer)
{
if (Request != FEED_DATA)
return -EINVAL;
copy_from_user(usb_char_buffer_out,(void*)Pointer,1024);
usb_char_out_length = 1024;
return 0;
}
static const struct file_operations Device1Entries = static const struct file_operations Device1Entries =
{ {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.read = Device1Read, .read = Device1Read,
.write = Device1Write, .write = Device1Write,
.mmap = Device1Mmap .mmap = Device1Mmap,
.ioctl = Device1Ioctl
}; };

View File

@ -19,6 +19,8 @@
#include <time.h> #include <time.h>
#include <signal.h> #include <signal.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/ioctl.h>
#include <string.h>
#define max(a, b) \ #define max(a, b) \
({ \ ({ \
@ -627,6 +629,48 @@ void read_block(uint32_t block_no, uint8_t *data) {
} }
} }
char rbfPath[300];
uint8_t stopApp[] = {
0x05, 0x00, // size
0x00, 0x00, // seq. no.
0x3f, 0x3d, // usb magic,
0x02, // req. no.
};
uint8_t runStart[] = {0x00, 0x00, // size
0x00, 0x00, // seq. no.
0x00, 0x00, 0x08, // something
0xC0, 0x08, 0x82, 0x01, 0x00, 0x84};
uint8_t runEnd[] = {0x00, 0x60, 0x64, 0x03, 0x01, 0x60, 0x64, 0x00};
#define FEED_DATA _IOC(_IOC_WRITE, 't', 108, 1024)
void startRbf() {
char buf[1024];
memset(buf, 0, sizeof(buf));
memcpy(buf, stopApp, sizeof(stopApp));
int fd = open("/dev/lms_usbdev", O_RDWR);
ioctl(fd, FEED_DATA, buf);
usleep(500000);
int off = 0;
memcpy(buf + off, runStart, sizeof(runStart));
off += sizeof(runStart);
strcpy(buf + off, rbfPath);
off += strlen(rbfPath);
memcpy(buf + off, runEnd, sizeof(runEnd));
off += sizeof(runEnd);
off -= 2;
buf[0] = off & 0xff;
buf[1] = off >> 8;
ioctl(fd, FEED_DATA, buf);
close(fd);
}
#define MAX_BLOCKS 8000 #define MAX_BLOCKS 8000
typedef struct { typedef struct {
uint32_t numBlocks; uint32_t numBlocks;
@ -634,73 +678,11 @@ typedef struct {
uint8_t writtenMask[MAX_BLOCKS / 8 + 1]; uint8_t writtenMask[MAX_BLOCKS / 8 + 1];
} WriteState; } WriteState;
char elfPath[300];
int lmsPid;
void stopLMS() {
struct dirent *ent;
DIR *dir;
dir = opendir("/proc");
if (dir == NULL)
return;
while ((ent = readdir(dir)) != NULL) {
int pid = atoi(ent->d_name);
if (!pid)
continue;
char namebuf[100];
snprintf(namebuf, 1000, "/proc/%d/cmdline", pid);
FILE *f = fopen(namebuf, "r");
if (f) {
fread(namebuf, 1, 99, f);
if (strcmp(namebuf, "./lms2012") == 0) {
lmsPid = pid;
}
fclose(f);
if (lmsPid)
break;
}
}
closedir(dir);
if (lmsPid) {
DBG("SIGSTOP to lmsPID=%d", lmsPid);
kill(lmsPid, SIGSTOP);
} else {
DBG("LMS not found");
}
}
void waitAndContinue() {
stopLMS();
for (int fd = 3; fd < 9999; ++fd)
close(fd);
pid_t child = fork();
if (child == 0) {
DBG("start %s", elfPath);
execl(elfPath, elfPath, "--msd", (char *)NULL);
exit(128);
}
int status;
waitpid(child, &status, 0);
DBG("re-start LMS");
if (lmsPid) {
kill(lmsPid, SIGCONT);
}
exit(0);
}
void restartProgram() { void restartProgram() {
if (!elfPath[0]) if (!rbfPath[0])
exit(0); exit(0);
startRbf();
pid_t child = fork(); exit(0); // causes parent to eject MSD etc
if (child == 0)
waitAndContinue();
else
exit(0); // causes parent to eject MSD etc
} }
int numWrites = 0; int numWrites = 0;
@ -765,8 +747,8 @@ void write_block(uint32_t block_no, uint8_t *data) {
write(fd, bl->data, bl->payloadSize); write(fd, bl->data, bl->payloadSize);
close(fd); close(fd);
if (strlen(fn) > 4 && !strcmp(fn + strlen(fn) - 4, ".elf")) { if (strlen(fn) > 4 && !strcmp(fn + strlen(fn) - 4, ".rbf")) {
strcpy(elfPath, fn); strcpy(rbfPath, fn);
} }
} }
} }

View File

@ -20,6 +20,9 @@
#include "uf2.h" #include "uf2.h"
const char *dev_file = "/dev/nbd0";
#define NUM_BLOCKS NUM_FAT_BLOCKS #define NUM_BLOCKS NUM_FAT_BLOCKS
uint64_t ntohll(uint64_t a) { uint64_t ntohll(uint64_t a) {
@ -96,8 +99,6 @@ void startclient() {
exit(0); exit(0);
} }
#define dev_file "/dev/nbd0"
void handleread(int off, int len) { void handleread(int off, int len) {
uint8_t buf[512]; uint8_t buf[512];
LOG("read @%d len=%d", off, len); LOG("read @%d len=%d", off, len);
@ -196,11 +197,14 @@ void enableMSD(int enabled) {
#endif #endif
} }
int main() { int main(int argc, char **argv) {
#ifndef X86 #ifndef X86
daemon(0, 1); daemon(0, 1);
#endif #endif
if (argc > 1)
dev_file = argv[1];
for (;;) { for (;;) {
pid_t child = fork(); pid_t child = fork();
if (child == 0) { if (child == 0) {