Compare commits

..

1 Commits

19 changed files with 128 additions and 576 deletions

View File

@ -11,9 +11,8 @@ they are derived from GPLv2 code).
* the `d_usbdev` uses the composite framework to register an additional mass storage function in addtion
to the pre-existing custom USB HID function
* the `g_mass_storage` module has the following changes:
* a bug fixed, where page-misaligned writes would hang
* additional `/sys/.../lun0/active` entry is added, which allows for signaling drive eject to the host
* `d_usbdev` has an additional `ioctl()` to pretend data came from the USB host - this can be used to direct
the VM to do stuff
### Kernel modifications

View File

@ -1,10 +1,9 @@
#!/bin/sh
set -ex
echo Y > /sys/module/printk/parameters/time
cd /mnt/ramdisk/prjs/ko
#echo 3 > /proc/sys/kernel/printk
echo 3 > /proc/sys/kernel/printk
insmod ./nbd.ko
sleep 1
./uf2d /dev/nbd1 > /tmp/uf2d.log 2> /tmp/uf2derr.log
./uf2d > /tmp/uf2d.log 2> /tmp/uf2derr.log
sleep 1
insmod ./d_usbdev.ko file=/dev/nbd1 HostStr=EV3 SerialStr=0016535543af
insmod ./d_usbdev.ko file=/dev/nbd0 HostStr=EV3 SerialStr=0016535543af

View File

@ -38,13 +38,6 @@
// Keep Eclipse happy
#endif
#if 1
#undef dev_vdbg
#undef dev_dbg
#define dev_vdbg(d, args...) printk(args)
#define dev_dbg(d, args...) printk(args)
#endif
/* big enough to hold our biggest descriptor */
#define USB_BUFSIZ 1024
@ -874,12 +867,6 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
req->length = USB_BUFSIZ;
gadget->ep0->driver_data = cdev;
VDBG(cdev,
"setup req %02x.%02x v%04x i%04x l%d\n",
ctrl->bRequestType, ctrl->bRequest,
w_value, w_index, w_length);
switch (ctrl->bRequest) {
/* we handle all standard USB descriptors */
case USB_REQ_GET_DESCRIPTOR:

View File

@ -40,8 +40,8 @@
#include <asm/types.h>
#endif
#include "source/lms2012.h"
#include "source/am1808.h"
#include "../../lms2012/source/lms2012.h"
#include "../../lms2012/source/am1808.h"
#define MODULE_NAME "usbdev_module"
@ -80,15 +80,12 @@ static void ModuleExit(void);
#include <linux/utsname.h>
#include <linux/device.h>
static struct fsg_common *fsg_common;
#include "computil.c" // The composite framework used as utility file
#include <../drivers/usb/gadget/gadget_chips.h>
#include <../drivers/usb/gadget/usbstring.c>
#include <../drivers/usb/gadget/config.c>
#include <../drivers/usb/gadget/epautoconf.c>
#include "f_mass_storage.c"
/*-------------------------------------------------------------------------*/
@ -173,10 +170,9 @@ static struct usb_device_descriptor device_desc = {
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = 0xEF,
.bDeviceSubClass = 2,
.bDeviceProtocol = 1,
.bDeviceClass = 0,
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
/*.bMaxPacketSize0 = f(hardware) */
.idVendor = cpu_to_le16(DRIVER_VENDOR_NUM),
.idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM),
@ -334,9 +330,6 @@ static void zero_resume(struct usb_composite_dev *cdev)
/*-------------------------------------------------------------------------*/
static int msg_bind(struct usb_composite_dev *cdev);
static void msg_bind2(struct usb_composite_dev *cdev);
static int zero_bind(struct usb_composite_dev *cdev)
{
int gcnum;
@ -369,10 +362,6 @@ static int zero_bind(struct usb_composite_dev *cdev)
strings_dev[STRING_SERIAL_IDX].id = id;
device_desc.iSerialNumber = id;
id = msg_bind(cdev);
if (id < 0)
return id;
setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev);
rudolf_add(cdev, autoresume != 0);
@ -392,9 +381,6 @@ static int zero_bind(struct usb_composite_dev *cdev)
longname, gadget->name);
device_desc.bcdDevice = cpu_to_le16(0x9999);
}
msg_bind2(cdev);
return 0;
}
@ -543,27 +529,12 @@ static int Device1Mmap(struct file *filp, struct vm_area_struct *vma)
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 =
{
.owner = THIS_MODULE,
.read = Device1Read,
.write = Device1Write,
.mmap = Device1Mmap,
.ioctl = Device1Ioctl
.mmap = Device1Mmap
};
@ -725,38 +696,3 @@ static void ModuleExit(void)
}
// MSG
/****************************** Configurations ******************************/
static struct fsg_module_parameters fsg_mod_data = {
.stall = 1
};
FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
/****************************** Gadget Bind ******************************/
static void msg_bind2(struct usb_composite_dev *cdev)
{
fsg_common_put(fsg_common);
}
static int msg_bind(struct usb_composite_dev *cdev)
{
/* set up mass storage function */
fsg_common = fsg_common_from_params(0, cdev, &fsg_mod_data);
if (IS_ERR(fsg_common)) {
return PTR_ERR(fsg_common);
}
return 0;
}
static int msg_config(struct usb_configuration *c) {
return fsg_add(c->cdev, c, fsg_common);
}

View File

@ -705,9 +705,7 @@ static int do_read(struct fsg_common *common)
u32 amount_left;
loff_t file_offset, file_offset_tmp;
unsigned int amount;
// partial_page handling causes hangs
// same thing in do_write() --mmoskal
//unsigned int partial_page;
unsigned int partial_page;
ssize_t nread;
/* Get the starting Logical Block Address and check that it's
@ -733,9 +731,6 @@ static int do_read(struct fsg_common *common)
/* Carry out the file reads */
amount_left = common->data_size_from_cmnd;
LDBG(curlun, "Uread off=%d cnt=%d\n", (int)lba, amount_left);
if (unlikely(amount_left == 0))
return -EIO; /* No default reply */
@ -752,12 +747,11 @@ static int do_read(struct fsg_common *common)
amount = min(amount_left, FSG_BUFLEN);
amount = min((loff_t) amount,
curlun->file_length - file_offset);
/*
partial_page = file_offset & (PAGE_CACHE_SIZE - 1);
if (partial_page > 0)
amount = min(amount, (unsigned int) PAGE_CACHE_SIZE -
partial_page);
*/
/* Wait for the next buffer to become available */
bh = common->next_buffhd_to_fill;
while (bh->state != BUF_STATE_EMPTY) {
@ -840,7 +834,7 @@ static int do_write(struct fsg_common *common)
u32 amount_left_to_req, amount_left_to_write;
loff_t usb_offset, file_offset, file_offset_tmp;
unsigned int amount;
//unsigned int partial_page;
unsigned int partial_page;
ssize_t nwritten;
int rc;
@ -849,7 +843,7 @@ static int do_write(struct fsg_common *common)
return -EINVAL;
}
spin_lock(&curlun->filp->f_lock);
curlun->filp->f_flags |= O_SYNC; /* Default is to wait */
curlun->filp->f_flags &= ~O_SYNC; /* Default is not to wait */
spin_unlock(&curlun->filp->f_lock);
/* Get the starting Logical Block Address and check that it's
@ -884,8 +878,6 @@ static int do_write(struct fsg_common *common)
amount_left_to_req = common->data_size_from_cmnd;
amount_left_to_write = common->data_size_from_cmnd;
LDBG(curlun, "Uwrite off=%d cnt=%d\n", (int)lba, amount_left_to_req);
while (amount_left_to_write > 0) {
/* Queue a request for more data from the host */
@ -904,12 +896,10 @@ static int do_write(struct fsg_common *common)
amount = min(amount_left_to_req, FSG_BUFLEN);
amount = min((loff_t) amount, curlun->file_length -
usb_offset);
/*
partial_page = usb_offset & (PAGE_CACHE_SIZE - 1);
if (partial_page > 0)
amount = min(amount,
(unsigned int) PAGE_CACHE_SIZE - partial_page);
*/
if (amount == 0) {
get_some_more = 0;
@ -2410,28 +2400,7 @@ static void fsg_disable(struct usb_function *f)
fsg->common->prev_fsg = fsg->common->fsg;
fsg->common->fsg = fsg;
fsg->common->new_config = 0;
DBG(common, "fsg_disable filp=%p\n", fsg->common->luns[0].filp);
raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE_DISABLE);
}
static void shutdown_server(void) {
DBG(fsg_common, "shutdown_server filp=%p\n", fsg_common->luns[0].filp);
if (fsg_common->luns[0].filp) {
uint32_t buf[512 / 4];
loff_t file_offset_tmp = 512 * 50000; // make sure we're outside of FS area
int i;
// this should shut down the nbd server, so that the caches are flushed
memset(buf, 0, sizeof(buf));
buf[0] = 0x20da6d81;
buf[1] = 0x747e09d4;
fsg_common->luns[0].filp->f_flags |= O_SYNC;
for (i = 0; i < 2; ++i)
vfs_write(fsg_common->luns[0].filp,
(char*)buf, 512, &file_offset_tmp);
}
raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
}
@ -2553,9 +2522,6 @@ static void handle_exception(struct fsg_common *common)
/* SS_RESET_OCCURRED; */
break;
case FSG_STATE_CONFIG_CHANGE_DISABLE:
shutdown_server();
// fall-through
case FSG_STATE_CONFIG_CHANGE:
rc = do_set_config(common, new_config);
if (common->ep0_req_tag != exception_req_tag)
@ -2663,41 +2629,6 @@ static int fsg_main_thread(void *common_)
static DEVICE_ATTR(ro, 0644, fsg_show_ro, fsg_store_ro);
static DEVICE_ATTR(file, 0644, fsg_show_file, fsg_store_file);
static struct fsg_dev *_fsg;
static int isActive(void) {
return _fsg->function.config->cdev->deactivations == 0 ? 1 : 0;
}
static ssize_t fsg_show_active(struct device *dev, struct device_attribute *attr,
char *buf)
{
return sprintf(buf, "%d\n", isActive());
}
static ssize_t fsg_store_active(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int i;
if (sscanf(buf, "%d", &i) != 1)
return -EINVAL;
if (isActive() != i) {
if (i == 0) {
usb_function_deactivate(&_fsg->function);
} else if (i == 1) {
usb_function_activate(&_fsg->function);
} else {
return -EINVAL;
}
}
return count;
}
static DEVICE_ATTR(active, 0644, fsg_show_active, fsg_store_active);
/****************************** FSG COMMON ******************************/
@ -2804,10 +2735,6 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
if (rc)
goto error_luns;
rc = device_create_file(&curlun->dev, &dev_attr_active);
if (rc)
goto error_luns;
if (lcfg->filename) {
rc = fsg_lun_open(curlun, lcfg->filename);
if (rc)
@ -3039,7 +2966,6 @@ static int fsg_add(struct usb_composite_dev *cdev,
int rc;
fsg = kzalloc(sizeof *fsg, GFP_KERNEL);
_fsg = fsg;
if (unlikely(!fsg))
return -ENOMEM;

View File

@ -334,7 +334,6 @@ enum fsg_state {
FSG_STATE_ABORT_BULK_OUT,
FSG_STATE_RESET,
FSG_STATE_INTERFACE_CHANGE,
FSG_STATE_CONFIG_CHANGE_DISABLE,
FSG_STATE_CONFIG_CHANGE,
FSG_STATE_DISCONNECT,
FSG_STATE_EXIT,

View File

@ -551,8 +551,6 @@ static void f_rudolf_disable(struct usb_function *f)
/*-------------------------------------------------------------------------*/
static int msg_config(struct usb_configuration *c);
static int rudolf_bind_config(struct usb_configuration *c)
{
struct f_rudolf *rudolf;
@ -570,18 +568,8 @@ static int rudolf_bind_config(struct usb_configuration *c)
rudolf->function.disable = f_rudolf_disable;
status = usb_add_function(c, &rudolf->function);
if (status) {
if (status)
kfree(rudolf);
return status;
}
status = msg_config(c);
if (status) {
kfree(rudolf);
return status;
}
return status;
}

View File

@ -1,14 +0,0 @@
# Patched EV3 image
The file `ev3-fs.patch` summarizes the changes done to the original V1.09D image.
You can see some text files are edited, the `d_usbdev.ko` is updated (sources in `../kernel`),
`uf2d` added (sources in `../uf2daemon`), and a stock `nbd.ko` module is added.
Additionally, the `edimax01.ko` is replaced by now much more popular `rtl8192cu.ko` (also stock).
The init script has a hook for running a shell script from `/mnt/ramdisk/`. This can be used
for testing different modules etc.
The kernel command line has been modified to:
* disable DMA for the MUSB driver - otherwise the mass storage device is very unstable
* increase the size of dmesg buffer to 128k

View File

@ -1,53 +0,0 @@
diff -ur orig-ev3/etc/init.d/ev3init.sh dev-ev3/etc/init.d/ev3init.sh
--- orig-ev3/etc/init.d/ev3init.sh 1970-01-01 01:00:00.000000000 +0100
+++ dev-ev3/etc/init.d/ev3init.sh 2017-07-27 12:19:43.195041798 +0100
@@ -1,5 +1,7 @@
#!/bin/sh
+echo Y > /sys/module/printk/parameters/time
+
bluetoothd -n > /dev/null 2>&1 &
echo "Setting up VirtualDrive...";
@@ -60,3 +62,6 @@
sleep 2
hciattach /dev/ttyS2 texas 2000000 "flow" "nosleep" $STRING
sdptool add SP
+
+insmod /lib/modules/2.6.33-rc4/kernel/drivers/net/wireless/rtl8192cu.ko
+. /mnt/ramdisk/rc.local || :
Only in orig-ev3/home/root/lms2012/sys: exit~
diff -ur orig-ev3/home/root/lms2012/sys/init dev-ev3/home/root/lms2012/sys/init
--- orig-ev3/home/root/lms2012/sys/init 1970-01-01 01:00:00.000000000 +0100
+++ dev-ev3/home/root/lms2012/sys/init 2017-07-27 12:23:43.072605126 +0100
@@ -5,13 +5,15 @@
var=$(printf 'HostStr=%s SerialStr=%s' $(cat /home/root/lms2012/sys/settings/BrickName) $(cat /home/root/lms2012/sys/settings/BTser))
echo $var > /home/root/lms2012/sys/settings/UsbInfo.dat
+insmod ${PWD}/mod/nbd.ko
+${PWD}/uf2d
insmod ${PWD}/mod/d_iic.ko `cat /home/root/lms2012/sys/settings/HwId`
insmod ${PWD}/mod/d_uart.ko `cat /home/root/lms2012/sys/settings/HwId`
insmod ${PWD}/mod/d_power.ko `cat /home/root/lms2012/sys/settings/HwId`
insmod ${PWD}/mod/d_pwm.ko `cat /home/root/lms2012/sys/settings/HwId`
insmod ${PWD}/mod/d_ui.ko `cat /home/root/lms2012/sys/settings/HwId`
insmod ${PWD}/mod/d_analog.ko `cat /home/root/lms2012/sys/settings/HwId`
-insmod ${PWD}/mod/d_usbdev.ko `cat /home/root/lms2012/sys/settings/UsbInfo.dat`
+insmod ${PWD}/mod/d_usbdev.ko `cat /home/root/lms2012/sys/settings/UsbInfo.dat` file=/dev/nbd0
insmod ${PWD}/mod/d_usbhost.ko
insmod ${PWD}/mod/d_sound.ko `cat /home/root/lms2012/sys/settings/HwId`
insmod ${PWD}/mod/d_bt.ko `cat /home/root/lms2012/sys/settings/HwId`
@@ -29,6 +31,8 @@
chmod 666 /dev/lms_iic
chmod 666 /dev/lms_bt
+echo 4 > /proc/sys/kernel/printk
+
cd ..
ls -R > /dev/null
cd sys
Binary files orig-ev3/home/root/lms2012/sys/mod/d_usbdev.ko and dev-ev3/home/root/lms2012/sys/mod/d_usbdev.ko differ
Only in dev-ev3/home/root/lms2012/sys/mod: nbd.ko
Only in dev-ev3/home/root/lms2012/sys: uf2d
Only in orig-ev3/lib/modules/2.6.33-rc4/kernel/drivers/net/wireless: edimax01.ko
Only in dev-ev3/lib/modules/2.6.33-rc4/kernel/drivers/net/wireless: rtl8192cu.ko

View File

@ -1,36 +1,14 @@
#!/bin/sh
let fs = require("fs")
// we try to use shorter versions of all parameters for the additional parameters to fit
let bootargs = "mem=${memsize} initrd=${filesysaddr},${filesyssize} root=/dev/ram0 rw rootfstype=cramfs console=${console} ip=${ipaddr} lpj=747520 quiet"
let bootnews = "mem=64M initrd=0xC1180000,10M root=1:0 rw rootfstype=cramfs console=${console} lpj=747520 musb_hdrc.use_dma=0 log_buf_len=128k quiet"
let piggy = true
function build() {
if (bootnews.length > bootargs.length) {
console.log("args too long")
return
}
while (bootnews.length < bootargs.length)
bootnews += " "
let cr = fs.readFileSync("cram.bin")
if (cr.length > 10485760) {
console.log("too big by " + (cr.length - 10485760))
if (cr.length > 10878976) {
console.log("too big")
return
}
let img = fs.readFileSync("EV3 Firmware V1.09D.bin")
for (let i = 0; i < bootnews.length; ++i) {
if (img[0x21DDA + i] != bootargs.charCodeAt(i)) {
console.log("boot args mismatch")
return
}
img[0x21DDA + i] = bootnews.charCodeAt(i)
}
let img = fs.readFileSync("boot.bin")
let off = 0x250000
if (img[off] != 0x45 || img[off + 1] != 0x3d) {
console.log("bad magic: " + img[off] + " / " + img[off+1])
@ -39,8 +17,8 @@ function build() {
cr.copy(img, off)
let kern = fs.readFileSync(piggy ? "piggy-patched.gzip" : "linux/arch/arm/boot/uImage")
off = piggy ? 0x0005540f : 0x00050000
let kern = fs.readFileSync("piggy-patched.gzip")
off = 0x0005540f
if (img[off] != kern[0] || img[off+1] != kern[1]) {
console.log("bad kernel magic: " + img[off] + " / " + img[off+1])

View File

@ -1,9 +1,4 @@
#!/bin/sh
# dd if=EV3\ Firmware\ V1.09D.bin of=orig.cram bs=65536 skip=37 count=400
sudo cp linux/pxt/uf2daemon/server dev-ev3/home/root/lms2012/sys/uf2d
sudo cp linux/pxt/kernel/d_usbdev.ko dev-ev3/home/root/lms2012/sys/mod/d_usbdev.ko
sudo chown -R root:root dev-ev3/home/root/lms2012
sudo mkfs.cramfs dev-ev3 cram.bin
node img
ls -l firmware.bin

View File

@ -6,5 +6,4 @@ ev3duder up bin/nbd.ko ../prjs/ko/nbd.ko
ev3duder up ins ../prjs/ko/ins
ev3duder exec 'rm ../prjs/ko/uf2d'
ev3duder up bin/uf2d ../prjs/ko/uf2d
#ev3duder exec 'echo . /mnt/ramdisk/prjs/ko/ins > /mnt/ramdisk/rc.local'

View File

@ -19,9 +19,6 @@
#include <time.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <string.h>
#include <errno.h>
#define max(a, b) \
({ \
@ -39,7 +36,7 @@
#include "uf2.h"
#define DBG LOG
#define DBG printf
typedef struct {
uint8_t JumpInstruction[3];
@ -335,7 +332,8 @@ void addClusterData(ClusterData *c, FsEntry *e) {
c->myfile = e;
DBG("add cluster: flags=%d size=%d numcl=%d", c->flags, (int)c->st.st_size, c->numclusters);
DBG("add cluster: flags=%d size=%d numcl=%d name=%s\n", c->flags, (int)c->st.st_size,
c->numclusters, c->name);
}
FsEntry *addRootText(const char *filename, const char *contents) {
@ -395,7 +393,7 @@ void setFatNames(FsEntry *dirent) {
}
}
DBG("setname: %s [%s] cl=%s @ %d sz=%d dents=%d", p->vfatname, p->fatname,
DBG("setname: %s [%s] cl=%s @ %d sz=%d dents=%d\n", p->vfatname, p->fatname,
p->data ? p->data->name : "(no data)", p->startCluster, p->size, p->numdirentries);
}
}
@ -530,7 +528,7 @@ void readDirData(uint8_t *dest, FsEntry *dirdata, int blkno) {
if (idx >= 16)
break;
// DBG("dir idx=%d %s", idx, e->vfatname);
// DBG("dir idx=%d %s\n", idx, e->vfatname);
for (int i = 0; i < e->numdirentries; ++i, ++idx) {
if (0 <= idx && idx < 16) {
@ -564,15 +562,15 @@ void readDirData(uint8_t *dest, FsEntry *dirdata, int blkno) {
}
void readBlock(uint8_t *dest, int blkno) {
// DBG("readbl %d", blkno);
// DBG("readbl %d\n", blkno);
int blkno0 = blkno;
for (ClusterData *c = firstCluster; c; c = c->cnext) {
// DBG("off=%d sz=%d", blkno, c->numclusters);
// DBG("off=%d sz=%d\n", blkno, c->numclusters);
if (blkno >= c->numclusters) {
blkno -= c->numclusters;
continue;
}
// DBG("readbl off=%d %p", blkno, c);
// DBG("readbl off=%d %p\n", blkno, c);
if (c->dirdata) {
readDirData(dest, c->dirdata, blkno);
} else if (c->flags & F_TEXT) {
@ -594,7 +592,6 @@ void readBlock(uint8_t *dest, int blkno) {
if (fd >= 0) {
lseek(fd, bl->targetAddr, SEEK_SET);
bl->payloadSize = read(fd, bl->data, 256);
close(fd);
} else {
bl->payloadSize = -1;
}
@ -630,48 +627,6 @@ 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
typedef struct {
uint32_t numBlocks;
@ -679,30 +634,80 @@ typedef struct {
uint8_t writtenMask[MAX_BLOCKS / 8 + 1];
} WriteState;
void restartProgram() {
if (!rbfPath[0])
exit(0);
startRbf();
exit(0); // causes parent to eject MSD etc
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\n", lmsPid);
kill(lmsPid, SIGSTOP);
} else {
DBG("LMS not found\n");
}
}
void waitAndContinue() {
stopLMS();
for (int fd = 3; fd < 9999; ++fd)
close(fd);
pid_t child = fork();
if (child == 0) {
DBG("start %s\n", elfPath);
execl(elfPath, elfPath, "--msd", (char*) NULL);
exit(128);
}
int status;
waitpid(child, &status, 0);
DBG("re-start LMS\n");
if (lmsPid)
kill(lmsPid, SIGCONT);
exit(0);
}
void restartProgram() {
if (!elfPath[0])
exit(0);
pid_t child = fork();
if (child == 0)
waitAndContinue();
else
exit(0); // causes parent to eject MSD etc
}
int numWrites = 0;
static WriteState wrState;
void write_block(uint32_t block_no, uint8_t *data) {
WriteState *state = &wrState;
UF2_Block *bl = (void *)data;
if (bl->magicStart0 == 0x20da6d81 && bl->magicStart1 == 0x747e09d4) {
DBG("restart req, #wr=%d", numWrites);
if (numWrites) {
exit(0);
}
return;
}
numWrites++;
if (!is_uf2_block(bl)) {
return;
}
@ -741,19 +746,15 @@ void write_block(uint32_t block_no, uint8_t *data) {
*p = '/';
int fd = open(fn, O_WRONLY | O_CREAT, 0777);
if (fd < 0 && errno == ETXTBSY) {
unlink(fn);
fd = open(fn, O_WRONLY | O_CREAT, 0777);
}
if (fd >= 0) {
ftruncate(fd, bl->fileSize);
lseek(fd, bl->targetAddr, SEEK_SET);
// DBG("write %d bytes at %d to %s", bl->payloadSize, bl->targetAddr, fn);
// DBG("write %d bytes at %d to %s\n", bl->payloadSize, bl->targetAddr, fn);
write(fd, bl->data, bl->payloadSize);
close(fd);
if (strlen(fn) > 4 && !strcmp(fn + strlen(fn) - 4, ".rbf")) {
strcpy(rbfPath, fn);
if (strlen(fn) > 4 && !strcmp(fn + strlen(fn) - 4, ".elf")) {
strcpy(elfPath, fn);
}
}
}
@ -772,7 +773,6 @@ void write_block(uint32_t block_no, uint8_t *data) {
// logval("incr", state->numWritten);
state->writtenMask[pos] |= mask;
state->numWritten++;
DBG("write %d/%d #%d", state->numWritten, state->numBlocks, bl->blockNo);
}
if (state->numWritten >= state->numBlocks) {
restartProgram();

View File

@ -16,48 +16,27 @@
#include <sys/stat.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdarg.h>
#include "uf2.h"
const char *dev_file = "/dev/nbd0";
#define NUM_BLOCKS NUM_FAT_BLOCKS
uint64_t ntohll(uint64_t a) {
return ((uint64_t)ntohl(a & 0xffffffff) << 32) | ntohl(a >> 32);
}
#define FAIL(args...) \
do { \
fprintf(stderr, args); \
fprintf(stderr, "\n"); \
exit(1); \
} while (0)
#define LOG(args...) \
do { \
fprintf(stderr, args); \
fprintf(stderr, "\n"); \
} while (0)
uint64_t ntohll(uint64_t a) { return ((uint64_t)ntohl(a & 0xffffffff) << 32) | ntohl(a >> 32); }
#define htonll ntohll
void mylog(const char *fmt, ...) {
va_list args;
char *p, *p2;
va_start(args, fmt);
vasprintf(&p, fmt, args);
vprintf(fmt, args);
va_end(args);
if (p[0] != '<')
asprintf(&p2, "<6>%s\n", p);
else
asprintf(&p2, "%s\n", p);
int len = strlen(p2);
#ifdef X86
write(2, p2, len);
#else
int fd = open("/dev/kmsg", O_WRONLY);
write(fd, p2, len);
close(fd);
#endif
free(p);
free(p2);
}
void readAll(int fd, void *dst, uint32_t length) {
while (length) {
int curr = read(fd, dst, length);
@ -99,10 +78,13 @@ void startclient() {
exit(0);
}
#define dev_file "/dev/nbd0"
void handleread(int off, int len) {
uint8_t buf[512];
LOG("read @%d len=%d", off, len);
reply.error = 0; // htonl(EPERM);
// fprintf(stderr, "read @%d len=%d\n", off, len);
// htonl(EPERM);
reply.error = 0;
writeAll(sock, &reply, sizeof(struct nbd_reply));
for (int i = 0; i < len; ++i) {
read_block(off + i, buf);
@ -112,7 +94,7 @@ void handleread(int off, int len) {
void handlewrite(int off, int len) {
uint8_t buf[512];
LOG("write @%d len=%d", off, len);
// fprintf(stderr, "write @%d len=%d\n", off, len);
for (int i = 0; i < len; ++i) {
readAll(sock, buf, 512);
write_block(off + i, buf);
@ -151,7 +133,7 @@ void runNBD() {
reply.error = htonl(0);
for (;;) {
// nbd_ioctl(BLKFLSBUF, 0); // flush buffers - we don't want the kernel to cache the writes
nbd_ioctl(BLKFLSBUF, 0); // flush buffers - we don't want the kernel to cache the writes
int nread = read(sock, &request, sizeof(request));
if (nread < 0) {
@ -197,14 +179,11 @@ void enableMSD(int enabled) {
#endif
}
int main(int argc, char **argv) {
int main() {
#ifndef X86
daemon(0, 1);
#endif
if (argc > 1)
dev_file = argv[1];
for (;;) {
pid_t child = fork();
if (child == 0) {

View File

@ -25,7 +25,8 @@ void write_block(uint32_t block_no, uint8_t *data);
#define CONCAT_1(a, b) a##b
#define CONCAT_0(a, b) CONCAT_1(a, b)
#define STATIC_ASSERT(e) enum { CONCAT_0(_static_assert_, __LINE__) = 1 / ((e) ? 1 : 0) }
#define STATIC_ASSERT(e) \
enum { CONCAT_0(_static_assert_, __LINE__) = 1 / ((e) ? 1 : 0) }
extern const char infoUf2File[];
@ -33,14 +34,4 @@ void readAll(int fd, void *dst, uint32_t length);
STATIC_ASSERT(sizeof(UF2_Block) == 512);
void mylog(const char *fmt, ...);
#define FAIL(args...) \
do { \
mylog("<4>" args); \
exit(1); \
} while (0)
#define LOG mylog
#endif

View File

@ -41,8 +41,7 @@ namespace pxt.editor {
export function deployCoreAsync(resp: pxtc.CompileResult, isCli = false) {
let w: Ev3Wrapper
let filename = resp.downloadFileBaseName || "pxt"
filename = filename.replace(/^lego-/, "")
let filename = resp.downloadFileBaseName
let fspath = "../prjs/BrkProg_SAVE/"

View File

@ -30,5 +30,7 @@
Object = 4,
Function = 5,
}
declare namespace serial {
}
// Auto-generated. Do not edit. Really.

158
libs/base/shims.d.ts vendored
View File

@ -1,158 +0,0 @@
// Auto-generated. Do not edit.
//% indexerGet=BufferMethods::getByte indexerSet=BufferMethods::setByte
declare interface Buffer {
/**
* Write a number in specified format in the buffer.
*/
//% shim=BufferMethods::setNumber
setNumber(format: NumberFormat, offset: int32, value: number): void;
/**
* Read a number in specified format from the buffer.
*/
//% shim=BufferMethods::getNumber
getNumber(format: NumberFormat, offset: int32): number;
/** Returns the length of a Buffer object. */
//% property shim=BufferMethods::length
length: int32;
/**
* Fill (a fragment) of the buffer with given value.
*/
//% offset.defl=0 length.defl=-1 shim=BufferMethods::fill
fill(value: int32, offset?: int32, length?: int32): void;
/**
* Return a copy of a fragment of a buffer.
*/
//% offset.defl=0 length.defl=-1 shim=BufferMethods::slice
slice(offset?: int32, length?: int32): Buffer;
/**
* Shift buffer left in place, with zero padding.
* @param offset number of bytes to shift; use negative value to shift right
* @param start start offset in buffer. Default is 0.
* @param length number of elements in buffer. If negative, length is set as the buffer length minus
* start. eg: -1
*/
//% start.defl=0 length.defl=-1 shim=BufferMethods::shift
shift(offset: int32, start?: int32, length?: int32): void;
/**
* Convert a buffer to its hexadecimal representation.
*/
//% shim=BufferMethods::toHex
toHex(): string;
/**
* Rotate buffer left in place.
* @param offset number of bytes to shift; use negative value to shift right
* @param start start offset in buffer. Default is 0.
* @param length number of elements in buffer. If negative, length is set as the buffer length minus
* start. eg: -1
*/
//% start.defl=0 length.defl=-1 shim=BufferMethods::rotate
rotate(offset: int32, start?: int32, length?: int32): void;
/**
* Write contents of `src` at `dstOffset` in current buffer.
*/
//% shim=BufferMethods::write
write(dstOffset: int32, src: Buffer): void;
}
declare namespace loops {
/**
* Repeats the code forever in the background. On each iteration, allows other codes to run.
* @param body code to execute
*/
//% help=loops/forever weight=100 blockGap=8
//% blockId=forever block="forever" blockAllowMultiple=1 shim=loops::forever
function forever(a: () => void): void;
/**
* Pause for the specified time in milliseconds
* @param ms how long to pause for, eg: 100, 200, 500, 1000, 2000
*/
//% help=loops/pause weight=99
//% async block="pause (ms) %pause"
//% blockId=device_pause shim=loops::pause
function pause(ms: int32): void;
}
declare namespace control {
/**
* Gets the number of milliseconds elapsed since power on.
*/
//% help=control/millis weight=50
//% blockId=control_running_time block="millis (ms)" shim=control::millis
function millis(): int32;
/**
* Run code when a registered event happens.
* @param id the event compoent id
* @param value the event value to match
*/
//% weight=20 blockGap=8 blockId="control_on_event" block="on event|from %src|with value %value"
//% blockExternalInputs=1
//% help="control/on-event" shim=control::onEvent
function onEvent(src: int32, value: int32, handler: () => void): void;
/**
* Reset the device.
*/
//% weight=30 async help=control/reset blockGap=8
//% blockId="control_reset" block="reset" shim=control::reset
function reset(): void;
/**
* Block the current fiber for the given microseconds
* @param micros number of micro-seconds to wait. eg: 4
*/
//% help=control/wait-micros weight=29 async
//% blockId="control_wait_us" block="wait (µs)%micros" shim=control::waitMicros
function waitMicros(micros: int32): void;
/**
* Run other code in the background.
*/
//% help=control/run-in-background blockAllowMultiple=1
//% blockId="control_run_in_background" block="run in background" blockGap=8 shim=control::runInBackground
function runInBackground(a: () => void): void;
/**
* Blocks the calling thread until the specified event is raised.
*/
//% help=control/wait-for-event async
//% blockId=control_wait_for_event block="wait for event|from %src|with value %value" shim=control::waitForEvent
function waitForEvent(src: int32, value: int32): void;
/**
* Derive a unique, consistent serial number of this device from internal data.
*/
//% blockId="control_device_serial_number" block="device serial number" weight=9 shim=control::deviceSerialNumber
function deviceSerialNumber(): int32;
}
declare namespace serial {
/**
* Write some text to the serial port.
*/
//% help=serial/write-string
//% weight=87
//% blockId=serial_writestring block="serial|write string %text" shim=serial::writeString
function writeString(text: string): void;
/**
* Send a buffer across the serial connection.
*/
//% help=serial/write-buffer advanced=true weight=6
//% blockId=serial_writebuffer block="serial|write buffer %buffer" shim=serial::writeBuffer
function writeBuffer(buffer: Buffer): void;
}
// Auto-generated. Do not edit. Really.

View File

@ -1,6 +1,6 @@
{
"name": "pxt-ev3",
"version": "0.0.1",
"version": "0.0.0",
"description": "LEGO Mindstorms EV3 for Microsoft MakeCode",
"private": true,
"keywords": [
@ -39,8 +39,8 @@
"semantic-ui-less": "^2.2.4"
},
"dependencies": {
"pxt-common-packages": "0.9.1",
"pxt-core": "1.8.10"
"pxt-common-packages": "0.8.1",
"pxt-core": "1.7.4"
},
"scripts": {
"test": "node node_modules/pxt-core/built/pxt.js travis"