wire up firmware flash progress

Also turn off logging and longer checksum interval to improve performance

94K movehub fw flashes in about 1:45
This commit is contained in:
David Lechner
2020-05-20 19:57:23 -05:00
committed by David Lechner
parent 7ba99d62bb
commit 3ae2fb2eef
8 changed files with 81 additions and 39 deletions
+27
View File
@@ -299,6 +299,10 @@ export enum BootloaderActionType {
* Flash new firmware to the device.
*/
FlashFirmware = 'bootloader.action.flash',
/**
* Firmware flash progress.
*/
FlashProgress = 'bootloader.action.flash.progress',
}
export interface BootloaderFlashFirmwareAction
@@ -309,3 +313,26 @@ export interface BootloaderFlashFirmwareAction
export function flashFirmware(data: ArrayBuffer): BootloaderFlashFirmwareAction {
return { type: BootloaderActionType.FlashFirmware, data };
}
export interface BootloaderFlashProgressAction
extends Action<BootloaderActionType.FlashProgress> {
/**
* The number of bytes that have been flashed so far.
*/
complete: number;
/**
* The total number of bytes to be flashed.
*/
total: number;
}
export function progress(
complete: number,
total: number,
): BootloaderFlashProgressAction {
return { type: BootloaderActionType.FlashProgress, complete, total };
}
export type BootloaderAction =
| BootloaderFlashFirmwareAction
| BootloaderFlashProgressAction;
+1 -1
View File
@@ -2,7 +2,7 @@ import React from 'react';
import { Col, Row } from 'react-bootstrap';
import Container from 'react-bootstrap/Container';
import Editor from './Editor';
import StatusBar from './Statusbar';
import StatusBar from './StatusBar';
import Terminal from './Terminal';
import Toolbar from './Toolbar';
+24
View File
@@ -0,0 +1,24 @@
import React from 'react';
import ProgressBar from 'react-bootstrap/ProgressBar';
import { connect } from 'react-redux';
import { RootState } from '../reducers';
type StateProps = { progress: number };
type StatusProps = StateProps;
class StatusBar extends React.Component<StatusProps> {
render(): JSX.Element {
return (
<div className="bg-info p-2">
<ProgressBar className="w-25" now={this.props.progress} />
</div>
);
}
}
const mapStateToProps = (state: RootState): StateProps => ({
progress: state.status.progress,
});
export default connect(mapStateToProps)(StatusBar);
-33
View File
@@ -1,33 +0,0 @@
import React from 'react';
import ProgressBar from 'react-bootstrap/ProgressBar';
import { BLEConnectionState } from '../reducers/ble';
interface StatusBarState {
bleState: BLEConnectionState;
}
class StatusBar extends React.Component<{}, StatusBarState> {
constructor(props: {}) {
super(props);
this.state = { bleState: BLEConnectionState.Disconnected };
this.onAction = this.onAction.bind(this);
}
private onAction(action: string): void {
console.log(action);
}
setBLEState(state: BLEConnectionState): void {
this.setState({ bleState: state });
}
render(): JSX.Element {
return (
<div className="bg-info p-2">
<ProgressBar className="w-25"></ProgressBar>
</div>
);
}
}
export default StatusBar;
+2 -1
View File
@@ -17,7 +17,8 @@ import serviceMiddleware from './services';
const sagaMiddleware = createSagaMiddleware();
const epicMiddleware = createEpicMiddleware();
const loggerMiddleware = createLogger();
// TODO: add runtime option or filter - logger affects firmware flash performance
const loggerMiddleware = createLogger({ predicate: () => false });
const store = createStore(
rootReducer,
+3 -1
View File
@@ -4,6 +4,7 @@ import bootloader, { BootloaderState } from './bootloader';
import editor, { EditorState } from './editor';
import hub, { HubState } from './hub';
import notification, { NotificationState } from './notification';
import status, { StatusState } from './status';
/**
* Root state for redux store.
@@ -14,6 +15,7 @@ export interface RootState {
readonly editor: EditorState;
readonly hub: HubState;
readonly notification: NotificationState;
readonly status: StatusState;
}
export default combineReducers({ bootloader, ble, editor, hub, notification });
export default combineReducers({ bootloader, ble, editor, hub, notification, status });
+18
View File
@@ -0,0 +1,18 @@
import { Reducer } from 'react';
import { combineReducers } from 'redux';
import { BootloaderAction, BootloaderActionType } from '../actions/bootloader';
const progress: Reducer<number, BootloaderAction> = (state = -1, action) => {
switch (action.type) {
case BootloaderActionType.FlashProgress:
return (action.complete / action.total) * 100;
default:
return state;
}
};
export interface StatusState {
readonly progress: number;
}
export default combineReducers({ progress });
+6 -3
View File
@@ -41,6 +41,7 @@ import {
initResponse,
programRequest,
programResponse,
progress,
rebootRequest,
send,
stateResponse,
@@ -305,11 +306,11 @@ function* flashFirmware(action: BootloaderFlashFirmwareAction): Generator {
const payload = firmware.slice(offset, offset + MaxProgramFlashSize);
yield put(programRequest(info[0].startAddress + offset, payload.buffer));
// TODO: dispatch progress action
yield put(progress(offset, firmware.length));
// request checksum every so often to prevent buffer overrun on the hub
// request checksum every 8K to prevent buffer overrun on the hub
// because of sending too much data at once
if (++count % 10 === 0) {
if (++count % 585 === 0) {
yield put(checksumRequest());
const checksum = (yield wait(
BootloaderResponseActionType.Checksum,
@@ -334,6 +335,8 @@ function* flashFirmware(action: BootloaderFlashFirmwareAction): Generator {
throw Error("Didn't flash all bytes");
}
yield put(progress(firmware.length, firmware.length));
// this will cause the remote device to disconnect and reboot
yield put(rebootRequest());
}