GETFILE/UPLOAD don't handle pre-emption

This commit is contained in:
Michal Moskal 2017-07-07 13:41:21 +01:00
parent 5af3cc4345
commit ce3fe646fd
2 changed files with 28 additions and 14 deletions

View File

@ -41,9 +41,8 @@ namespace pxt.editor {
return initAsync() return initAsync()
.then(w_ => { .then(w_ => {
w = w_ w = w_
// run LS to make sure we can talk to device first if (w.isStreaming)
// otherwise flashing a file might lock it U.userError("please stop the program first")
return w.lsAsync("/")
}).then(() => { }).then(() => {
let f = U.stringToUint8Array(atob(resp.outfiles[pxt.outputName()])) let f = U.stringToUint8Array(atob(resp.outfiles[pxt.outputName()]))
return w.flashAsync(elfPath, f) return w.flashAsync(elfPath, f)

View File

@ -18,6 +18,7 @@ namespace pxt.editor {
msgs = new U.PromiseBuffer<Uint8Array>() msgs = new U.PromiseBuffer<Uint8Array>()
private cmdSeq = U.randomUint32() & 0xffff; private cmdSeq = U.randomUint32() & 0xffff;
private lock = new U.PromiseQueue(); private lock = new U.PromiseQueue();
isStreaming = false;
constructor(public io: pxt.HF2.PacketIO) { constructor(public io: pxt.HF2.PacketIO) {
io.onData = buf => { io.onData = buf => {
@ -90,11 +91,12 @@ namespace pxt.editor {
let begin = this.allocSystem(4 + path.length + 1, 0x92) let begin = this.allocSystem(4 + path.length + 1, 0x92)
HF2.write32(begin, 6, file.length) // fileSize HF2.write32(begin, 6, file.length) // fileSize
U.memcpy(begin, 10, U.stringToUint8Array(path)) U.memcpy(begin, 10, U.stringToUint8Array(path))
return this.talkAsync(begin) return this.lock.enqueue("file", () =>
.then(resp => { this.talkAsync(begin)
handle = resp[7] .then(resp => {
return loopAsync(0) handle = resp[7]
}) return loopAsync(0)
}))
} }
lsAsync(path: string): Promise<DirEntry[]> { lsAsync(path: string): Promise<DirEntry[]> {
@ -129,23 +131,26 @@ namespace pxt.editor {
.then(resp => { }) .then(resp => { })
} }
streamFileAsync(path: string, cb: (d: Uint8Array) => void) { private streamFileOnceAsync(path: string, cb: (d: Uint8Array) => void) {
let fileSize = 0 let fileSize = 0
let filePtr = 0 let filePtr = 0
let handle = -1 let handle = -1
let restart = () => Promise.delay(500).then(() => this.streamFileAsync(path, cb))
let resp = (buf: Uint8Array): Promise<void> => { let resp = (buf: Uint8Array): Promise<void> => {
if (buf[6] == 2) { if (buf[6] == 2) {
// handle not ready - file is missing // handle not ready - file is missing
return restart() this.isStreaming = false
return Promise.resolve()
} }
if (buf[6] != 0 && buf[6] != 8) if (buf[6] != 0 && buf[6] != 8)
U.userError("bad response when streaming file: " + buf[6]) U.userError("bad response when streaming file: " + buf[6] + " " + U.toHex(buf))
this.isStreaming = true
fileSize = HF2.read32(buf, 7) fileSize = HF2.read32(buf, 7)
if (handle == -1) if (handle == -1) {
handle = buf[11] handle = buf[11]
log(`stream on, handle=${handle}`)
}
let data = buf.slice(12) let data = buf.slice(12)
filePtr += data.length filePtr += data.length
if (data.length > 0) if (data.length > 0)
@ -153,7 +158,8 @@ namespace pxt.editor {
if (buf[6] == 8) { if (buf[6] == 8) {
// end of file // end of file
return this.rmAsync(path).then(restart) this.isStreaming = false
return this.rmAsync(path)
} }
let contFileReq = this.allocSystem(1 + 2, 0x97) let contFileReq = this.allocSystem(1 + 2, 0x97)
@ -170,6 +176,15 @@ namespace pxt.editor {
return this.talkAsync(getFileReq, -1).then(resp) return this.talkAsync(getFileReq, -1).then(resp)
} }
streamFileAsync(path: string, cb: (d: Uint8Array) => void) {
let loop = (): Promise<void> =>
this.lock.enqueue("file", () =>
this.streamFileOnceAsync(path, cb))
.then(() => Promise.delay(500))
.then(loop)
return loop()
}
private initAsync() { private initAsync() {
return Promise.resolve() return Promise.resolve()
} }