Skip to content

Commit

Permalink
Optimize Microbit abort framework to better abort upload operations
Browse files Browse the repository at this point in the history
  • Loading branch information
zhengyangliu committed Mar 31, 2023
1 parent 3241561 commit 342690c
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 13 deletions.
1 change: 1 addition & 0 deletions src/session/serialport.js
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ class SerialportSession extends Session {
this.tool = new Microbit(this.peripheral.path, config, this.userDataPath,
this.toolsPath, this.sendstd.bind(this), this.sendRemoteRequest.bind(this));
try {
this.sendRemoteRequest('setUploadAbortEnabled', true);
await this.disconnect();
const exitCode = await this.tool.flash(code, library);
await this.connect(this.peripheralParams, true);
Expand Down
51 changes: 38 additions & 13 deletions src/upload/microbit.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ const os = require('os');

const FLASH_TIME = 25 * 1000; // 20s

const ABORT_STATE_CHECK_INTERVAL = 100;

const UFLASH_MODULE_NAME = 'uflash';
const MICROFS_MODULE_NAME = 'microfs';

Expand Down Expand Up @@ -62,28 +64,30 @@ class Microbit {

const ufsTestExitCode = await this.ufsTestFirmware();
if (ufsTestExitCode === 'Failed') {
if (this._abort === true) {
return Promise.resolve('Aborted');
}

this._sendstd(`${ansi.yellow_dark}Could not enter raw REPL.\n`);
this._sendstd(`${ansi.clear}Try to flash micropython for microbit firmware to fix.\n`);
await this.uflash();
}

if (this._abort === true) {
return Promise.resolve('Aborted');
}

this._sendstd('Writing files...\n');

this._sendRemoteRequest('setUploadAbortEnabled', true);
for (const file of fileToPut) {
if (this._abort === true) {
return Promise.resolve('Aborted');
}
const ufsPutExitCode = await this.ufsPut(file);
if (ufsPutExitCode !== 'Success') {
if (ufsPutExitCode !== 'Success' && ufsPutExitCode !== 'Aborted') {
return Promise.reject(ufsPutExitCode);
}
if (this._abort === true) {
break;
}
}

if (this._abort === true) {
return Promise.resolve('Aborted');
}
this._sendstd(`${ansi.green_dark}Success\n`);
return Promise.resolve('Success');
}
Expand All @@ -94,13 +98,23 @@ class Microbit {
return new Promise(resolve => {
const ufs = spawn(this._pyPath, ['-m', MICROFS_MODULE_NAME, 'ls']);

ufs.stdout.on('data', buf => {
if (buf.toString().indexOf('Could not enter raw REPL.') !== -1){
const listenAbortSignal = setInterval(() => {
if (this._abort) {
ufs.kill();
}
}, ABORT_STATE_CHECK_INTERVAL);

ufs.on('exit', outCode => {
clearInterval(listenAbortSignal);
switch (outCode) {
case null:
return resolve('Aborted');
case 0:
return resolve('Success');
case 1: // Could not enter raw REPL.
return resolve('Failed');
}
});

ufs.on('exit', () => resolve('Success'));
});
}

Expand All @@ -113,8 +127,17 @@ class Microbit {
return resolve('Failed');
});

const listenAbortSignal = setInterval(() => {
if (this._abort) {
ufs.kill();
}
}, ABORT_STATE_CHECK_INTERVAL);

ufs.on('exit', outCode => {
clearInterval(listenAbortSignal);
switch (outCode) {
case null:
return resolve('Aborted');
case 0:
this._sendstd(`${file} write finish\n`);
return resolve('Success');
Expand All @@ -127,6 +150,8 @@ class Microbit {

uflash () {
return new Promise((resolve, reject) => {
// For some unknown reason, uflash cannot be killed in the test, so the termination button is disabled
// when uflash is running.
this._sendRemoteRequest('setUploadAbortEnabled', false);

const uflash = spawn(this._pyPath, ['-m', UFLASH_MODULE_NAME]);
Expand Down

0 comments on commit 342690c

Please sign in to comment.