/**
|
/*
|
* @file
|
* Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com
|
* @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved.
|
*
|
* @author Sergey Khabarov - sergeykhbr@gmail.com
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
* @brief GUI for the RISC-V debugger.
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
*/
|
*/
|
|
|
#include "api_core.h"
|
#include "api_core.h"
|
#include "gui_plugin.h"
|
#include "gui_plugin.h"
|
#include "coreservices/iserial.h"
|
#include "coreservices/iserial.h"
|
#include "coreservices/irawlistener.h"
|
#include "coreservices/irawlistener.h"
|
#include <string>
|
#include <string>
|
|
|
namespace debugger {
|
namespace debugger {
|
|
|
GuiPlugin::GuiPlugin(const char *name)
|
GuiPlugin::GuiPlugin(const char *name)
|
: IService(name), IHap(HAP_ConfigDone) {
|
: IService(name), IHap(HAP_ConfigDone) {
|
registerInterface(static_cast<IGui *>(this));
|
registerInterface(static_cast<IGui *>(this));
|
registerInterface(static_cast<IThread *>(this));
|
registerInterface(static_cast<IThread *>(this));
|
registerInterface(static_cast<IHap *>(this));
|
registerInterface(static_cast<IHap *>(this));
|
registerAttribute("WidgetsConfig", &guiConfig_);
|
registerAttribute("WidgetsConfig", &guiConfig_);
|
registerAttribute("SocInfo", &socInfo_);
|
registerAttribute("SocInfo", &socInfo_);
|
registerAttribute("CommandExecutor", &cmdExecutor_);
|
registerAttribute("CommandExecutor", &cmdExecutor_);
|
|
|
guiConfig_.make_dict();
|
guiConfig_.make_dict();
|
socInfo_.make_string("");
|
socInfo_.make_string("");
|
cmdExecutor_.make_string("");
|
cmdExecutor_.make_string("");
|
|
|
char coredir[4096];
|
char coredir[4096];
|
RISCV_get_core_folder(coredir, sizeof(coredir));
|
RISCV_get_core_folder(coredir, sizeof(coredir));
|
QString topDir(coredir);
|
QString topDir(coredir);
|
QResource::registerResource(
|
QResource::registerResource(
|
topDir + "resources/gui.rcc");
|
topDir + "resources/gui.rcc");
|
|
|
info_ = 0;
|
info_ = 0;
|
ui_ = NULL;
|
ui_ = NULL;
|
RISCV_event_create(&eventCommandAvailable_, "eventCommandAvailable_");
|
RISCV_event_create(&eventCommandAvailable_, "eventCommandAvailable_");
|
RISCV_event_create(&config_done_, "eventGuiGonfigGone");
|
RISCV_event_create(&config_done_, "eventGuiGonfigGone");
|
RISCV_register_hap(static_cast<IHap *>(this));
|
RISCV_register_hap(static_cast<IHap *>(this));
|
RISCV_mutex_init(&mutexCommand_);
|
|
|
|
cmdQueueWrPos_ = 0;
|
|
cmdQueueRdPos_ = 0;
|
|
cmdQueueCntTotal_ = 0;
|
|
|
|
// Adding path to platform libraries:
|
// Adding path to platform libraries:
|
char core_path[1024];
|
char core_path[1024];
|
RISCV_get_core_folder(core_path, sizeof(core_path));
|
RISCV_get_core_folder(core_path, sizeof(core_path));
|
QStringList paths = QApplication::libraryPaths();
|
QStringList paths = QApplication::libraryPaths();
|
std::string qt_path = std::string(core_path);
|
std::string qt_path = std::string(core_path);
|
std::string qt_lib_path = qt_path;
|
std::string qt_lib_path = qt_path;
|
paths.append(QString(qt_lib_path.c_str()));
|
paths.append(QString(qt_lib_path.c_str()));
|
qt_lib_path += "qtlib/";
|
qt_lib_path += "qtlib/";
|
paths.append(QString(qt_lib_path.c_str()));
|
paths.append(QString(qt_lib_path.c_str()));
|
qt_lib_path += "platforms";
|
qt_lib_path += "platforms";
|
paths.append(QString(qt_lib_path.c_str()));
|
paths.append(QString(qt_lib_path.c_str()));
|
|
|
paths.append(QString("platforms"));
|
paths.append(QString("platforms"));
|
QApplication::setLibraryPaths(paths);
|
QApplication::setLibraryPaths(paths);
|
|
|
ui_ = new QtWrapper(static_cast<IGui *>(this));
|
ui_ = new QtWrapper(static_cast<IGui *>(this));
|
}
|
}
|
|
|
GuiPlugin::~GuiPlugin() {
|
GuiPlugin::~GuiPlugin() {
|
RISCV_event_close(&config_done_);
|
RISCV_event_close(&config_done_);
|
RISCV_event_close(&eventCommandAvailable_);
|
RISCV_event_close(&eventCommandAvailable_);
|
RISCV_mutex_destroy(&mutexCommand_);
|
|
}
|
}
|
|
|
void GuiPlugin::postinitService() {
|
void GuiPlugin::postinitService() {
|
iexec_ = static_cast<ICmdExecutor *>(
|
iexec_ = static_cast<ICmdExecutor *>(
|
RISCV_get_service_iface(cmdExecutor_.to_string(), IFACE_CMD_EXECUTOR));
|
RISCV_get_service_iface(cmdExecutor_.to_string(), IFACE_CMD_EXECUTOR));
|
if (!iexec_) {
|
if (!iexec_) {
|
RISCV_error("ICmdExecutor interface of %s not found.",
|
RISCV_error("ICmdExecutor interface of %s not found.",
|
cmdExecutor_.to_string());
|
cmdExecutor_.to_string());
|
}
|
}
|
|
|
info_ = static_cast<ISocInfo *>(
|
info_ = static_cast<ISocInfo *>(
|
RISCV_get_service_iface(socInfo_.to_string(), IFACE_SOC_INFO));
|
RISCV_get_service_iface(socInfo_.to_string(), IFACE_SOC_INFO));
|
if (!iexec_) {
|
if (!iexec_) {
|
RISCV_error("ISocInfo interface of %s not found.",
|
RISCV_error("ISocInfo interface of %s not found.",
|
socInfo_.to_string());
|
socInfo_.to_string());
|
}
|
}
|
|
|
ui_->postInit(&guiConfig_);
|
ui_->postInit(&guiConfig_);
|
run();
|
run();
|
}
|
}
|
|
|
|
IService *GuiPlugin::getParentService() {
|
|
return static_cast<IService *>(this);
|
|
}
|
|
|
IFace *GuiPlugin::getSocInfo() {
|
IFace *GuiPlugin::getSocInfo() {
|
return info_;
|
return info_;
|
}
|
}
|
|
|
const AttributeType *GuiPlugin::getpConfig() {
|
const AttributeType *GuiPlugin::getpConfig() {
|
return &guiConfig_;
|
return &guiConfig_;
|
}
|
}
|
|
|
void GuiPlugin::registerCommand(IGuiCmdHandler *src,
|
void GuiPlugin::registerCommand(IGuiCmdHandler *src,
|
AttributeType *cmd,
|
AttributeType *cmd,
|
bool silent) {
|
bool silent) {
|
|
queue_.put(src, cmd, silent);
|
if (cmdQueueCntTotal_ >= CMD_QUEUE_SIZE) {
|
|
RISCV_error("Command queue size %d overflow. Target not responding",
|
|
cmdQueueCntTotal_);
|
|
return;
|
|
}
|
|
//RISCV_info("CMD %s", cmd->to_string());
|
|
if (cmdQueueWrPos_ == CMD_QUEUE_SIZE) {
|
|
cmdQueueWrPos_ = 0;
|
|
}
|
|
RISCV_mutex_lock(&mutexCommand_);
|
|
cmdQueue_[cmdQueueWrPos_].silent = silent;
|
|
cmdQueue_[cmdQueueWrPos_].src = src;
|
|
cmdQueue_[cmdQueueWrPos_++].cmd = *cmd;
|
|
cmdQueueCntTotal_++;
|
|
RISCV_mutex_unlock(&mutexCommand_);
|
|
RISCV_event_set(&eventCommandAvailable_);
|
RISCV_event_set(&eventCommandAvailable_);
|
}
|
}
|
|
|
void GuiPlugin::removeFromQueue(IFace *iface) {
|
void GuiPlugin::removeFromQueue(IFace *iface) {
|
RISCV_mutex_lock(&mutexCommand_);
|
queue_.remove(iface);
|
for (unsigned i = 0; i < CMD_QUEUE_SIZE; i++) {
|
|
if (iface == cmdQueue_[i].src) {
|
|
cmdQueue_[i].src = NULL;
|
|
}
|
|
}
|
|
RISCV_mutex_unlock(&mutexCommand_);
|
|
}
|
}
|
|
|
void GuiPlugin::hapTriggered(IFace *isrc, EHapType type,
|
void GuiPlugin::hapTriggered(IFace *isrc, EHapType type,
|
const char *descr) {
|
const char *descr) {
|
RISCV_event_set(&config_done_);
|
RISCV_event_set(&config_done_);
|
}
|
}
|
|
|
void GuiPlugin::busyLoop() {
|
void GuiPlugin::busyLoop() {
|
RISCV_event_wait(&config_done_);
|
RISCV_event_wait(&config_done_);
|
|
|
while (isEnabled()) {
|
while (isEnabled()) {
|
if (RISCV_event_wait_ms(&eventCommandAvailable_, 500)) {
|
if (RISCV_event_wait_ms(&eventCommandAvailable_, 500)) {
|
RISCV_event_clear(&eventCommandAvailable_);
|
RISCV_event_clear(&eventCommandAvailable_);
|
continue;
|
continue;
|
}
|
}
|
|
|
processCmdQueue();
|
processCmdQueue();
|
}
|
}
|
ui_->gracefulClose();
|
ui_->gracefulClose();
|
delete ui_;
|
delete ui_;
|
}
|
}
|
|
|
bool GuiPlugin::processCmdQueue() {
|
bool GuiPlugin::processCmdQueue() {
|
AttributeType resp;
|
AttributeType resp;
|
while (cmdQueueCntTotal_ > 0) {
|
AttributeType cmd;
|
AttributeType &cmd = cmdQueue_[cmdQueueRdPos_].cmd;
|
IFace *iresp;
|
|
bool silent;
|
|
|
iexec_->exec(cmd.to_string(), &resp, cmdQueue_[cmdQueueRdPos_].silent);
|
queue_.initProc();
|
|
queue_.pushPreQueued();
|
|
|
RISCV_mutex_lock(&mutexCommand_);
|
while (queue_.getNext(&iresp, cmd, silent)) {
|
if (cmdQueue_[cmdQueueRdPos_].src) {
|
iexec_->exec(cmd.to_string(), &resp, silent);
|
cmdQueue_[cmdQueueRdPos_].src->handleResponse(
|
|
const_cast<AttributeType *>(&cmd), &resp);
|
if (iresp) {
|
}
|
static_cast<IGuiCmdHandler *>(iresp)->handleResponse(&cmd, &resp);
|
if ((++cmdQueueRdPos_) >= CMD_QUEUE_SIZE) {
|
|
cmdQueueRdPos_ = 0;
|
|
}
|
}
|
cmdQueueCntTotal_--;
|
cmd.attr_free();
|
RISCV_mutex_unlock(&mutexCommand_);
|
resp.attr_free();
|
}
|
}
|
return false;
|
return false;
|
}
|
}
|
|
|
void GuiPlugin::stop() {
|
void GuiPlugin::stop() {
|
IThread::stop();
|
IThread::stop();
|
}
|
}
|
|
|
extern "C" void plugin_init(void) {
|
extern "C" void plugin_init(void) {
|
REGISTER_CLASS(GuiPlugin);
|
REGISTER_CLASS(GuiPlugin);
|
}
|
}
|
|
|
} // namespace debugger
|
} // namespace debugger
|
|
|