##// END OF EJS Templates
New Plugin Manager and interface to remove all the previous crap!...
New Plugin Manager and interface to remove all the previous crap! Let's use Qt plugin API and make it much simpler.

File last commit:

r118:de85e8465e67 tip 1.0
r118:de85e8465e67 tip 1.0
Show More
isocexplorerplugin.h
334 lines | 13.6 KiB | text/x-c | CLexer
New Plugin Manager and interface to remove all the previous crap!...
r118 /*------------------------------------------------------------------------------
███████╗ ██████╗ ██████╗ ███████╗██╗ ██╗██████╗ ██╗ ██████╗ ██████╗ ███████╗██████╗
██╔════╝██╔═══██╗██╔════╝ ██╔════╝╚██╗██╔╝██╔══██╗██║ ██╔═══██╗██╔══██╗██╔════╝██╔══██╗
███████╗██║ ██║██║ █████╗ ╚███╔╝ ██████╔╝██║ ██║ ██║██████╔╝█████╗ ██████╔╝
╚════██║██║ ██║██║ ██╔══╝ ██╔██╗ ██╔═══╝ ██║ ██║ ██║██╔══██╗██╔══╝ ██╔══██╗
███████║╚██████╔╝╚██████╗ ███████╗██╔╝ ██╗██║ ███████╗╚██████╔╝██║ ██║███████╗██║ ██║
╚══════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
-- This file is a part of the SOC Explorer Software
-- Copyright (C) 2018, Plasma Physics Laboratory - CNRS
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-------------------------------------------------------------------------------*/
/*-- Author : Alexis Jeandet
-- Mail : alexis.jeandet@lpp.polytechnique.fr
----------------------------------------------------------------------------*/
#ifndef ISOCEXPLORERPLUGIN_H
#define ISOCEXPLORERPLUGIN_H
#include <QtPlugin>
#include <QWidget>
#include <QAction>
#include <QDockWidget>
#include <QMainWindow>
#include <QList>
#include <QMenu>
#include <socexplorer.h>
#include <QObject>
#include <QVariant>
#include <QVariantList>
#include <malloc.h>
#include <QFile>
#include <stdint.h>
#include <QTextStream>
#include <abstractbinfile.h>
#include <srec/srecfile.h>
#include <BinFile/binaryfile.h>
class ISocexplorerPlugin : public QDockWidget
{
Q_OBJECT
public:
//! Default plugin constructor, any plugin should call this constructor.
ISocexplorerPlugin(QWidget *parent = Q_NULLPTR,bool createPyObject=true):QDockWidget(parent)
{
Q_UNUSED(createPyObject)
closeAction=Q_NULLPTR;
menu=Q_NULLPTR;
ChildsMenu=Q_NULLPTR;
this->Connected = false;
this->setFeatures(QDockWidget::DockWidgetMovable|QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetVerticalTitleBar);
}
//! Tells if the plugin is connected, it is used to enable or disable all childrens interfaces.
virtual bool isConnected(){return this->Connected;}
//! Gives the associated Vendor IDentifier, usefull to automatically associate plugins with found
//! hardware while board enumeration.
virtual uint64_t baseAddress(){return this->BaseAddress;}
//! Sets the base address of the current instance, for example if your plugin is supposed to drive
//! an UART it will correspond to the address of it's first register. This address have at least to
//! be set by SocExplorer and it can be user accessible if you want.
virtual void setBaseAddress(uint64_t baseAddress){this->BaseAddress = baseAddress;}
QList<ISocexplorerPlugin*> childs;
ISocexplorerPlugin* parent;
QAction* closeAction;
QString instanceName(){return _instanceName;}
QString instance(){return instanceName();}
QMenu* menu;
QMenu* ChildsMenu;
signals:
//! Signal emited each time the plugin is about to be closed.
void closePlugin(ISocexplorerPlugin* driver);
void activateSig(bool flag);
void registerObject(QObject* object,const QString& instanceName);
public slots:
virtual int registermenu(QMenu* menu)
{
this->menu = menu->addMenu(this->_instanceName);
this->closeAction = this->menu->addAction(tr("Close plugin"));
QObject::connect(this->closeAction,SIGNAL(triggered()),this,SLOT(closeMe()));
this->ChildsMenu = this->menu->addMenu(QString("Childs"));
for(int i=0;i<this->childs.count();i++)
{
this->childs.at(i)->registermenu(this->ChildsMenu);
}
emit this->registerObject((QObject*)this,this->instanceName());
return 0;
}
virtual void postInstantiationTrigger(){}
//! Write slot this is the way your children plugins ask you for writing data.
//! If your plugin is supposed to have childern drivers you should implement this methode.
//! By default this methode forward the write request to the parent plugin.
//! \param Value Pointer the data buffer.
//! \param count Number of 32 bits words you should to write.
//! \param address Address from where you should to start to write.
//! \return Quantity of 32 bits words writtens.
virtual unsigned int Write(unsigned int* Value, int count, uint64_t address)
{
if(parent!=Q_NULLPTR)
{
return parent->Write(Value,count,address);
}
return 0;
}
void Write(uint64_t address, QList<QVariant> dataList)
{
unsigned int data[dataList.count()];
for(int i = 0;i<dataList.count();i++)
{
data[i] = (unsigned int)dataList.at(i).toUInt();
}
Write(data,dataList.count(),address);
}
//! Read slot this is the way your children plugins ask you for reading data.
//! If your plugin is supposed to have childern drivers you should implement this methode.
//! By default this methode forward the write request to the parent plugin.
//! \param Value Pointer the data buffer.
//! \param count Number of 32 bits words you should to read.
//! \param address Address from where you should to start to read.
//! \return Quantity of 32 bits words read.
virtual unsigned int Read(unsigned int* Value, int count, uint64_t address)
{
if(parent!=Q_NULLPTR)
{
return parent->Read(Value,count,address);
}
return 0;
}
QVariantList Read(uint64_t address, int count)
{
unsigned int data[count];
QVariantList result;
Read(data,count,address);
for(int i = 0;i<count;i++)
{
result.append(QVariant(static_cast<int>(data[i])));
}
return result;
}
virtual void closeMe(){emit this->closePlugin(this);}
virtual void activate(bool flag)
{
this->setEnabled(flag);
emit this->activateSig(flag);
}
virtual void setInstanceName(const QString& newName)
{
this->_instanceName = newName;
if(this->menu)
this->menu->setTitle(this->_instanceName);
this->setWindowTitle(newName);
this->setObjectName(newName);
}
virtual bool dumpMemory(uint64_t address, unsigned int count, QString file)
{
unsigned int* buffer = (unsigned int*)malloc(count*sizeof(unsigned int));
if(buffer!=NULL)
{
this->Read(buffer,count,address);
QFile outfile(file);
if (!outfile.open(QIODevice::ReadWrite | QIODevice::Text))
return false;
QTextStream out(&outfile);
for(int i=0;(unsigned int)i<count;i++)
out << "0x"+QString::number(address+(i*4),16) + ": 0x" + QString::number(buffer[i],16) + "\n";
free(buffer);
out.flush();
outfile.close();
return true;
}
return false;
}
virtual bool dumpMemory(uint64_t address,unsigned int count,QString file,const QString& format)
{
unsigned int* buffer = (unsigned int*)malloc(count*sizeof(unsigned int));
if(buffer!=NULL)
{
this->Read(buffer,count,address);
if(!format.compare("srec",Qt::CaseInsensitive))
{
//need to convert from in memory endianness to file endianness
//SREC is always big endian
#if __BYTE_ORDER == __LITTLE_ENDIAN
for(int l=0;l<(count);l++)
{
buffer[l] = socexplorerBswap32(buffer[l]);
}
#elif __BYTE_ORDER == __BIG_ENDIAN
#endif
codeFragment fragment((char*)buffer,count*4,address);
srecFile::toSrec(QList<codeFragment*>()<<&fragment,file);
}
if(!format.compare("bin",Qt::CaseInsensitive))
{
//beware this format is not portable from a big endian host to a litle endian one
codeFragment fragment((char*)buffer,count*4,address);
binaryFile::toBinary(QList<codeFragment*>()<<&fragment,file);
}
if(!format.compare("hexa",Qt::CaseInsensitive))
{
QFile outfile(file);
if (!outfile.open(QIODevice::ReadWrite | QIODevice::Text))
return false;
QTextStream out(&outfile);
for(int i=0;(unsigned int)i<count;i++)
out << "0x"+QString::number(address+(i*4),16) + ": 0x" + QString::number(buffer[i],16) + "\n";
free(buffer);
out.flush();
outfile.close();
}
return true;
}
return false;
}
virtual bool memSet(uint64_t address, int value, unsigned int count)
{
unsigned int* buffer = static_cast<unsigned int*>(malloc(count*sizeof(unsigned int)));
if(buffer!=Q_NULLPTR)
{
memset(static_cast<void*>(buffer),value,count*sizeof(unsigned int));
this->Write(buffer,count,address);
free(buffer );
return true;
}
return false;
}
virtual bool loadbin(uint64_t address,QString file)
{
QFile infile(file);
if (!infile.open(QIODevice::ReadOnly))
return false;
uint32_t* buffer = (uint32_t*)malloc(infile.size());
if(buffer!=NULL)
{
infile.read((char*)buffer,infile.size());
for(int i=0;i<(infile.size()/4);i++)
{
buffer[i] = socexplorerBswap32(buffer[i]);
}
this->Write(buffer,infile.size()/4,address);
free(buffer);
return true;
}
return false;
}
virtual bool loadfile(abstractBinFile* file)
{
{
if(file->isopened())
{
QList<codeFragment*> fragments= file->getFragments();
for(int i=0;i<fragments.count();i++)
{
int size = fragments.at(i)->size/4;
// TODO fixme, should be the oposite
#if __BYTE_ORDER == __LITTLE_ENDIAN
if(!file->litleendian)
{
uint32_t* buffer = (uint32_t*)malloc(fragments.at(i)->size);
memcpy(buffer,fragments.at(i)->data,fragments.at(i)->size);
if(buffer!=NULL)
{
for(int l=0;l<(size);l++)
{
buffer[l] = socexplorerBswap32(buffer[l]);
}
this->Write(buffer,size,fragments.at(i)->address);
free(buffer);
}
}
else
{
this->Write((uint32_t*) fragments.at(i)->data,size,fragments.at(i)->address);
}
#elif __BYTE_ORDER == __BIG_ENDIAN
if(file->litleendian)
{
uint32_t* buffer = (uint32_t*)malloc(fragments.at(i)->size);
memcpy(buffer,fragments.at(i)->data,fragments.at(i)->size);
if(buffer!=NULL)
{
for(int l=0;l<(size);l++)
{
buffer[l] = socexplorerBswap32(buffer[l]);
}
this->Write(buffer,size,fragments.at(i)->address);
free(buffer);
}
}
else
{
this->Write((uint32_t*) fragments.at(i)->data,size,fragments.at(i)->address);
}
#endif
}
}
return true;
}
}
ISocexplorerPlugin* parentPlugin(){return this->parent;}
ISocexplorerPlugin* toPlugin(){return static_cast<ISocexplorerPlugin*>(this);}
protected:
QString _instanceName;
uint64_t BaseAddress;
bool Connected;
};
Q_DECLARE_INTERFACE(ISocexplorerPlugin, "socexplorer.plugins.ISocexplorerPlugin")
#endif // ISOCEXPLORERPLUGIN_H