1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-11-29 07:24:13 +01:00

gcs uploader: add support for "Safe Boot" to the GCS uploader

When halted in the bootloader or while rescuing a board, the
user can press the "Safe Boot" button in the uploader gadget
to force the FW to boot with a default hwsettings configuration.

The default conditions of the hwsettings uavo will disable all
optional modules, disable all serial port config, and ensure that
the board can communicate via the USB HID telemetry interface.

Once booted in this mode, a user can easily reconfigure the
hwsettings uavo through the config GUI and save the fixed
settings to the board to be used on the next reboot.  No need
to wipe all settings just to recover from a non-functional
HW config.

NOTE: The GCS needs to grow some very clear visual clues to
      indicate when the board has booted in safe mode.  The
      firmware helpfully raises a (new) critical alarm called
      BootFault whenever it boots in safe mode.
This commit is contained in:
Stacey Sheldon 2012-01-02 14:21:12 -05:00
parent 4d2760f11d
commit 4fd40ca0d2
5 changed files with 53 additions and 6 deletions

View File

@ -509,7 +509,7 @@ int DFUObject::AbortOperation(void)
/**
Starts the firmware (leaves bootloader and boots the main software)
*/
int DFUObject::JumpToApp()
int DFUObject::JumpToApp(bool safeboot)
{
char buf[BUF_LEN];
buf[0] =0x02;//reportID
@ -520,8 +520,17 @@ int DFUObject::JumpToApp()
buf[5] = 0;
buf[6] = 0;
buf[7] = 0;
buf[8] = 0;
buf[9] = 0;
if (safeboot)
{
/* force system to safe boot mode (hwsettings == defaults) */
buf[8] = 0x5A;
buf[9] = 0xFE;
}
else
{
buf[8] = 0;
buf[9] = 0;
}
return sendData(buf, BUF_LEN);
//return hidHandle.send(0,buf, BUF_LEN, 500);

View File

@ -129,7 +129,7 @@ namespace OP_DFU {
// Service commands:
bool enterDFU(int const &devNumber);
bool findDevices();
int JumpToApp();
int JumpToApp(bool);
int ResetDevice(void);
OP_DFU::Status StatusRequest();
bool EndOperation();

View File

@ -50,6 +50,24 @@ menu on the right.</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="safeBootButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Boots the system into safe mode (ie. default HwSettings).
Only useful if the system is halted
(mainboard blue LED blinking slowly, orange LED off)
If telemetry is not running, select the link using the dropdown
menu on the right.</string>
</property>
<property name="text">
<string>Safe Boot</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="resetButton">
<property name="enabled">

View File

@ -52,6 +52,7 @@ UploaderGadgetWidget::UploaderGadgetWidget(QWidget *parent) : QWidget(parent)
connect(m_config->haltButton, SIGNAL(clicked()), this, SLOT(goToBootloader()));
connect(m_config->resetButton, SIGNAL(clicked()), this, SLOT(systemReset()));
connect(m_config->bootButton, SIGNAL(clicked()), this, SLOT(systemBoot()));
connect(m_config->safeBootButton, SIGNAL(clicked()), this, SLOT(systemSafeBoot()));
connect(m_config->rescueButton, SIGNAL(clicked()), this, SLOT(systemRescue()));
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
connect(cm,SIGNAL(deviceConnected(QIODevice*)),this,SLOT(onPhisicalHWConnect()));
@ -117,6 +118,7 @@ QString UploaderGadgetWidget::getPortDevice(const QString &friendName)
void UploaderGadgetWidget::onPhisicalHWConnect()
{
m_config->bootButton->setEnabled(false);
m_config->safeBootButton->setEnabled(false);
m_config->rescueButton->setEnabled(false);
m_config->telemetryLink->setEnabled(false);
}
@ -132,6 +134,7 @@ void UploaderGadgetWidget::populate()
{
m_config->haltButton->setEnabled(true);
m_config->resetButton->setEnabled(true);
m_config->safeBootButton->setEnabled(false);
m_config->bootButton->setEnabled(false);
m_config->rescueButton->setEnabled(false);
m_config->telemetryLink->setEnabled(false);
@ -155,6 +158,7 @@ void UploaderGadgetWidget::onAutopilotDisconnect(){
m_config->haltButton->setEnabled(false);
m_config->resetButton->setEnabled(false);
m_config->bootButton->setEnabled(true);
m_config->safeBootButton->setEnabled(true);
if (currentStep == IAP_STATE_BOOTLOADER) {
m_config->rescueButton->setEnabled(false);
m_config->telemetryLink->setEnabled(false);
@ -311,6 +315,7 @@ void UploaderGadgetWidget::goToBootloader(UAVObject* callerObj, bool success)
*/
// Need to re-enable in case we were not connected
m_config->bootButton->setEnabled(true);
m_config->safeBootButton->setEnabled(true);
/*
m_config->telemetryLink->setEnabled(false);
m_config->rescueButton->setEnabled(false);
@ -348,14 +353,25 @@ void UploaderGadgetWidget::systemReset()
goToBootloader();
}
void UploaderGadgetWidget::systemBoot()
{
commonSystemBoot(false);
}
void UploaderGadgetWidget::systemSafeBoot()
{
commonSystemBoot(true);
}
/**
Tells the system to boot (from Bootloader state)
*/
void UploaderGadgetWidget::systemBoot()
void UploaderGadgetWidget::commonSystemBoot(bool safeboot)
{
clearLog();
m_config->bootButton->setEnabled(false);
m_config->safeBootButton->setEnabled(false);
// Suspend telemety & polling in case it is not done yet
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
@ -379,11 +395,12 @@ void UploaderGadgetWidget::systemBoot()
delete dfu;
dfu = NULL;
m_config->bootButton->setEnabled(true);
m_config->safeBootButton->setEnabled(true);
m_config->rescueButton->setEnabled(true); // Boot not possible, maybe Rescue OK?
return;
}
log("Booting system...");
dfu->JumpToApp();
dfu->JumpToApp(safeboot);
// Restart the polling thread
cm->resumePolling();
m_config->rescueButton->setEnabled(true);
@ -530,6 +547,7 @@ void UploaderGadgetWidget::systemRescue()
m_config->haltButton->setEnabled(false);
m_config->resetButton->setEnabled(false);
m_config->bootButton->setEnabled(true);
m_config->safeBootButton->setEnabled(true);
m_config->rescueButton->setEnabled(false);
currentStep = IAP_STATE_BOOTLOADER; // So that we can boot from the GUI afterwards.
}

View File

@ -94,6 +94,8 @@ private slots:
void goToBootloader(UAVObject* = NULL, bool = false);
void systemReset();
void systemBoot();
void systemSafeBoot();
void commonSystemBoot(bool = false);
void systemRescue();
void getSerialPorts();
void perform();