Related
I'm developing a driver for a device with Qt. I have already done that many times and I have a code that I use every time. But, this time, when I open the QserialPort, it seems to work correctly, but it is not : I can write, the device receives commands, but I cannot receive on the soft : the signal QSerialPort::ReadyRead is never triggered.
When I open the serial port with Putty (just open it without sending anything) and close it just after, my Qt soft work perfectly when I reconnect it : I can now receive correctly...
Do you have an idea of what putty do of different/more than my soft when opening the port ?
(I have the same parameters and I'm on windows and Qt 5.15.2).
My code for opening :
_serial->setPortName(com);
_serial->setBaudRate(QSerialPort::Baud115200);
_serial->setDataBits(QSerialPort::Data8);
_serial->setParity(QSerialPort::NoParity);
_serial->setStopBits(QSerialPort::OneStop);
_serial->setFlowControl(QSerialPort::NoFlowControl);
if(!_serial->open(QIODevice::ReadWrite))
{
emit error(tr("Unable to open port"));
return;
}
_serial->clear();
My code for write (simple string like "hello") :
_serial->write("Hello");
My code for connect the signal :
connect(_serial, &QSerialPort::readyRead, this, &device::processCommand);
My code for read serial (processCommand()):
QString bufferData;
if (_serial->isOpen())
{
_datas.append(_serial->readAll());
bufferData = _datas.constData();
}
EDIT : The Qt exemple 'Terminal' do not works on windows with my device but works on ubuntu...
EDIT 2 : SOLUTION : I have finally find the solution, just add _serial->setDataTerminalReady(true); after opening the QSerialPort.
Thanks.
I ran into the same problem where the read signal was not detected in the virtual USB port. In the end I came to the conclusion that the QSerialPort class shouldn't.
I solved it using QThread and Win32 API.
#pragma once
#include <windows.h>
#include <QMutex>
#include <QThread>
#include <QWaitCondition>
#define SERIAL_RX_BUF_SIZE 2047
class SerialThread : public QThread
{
Q_OBJECT
public:
explicit SerialThread(QObject *parent = nullptr);
~SerialThread();
bool startThread(const QString& portName);
void stopThread();
void request(const QString& command);
signals:
void response(char* text);
void timeout();
private:
void run() override;
bool writeCommand(const QString& command);
QString m_portName;
QString m_command;
QMutex m_mutex;
QWaitCondition m_wait;
volatile bool m_quit = false;
HANDLE m_hComm;
char m_buf[SERIAL_RX_BUF_SIZE + 1];
};
#include "serial_thread.h"
#include <QDebug>
SerialThread::SerialThread(QObject *parent) :
QThread(parent)
{
memset(m_buf, 0, sizeof(m_buf));
}
SerialThread::~SerialThread()
{
}
bool SerialThread::startThread(const QString &portName)
{
const QMutexLocker locker(&m_mutex);
m_hComm = CreateFileA(portName.toStdString().c_str(), // PORT NAME
GENERIC_READ | GENERIC_WRITE, // READ/WRITE
0, // NO SHARING
NULL, // NO SECURITY
OPEN_EXISTING, // OPEN EXISTING PORT ONLY
0, // NON OVERLAPPED I/O
NULL); // NULL FOR COMM DEVICES
if (m_hComm == INVALID_HANDLE_VALUE)
{
return false;
}
m_portName = portName;
if (!SetCommMask(m_hComm, EV_RXCHAR | EV_ERR))
{
qCritical() << "SetCommMask failed";
CloseHandle(m_hComm);
return false;
}
COMMTIMEOUTS comm_timeouts;
if (!GetCommTimeouts(m_hComm, &comm_timeouts))
{
qCritical() << "GetCommTimeouts failed";
CloseHandle(m_hComm);
return false;
}
comm_timeouts.ReadIntervalTimeout = 1;
comm_timeouts.ReadTotalTimeoutMultiplier = 0;
comm_timeouts.ReadTotalTimeoutConstant = 500;
comm_timeouts.WriteTotalTimeoutMultiplier = 0;
comm_timeouts.WriteTotalTimeoutConstant = 0;
if (!SetCommTimeouts(m_hComm, &comm_timeouts))
{
qCritical() << "SetCommTimeouts failed";
CloseHandle(m_hComm);
return false;
}
start();
return true;
}
void SerialThread::stopThread()
{
m_mutex.lock();
m_quit = true;
m_mutex.unlock();
m_wait.wakeAll();
wait();
}
void SerialThread::request(const QString& command)
{
m_mutex.lock();
m_command = command;
m_mutex.unlock();
m_wait.wakeAll();
}
void SerialThread::run()
{
DWORD dwEvtMask, nRead;
while (!m_quit)
{
m_mutex.lock();
m_wait.wait(&m_mutex);
m_mutex.unlock();
{
const QMutexLocker locker(&m_mutex);
if (m_command.isEmpty())
{
continue;
}
if (!writeCommand(m_command))
{
continue;
}
if (WaitCommEvent(m_hComm, &dwEvtMask, NULL))
{
if (dwEvtMask & EV_ERR)
{
qCritical() << "Wait failed with error: " << GetLastError();
break;
}
if (dwEvtMask & EV_RXCHAR)
{
if (!ReadFile(m_hComm, &m_buf, SERIAL_RX_BUF_SIZE, &nRead, NULL))
{
qCritical() << "ReadFile error: " << GetLastError();
}
else
{
m_buf[nRead] = 0;
qDebug() << "Read: " << nRead;
emit response(m_buf);
}
}
}
else
{
DWORD dwRet = GetLastError();
if (ERROR_IO_PENDING == dwRet)
{
qDebug() << "RX timeout";
emit timeout();
}
else
{
qCritical() << "WaitCommEvent failed: " << dwRet;
}
}
m_command.clear();
}
}
CloseHandle(m_hComm);
m_quit = false;
}
bool SerialThread::writeCommand(const QString& command)
{
std::string s = command.toStdString();
DWORD n;
if (!WriteFile(m_hComm, s.data(), s.length(), &n, NULL))
{
qCritical() << "WriteFile error";
return false;
}
return true;
}
In my project,
I implement a new class called myApp which inherits from ApplicationBase and UdpSocket classes. When I build my project I get no error, but when I debug C/C++ application with the IDE, it displays the first error in errors section. And the command line display the second error when I run make :
Code of myApp.ned, myApp.h and myApp.cc in what follows :
I did include inet library in project references, and I tried the solution posted in The following NED types could not be fully resolved, due to a missing base type or interface.
import inet.applications.contract.IApp;
simple myApp like IApp
{
parameters:
int localPort = default(-1); // local UDP port number (-1: use ephemeral port)
int destPort; // remote UDP port number
string packetName = default("myApp");
string interfaceTableModule; // The path to the InterfaceTable module
double helloInterval #unit(s) = default(5s); // how often hello messages should be sent out
volatile double sendInterval #unit(s); // should usually be a random value, e.g. exponential(1)
double startTime #unit(s) = default(this.sendInterval); // application start time (start of the first packet)
double stopTime #unit(s) = default(-1s); // time of finishing sending, -1s means forever
double maxVariance = default(1); // This is the maximum of a random value to determine when the first hello message will be sent out
volatile double broadcastDelay #unit(s) = default(uniform(0s,0.01s));
int timeToLive = default(-1); // if not -1, set the TTL (IPv4) or Hop Limit (IPv6) field of sent packets to this value
bool dontFragment = default(false); // if true, asks IP to not fragment the message during routing
int typeOfService = default(-1); // if not -1, set the ToS (IPv4) or Traffic Class (IPv6) field of sent packets to this value
string multicastInterface = default(""); // if not empty, set the multicast output interface option on the socket (interface name expected)
bool receiveBroadcast = default(false); // if true, makes the socket receive broadcast packets
bool joinLocalMulticastGroups = default(false); // if true, makes the socket receive packets from all multicast groups set on local interfaces
#class(myApp);
gates:
input socketIn #labels(UdpControlInfo/up);
output socketOut #labels(UdpControlInfo/down);
}
#ifndef MYAPP_H_
#define MYAPP_H_
#include "inet/common/INETDefs.h"
#include "inet/applications/base/ApplicationBase.h"
#include "inet/transportlayer/contract/udp/UdpSocket.h"
#include "inet/transportlayer/contract/udp/UdpControlInfo_m.h"
#include "inet/common/ModuleAccess.h"
#include "inet/common/TimeTag_m.h"
#include "inet/common/packet/Packet.h"
#include "inet/common/lifecycle/ModuleOperations.h"
#include "inet/common/IProtocolRegistrationListener.h"
#include "inet/common/ProtocolTag_m.h"
#include "inet/linklayer/common/InterfaceTag_m.h"
#include "inet/networklayer/contract/IInterfaceTable.h"
#include "inet/networklayer/contract/ipv4/Ipv4Address.h"
#include "inet/networklayer/ipv4/IIpv4RoutingTable.h"
#include "inet/networklayer/ipv4/Ipv4Header_m.h"
#include "inet/networklayer/ipv4/Ipv4InterfaceData.h"
#include "inet/networklayer/common/FragmentationTag_m.h"
#include "inet/networklayer/common/L3AddressResolver.h"
#include "HelloMsg_m.h"
#include "XedMsg_m.h"
#include <omnetpp.h>
#include <vector>
#include <random>
#include <algorithm>
using namespace omnetpp;
using namespace inet;
using namespace std;
class myApp : public ApplicationBase, public UdpSocket::ICallback
{
protected:
//enum SelfMsgKinds { START = 1, SEND, STOP };
int localPort = -1, destPort = -1;
bool dontFragment = false;
const char *packetName = nullptr;
simtime_t startTime;
simtime_t stopTime;
// state
UdpSocket socket;
cMessage *selfMsg = nullptr;
cModule *host = nullptr;
cMessage *event = nullptr;
cPar *broadcastDelay = nullptr;
unsigned int sequencenumber = 0;
simtime_t helloInterval;
IInterfaceTable *ift = nullptr;
InterfaceEntry *interface80211ptr = nullptr;
int interfaceId = -1;
list<L3Address> neighbors;
Ipv4Address source;
/********** XED **********/
class XED
{
public:
L3Address originatorAddr, destinationAddr;
unsigned int random;
XED(const L3Address& originatorAddr, const L3Address& destinationAddr, unsigned int random)
: originatorAddr(originatorAddr), destinationAddr(destinationAddr), random(random) {};
bool operator==(const XED& other) const
{
return this->originatorAddr == other.originatorAddr && this->destinationAddr == other.destinationAddr
&& this->random == other.random;
}
};
list<XED> lr,ls;
/********** MTLSD **********/
class MTLSD
{
public:
L3Address originatorAddr, destinationAddr;
char *position;
simtime_t time;
MTLSD(const L3Address& originatorAddr, const L3Address& destinationAddr, char *position, simtime_t time)
: originatorAddr(originatorAddr), destinationAddr(destinationAddr), position(position), time(time) {};
bool operator==(const MTLSD& other) const
{
return this->originatorAddr == other.originatorAddr && this->destinationAddr == other.destinationAddr
&& this->position == other.position && this->time == time;
}
};
protected:
virtual int numInitStages() const override { return NUM_INIT_STAGES; }
virtual void initialize(int stage) override;
virtual void handleMessageWhenUp(cMessage *msg) override;
void handleSelfMessage(cMessage *msg);
/*virtual void processStart();
virtual void processSend();
virtual void processStop();*/
// lifecycle
virtual void handleStartOperation(LifecycleOperation *operation) override { start(); }
virtual void handleStopOperation(LifecycleOperation *operation) override { stop(); }
virtual void handleCrashOperation(LifecycleOperation *operation) override { stop(); }
void start();
void stop();
virtual void socketDataArrived(UdpSocket *socket, Packet *packet) override;
virtual void socketErrorArrived(UdpSocket *socket, Indication *indication) override;
virtual void socketClosed(UdpSocket *socket) override;
//virtual void generateMTLSDPacket();
//virtual Packet *generateXEDPacket();
virtual double generateRandom();
public:
myApp() {}
~myApp();
};
#endif /* MYAPP_H_ */
#include "myApp.h"
#include "inet/applications/base/ApplicationPacket_m.h"
#include "inet/applications/udpapp/UdpBasicApp.h"
#include "inet/common/TagBase_m.h"
#include "inet/networklayer/common/L3AddressTag_m.h"
#include <iterator>
using namespace std;
Define_Module(myApp);
myApp::~myApp()
{
EV << "App destructor" << endl;
cancelAndDelete(selfMsg);
}
void myApp::initialize(int stage)
{
ApplicationBase::initialize(stage);
if (stage == INITSTAGE_LOCAL)
{
sequencenumber = 0;
ift = getModuleFromPar<IInterfaceTable>(par("interfaceTableModule"), this);
event = new cMessage("event");
broadcastDelay = &par("broadcastDelay");
helloInterval = par("helloInterval");
localPort = par("localPort");
destPort = par("destPort");
packetName = par("packetName");
startTime = par("startTime");
stopTime = par("stopTime");
}
else if (stage == INITSTAGE_ROUTING_PROTOCOLS)
{
registerService(Protocol::manet, nullptr, gate("socketIn"));
registerProtocol(Protocol::manet, gate("socketOut"), nullptr);
}
}
void myApp::handleSelfMessage(cMessage *msg)
{
if (msg == event)
{
auto hello = makeShared<HelloMsg>();
Ipv4Address source = (interface80211ptr->getProtocolData<Ipv4InterfaceData>()->getIPAddress());
hello->setChunkLength(b(128));
hello->setSrcAddress(source);
sequencenumber += 2;
hello->setSequencenumber(sequencenumber);
hello->setNextAddress(source);
hello->setHopdistance(1);
auto packet = new Packet("Hello", hello);
packet->addTagIfAbsent<L3AddressReq>()->setDestAddress(Ipv4Address(255, 255, 255, 255));
packet->addTagIfAbsent<L3AddressReq>()->setSrcAddress(source);
packet->addTagIfAbsent<InterfaceReq>()->setInterfaceId(interface80211ptr->getInterfaceId());
packet->addTagIfAbsent<PacketProtocolTag>()->setProtocol(&Protocol::manet);
packet->addTagIfAbsent<DispatchProtocolReq>()->setProtocol(&Protocol::ipv4);
send(packet, "socketOut");
packet = nullptr;
hello = nullptr;
scheduleAt(simTime()+helloInterval+broadcastDelay->doubleValue(), event);
}
}
void myApp::handleMessageWhenUp(cMessage *msg)
{
if (msg->isSelfMessage())
{
handleSelfMessage(msg);
}
else if (check_and_cast<Packet *>(msg)->getTag<PacketProtocolTag>()->getProtocol() == &Protocol::manet)
{
auto recHello = staticPtrCast<HelloMsg>(check_and_cast<Packet *>(msg)->peekData<HelloMsg>()->dupShared());
if (msg->arrivedOn("socketIn"))
{
bubble("Received hello message");
Ipv4Address source = interface80211ptr->getProtocolData<Ipv4InterfaceData>()->getIPAddress();
Ipv4Address src;
unsigned int msgsequencenumber;
int numHops;
Ipv4Address next;
src = recHello->getSrcAddress();
msgsequencenumber = recHello->getSequencenumber();
next = recHello->getNextAddress();
numHops = recHello->getHopdistance();
if (src == source)
{
EV_INFO << "Hello msg dropped. This message returned to the original creator.\n";
delete msg;
return;
}
else
{
neighbors.push_back(src);
/*list<XED>::iterator findIter = find(ls.begin()->destinationAddr, ls.end()->destinationAddr, src);
if (findIter != ls.end()->destinationAddr)
{
}*/
source = (interface80211ptr->getProtocolData<Ipv4InterfaceData>()->getIPAddress());
//socket.bind(source, localPort);
auto xed = makeShared<XedMsg>();
xed->setChunkLength(b(128)); ///size of XED message in bits
xed->setSrcAddress(source);
xed->setDstAddress(src);
double random = generateRandom();
xed->setRandom(random);
//XED item = XED(source, src, random);
//ls.push_back(item);
auto packet = new Packet("XED", xed);
packet->addTagIfAbsent<L3AddressReq>()->setDestAddress(src);
packet->addTagIfAbsent<L3AddressReq>()->setSrcAddress(source);
packet->addTagIfAbsent<InterfaceReq>()->setInterfaceId(interfaceId);
packet->addTagIfAbsent<PacketProtocolTag>()->setProtocol(&Protocol::ipv4);
packet->addTagIfAbsent<DispatchProtocolReq>()->setProtocol(&Protocol::ipv4);
socket.setOutputGate(gate("socketOut"));
socket.setCallback(this);
socket.bind(source, localPort);
//emit(packetSentSignal, packet);
socket.sendTo(packet, src, destPort);
//send(packet, "socketOut");
packet = nullptr;
xed = nullptr;
/*Ipv4Address source = (interface80211ptr->getProtocolData<Ipv4InterfaceData>()->getIPAddress());
EV << "I am node " << source << ", my neighbors are : " << endl;
list<L3Address>::iterator it;
for (it = neighbors.begin(); it != neighbors.end(); ++it)
{
EV << it. << endl;
}
for (auto const& i : neighbors)
{
EV << i.str() << endl;
}*/
EV << "I am your neighbor " << src.str();
}
delete msg;
}
else if (check_and_cast<Packet *>(msg)->getTag<PacketProtocolTag>()->getProtocol() == &Protocol::ipv4)
{
EV << "Xed message received" << endl;
//auto recXed = staticPtrCast<XedMsg>(check_and_cast<Packet *>(msg)->peekData<XedMsg>()->dupShared());
}
else
throw cRuntimeError("Message arrived on unknown gate %s", msg->getArrivalGate()->getName());
}
}
void myApp::start()
{
/*socket.setOutputGate(gate("socketOut"));
socket.setCallback(this);*/
int num_80211 = 0;
InterfaceEntry *ie;
InterfaceEntry *i_face;
const char *name;
for (int i = 0; i < ift->getNumInterfaces(); i++)
{
ie = ift->getInterface(i);
name = ie->getInterfaceName();
if (strstr(name, "wlan") != nullptr)
{
i_face = ie;
num_80211++;
interfaceId = i;
}
}
if (num_80211 == 1)
{
interface80211ptr = i_face;
interfaceId = interface80211ptr->getInterfaceId();
}
else
throw cRuntimeError("Node has found %i 80211 interfaces", num_80211);
scheduleAt(simTime() + uniform(0.0, par("maxVariance").doubleValue()), event);
}
double myApp::generateRandom()
{
double lower_bound = 10000;
double upper_bound = 100000;
uniform_real_distribution<double> unif(lower_bound,upper_bound);
default_random_engine re;
double a_random_double = unif(re);
return a_random_double;
}
void myApp::stop()
{
cancelEvent(event);
socket.close();
delayActiveOperationFinish(par("stopOperationTimeout"));
}
void myApp::socketDataArrived(UdpSocket *socket, Packet *packet)
{
emit(packetReceivedSignal, packet);
EV_INFO << "Received packet: " << UdpSocket::getReceivedPacketInfo(packet) << endl;
}
void myApp::socketErrorArrived(UdpSocket *socket, Indication *indication)
{
EV_WARN << "Ignoring UDP error report " << indication->getName() << endl;
delete indication;
}
void myApp::socketClosed(UdpSocket *socket)
{
if (operationalState == State::STOPPING_OPERATION)
startActiveOperationExtraTimeOrFinish(par("stopOperationExtraTime"));
}
Error: NED type 'myApp' could not be fully resolved due to a missing base type or interface, at /home/bocuhra/Downloads/omnetpp-5.4.1/samples/SaaS/myApp.ned:18
myApp.cc
HelloMsg_m.cc
XedMsg_m.cc
Creating executable: out/gcc-release//SaaS
/usr/bin/ld: cannot find -lINET
collect2: error: ld returned 1 exit status
Makefile:104: recipe for target 'out/gcc-release//SaaS' failed
make: *** [out/gcc-release//SaaS] Error 1
I did solve the problem by adding all ned files in my .ini file.
ned-path = .;../inet/src/inet
I'm completely new developing in LINUX kernel, and I'm having some problems in a new LINUX driver I'm developing.
After I map NXP PWM registers using ioremap()/ioremap_nocache() and then I try to write to the register mappend my system hags/freeze.
Could you please help me understanding what it is happening?
My Driver is this:
#include <linux/device.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kthread.h> // for threads
#include <linux/fs.h>
#include <linux/sched.h> // for task_struct
#include <linux/delay.h> // for ndelay
#include <linux/uaccess.h> // Required for the copy to user function
#include <asm/io.h> // for ioremap()
#include <linux/interrupt.h>
#include <linux/gpio.h>
#define MX3_PWMCR_PRESCALER(x) ((((x) - 1) & 0xFFF) << 4)
#define DEVICE_NAME "pwm_cus_drv"
#define CLASS_NAME "pwm_custom_driver"
static volatile void __iomem *mmio_pwm1_base = NULL;
static volatile void __iomem *mmio_pwm2_base = NULL;
static int majorNumber;
static struct class* vfd_char_dev_class = NULL;
static struct device* vfd_char_dev = NULL;
static struct device_driver vfd_driver;
static int dev_open(struct inode *inodep, struct file *file_ptr);
static int dev_release(struct inode *inodep, struct file *file_ptr);
static ssize_t dev_read(struct file *file_ptr, char *buffer, size_t len, loff_t *offset);
static ssize_t dev_write(struct file *file_ptr, char *buffer, size_t len, loff_t *offset);
static long dev_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg);
static irqreturn_t pwm_imx_futaba_isr(int irq, void *dev_id);
static bool Initialize_PWM_Signals(void);
static void pwm_init(void);
/**
* ISR used to attend PWM rising edge interrupt activation.
*/
irqreturn_t pwm_imx_futaba_isr(int irq, void *dev_id)
{
if(NULL != mmio_pwm1_base)
{
writel(0x00000078, mmio_pwm1_base + 0x04);
gpio_set_value(47, 1);
gpio_set_value(47, 0);
}
return IRQ_HANDLED;
}
/**
*
*/
bool Initialize_PWM_Signals(void)
{
u32 cs_pin_dir_value = 0;
u32 cs_pin_out_value = 0;
u32 duty_cycles = 0;
u32 period_cycles = 0;
u32 cr_1 = 0;
u32 cr_2 = 0;
pwm_init();
period_cycles = ((24000000)/(4000)) - 2; /* 4 KHz */
duty_cycles = period_cycles / 2; /* duty = 50% */
printk(KERN_NOTICE "PWM data. PERIOD[%d] DUTY[%d]\n", period_cycles, duty_cycles);
cr_1 = MX3_PWMCR_PRESCALER(1) | (1 << 24) | (1 << 23) | (2 << 16);
cr_2 = MX3_PWMCR_PRESCALER(1) | (1 << 24) | (1 << 23) | (2 << 16);
printk(KERN_NOTICE "Disabling IMX6UL PWMs \n");
/*******************************/
/* AFTER THIS, THE KERNEL HANGS*/
/*******************************/
writel(cr_1, mmio_pwm1_base + 0x00);
writel(cr_2, mmio_pwm2_base + 0x00);
printk(KERN_NOTICE "PWMs disabled\n");
if (1)
{
/* Configure IMX6UL PWM1 */
printk(KERN_NOTICE " Configuring PWM1 \n");
writel(duty_cycles, mmio_pwm1_base + 0x0C);
writel(period_cycles, mmio_pwm1_base + 0x10);
/* Configure IMX6UL PWM2 */
printk(KERN_NOTICE " Configuring PWM2 \n");
writel(duty_cycles, mmio_pwm2_base + 0x0C);
writel(period_cycles, mmio_pwm2_base + 0x10);
cr_1 |= (1 << 0);
cr_2 |= (1 << 0);
printk(KERN_NOTICE "Enabling IRQs !!\n");
writel(0x00000002, mmio_pwm1_base + 0x08);
/* Enabling IMX6UL PWMs */
printk(KERN_NOTICE " Enabling PWMs \n");
writel(cr_1, mmio_pwm1_base + 0x00);
writel(cr_2, mmio_pwm2_base + 0x00);
}
return 0;
}
/**
*
*/
int dev_open(struct inode *inodep, struct file *file_ptr)
{
printk(KERN_NOTICE "\n[%s]\n", __func__);
Initialize_PWM_Signals();
printk(KERN_NOTICE "[%s] Driver initialized \n", __func__);
}
/**
*
*/
int dev_release(struct inode *inodep, struct file *file_ptr)
{
printk(KERN_NOTICE "\n[%s]\n", __func__);
}
/**
*
*/
ssize_t dev_read(struct file *file_ptr, char *buffer, size_t len, loff_t *offset)
{
printk(KERN_NOTICE "\n[%s]\n", __func__);
}
/**
*
*/
ssize_t dev_write(struct file *file_ptr, char *buffer, size_t len, loff_t *offset)
{
printk(KERN_NOTICE "\n[%s]\n", __func__);
}
/**
*
*/
long dev_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
{
printk(KERN_NOTICE "\n[%s]\n", __func__);
}
/**
*
*/
void pwm_init(void)
{
printk(KERN_ALERT "[%s]\n", __func__);
if(NULL != request_mem_region(0x2080000, 0x4000, DEVICE_NAME))
{
mmio_pwm1_base = ioremap_nocache(0x2080000, 0x4000);
if(IS_ERR(mmio_pwm1_base))
{
printk(KERN_NOTICE "Failed to map memory 1\n");
}
}
else
{
printk(KERN_NOTICE "Failed to map memory 2\n");
}
if(NULL != request_mem_region(0x2084000, 0x4000, DEVICE_NAME))
{
mmio_pwm2_base = ioremap_nocache(0x2084000, 0x4000);
if(IS_ERR(mmio_pwm2_base))
{
printk(KERN_NOTICE "Failed to map memory 3\n");
}
}
else
{
printk(KERN_NOTICE "Failed to map memory 4\n");
}
printk(KERN_NOTICE "PWMs memory mapped \n");
}
static const struct file_operations fops =
{
.owner = THIS_MODULE,
.open = dev_open,
.read = dev_read,
.write = dev_write,
.release = dev_release,
.unlocked_ioctl = dev_ioctl,
.compat_ioctl = dev_ioctl,
};
struct bus_type futaba_bus_type =
{
.name = DEVICE_NAME,
};
static int pwm_driver_init(void)
{
unsigned irqflags = 0;
unsigned ret = 0;
const char *dev_name = "pwm1_irq";
u32 pwm_irq = 25;
majorNumber = register_chrdev(0, DEVICE_NAME, &fops);
if (majorNumber < 0)
{
printk(KERN_NOTICE "EBBChar failed to register a major number\n");
return majorNumber;
}
vfd_char_dev_class = class_create(THIS_MODULE, CLASS_NAME);
if (IS_ERR(vfd_char_dev_class))
{
unregister_chrdev(majorNumber, DEVICE_NAME);
printk(KERN_NOTICE "Failed to register device class\n");
return PTR_ERR(vfd_char_dev_class);
}
vfd_char_dev = device_create(vfd_char_dev_class, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME);
if (IS_ERR(vfd_char_dev))
{
class_destroy(vfd_char_dev_class);
unregister_chrdev(majorNumber, DEVICE_NAME);
printk(KERN_ALERT "Failed to create the device\n");
return PTR_ERR(vfd_char_dev);
}
ret = request_irq(pwm_irq, pwm_imx_futaba_isr, irqflags, dev_name, DEVICE_NAME);
if (0 != ret)
{
printk(KERN_NOTICE "can't get irq: %d\n", ret);
}
return 0;
}
static void pwm_driver_exit(void)
{
device_destroy(vfd_char_dev_class, MKDEV(majorNumber, 0));
class_unregister(vfd_char_dev_class);
class_destroy(vfd_char_dev_class);
unregister_chrdev(majorNumber, DEVICE_NAME);
iounmap(mmio_pwm1_base);
iounmap(mmio_pwm2_base);
}
module_init(pwm_driver_init);
module_exit(pwm_driver_exit);
MODULE_AUTHOR("New Drivers developer");
MODULE_DESCRIPTION(" PWM Handler ");
MODULE_LICENSE("GPL");
Thanks for all your answers. I solved this issue after using some NXP recommendations. At the end the problem was caused due to the IPG/PER clocks were not enabled. According NXP, clocks shall be enabled first before starting to modify registers associated with the module(in my case for PWM).
Typical reason of hang at register access is that hardware module owning the register is either powered down, or not clocked.
Per imx6ul device tree from mainline kernel (arch/arm/boot/dts/imx6ul.dtsi), there are clocks to enable:
pwm1: pwm#2080000 {
compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm";
reg = <0x02080000 0x4000>;
interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_PWM1>,
<&clks IMX6UL_CLK_PWM1>;
clock-names = "ipg", "per";
#pwm-cells = <2>;
status = "disabled";
};
By the way, driver for this module is available, drivers/pwm/pwm-imx.c
Note: I will first spit out specifically my issue and then I will explain better my scenario.
On my windows, using my intel driver. I can compile these two (respectively vertex and fragment shader), but can not link them:
attribute vec4 vertex;
void main(void) {
gl_Position = vertex;
}
,
uniform sampler2D textures[2];
vec4 third(sampler2D texture) {
return texture2D(texture,vec2(0.5,0.5));
}
vec4 second(float a) {
return third(textures[0]);
}
void main(void) {
gl_FragColor = second(0.0);
}
I get an error on the linking (the link status is false) but the info log is empty.
The thing is that this shader works fine in my Linux with the same GPU and works fine in my NVIDIA. Only in windows using the Intel driver I get this problem. My OpenGL informs the following about the driver:
GL_VENDOR Intel
GL_RENDERER Intel(R) HD Graphics Family
GL_VERSION 3.0.0 - Build 8.15.10.2253
GL_SHADING_LANGUAGE_VERSION 1.30 - Intel Build 8.15.10.2253
Funny thing is that modifications that seems irrelevant makes the program to link correctly, I found a few so far:
If the second function does not receive any parameter, it works.
If main() calls third directly, it works.
If the uniform is not a array, it is a single element, it works.
If instead of passing the sampler2D from second to third, I pass an index that third will use to access textures, it works.
My question is how to make it work but keeping the same semantics? I need three functions, I needed that the third and the main function do not use the uniform, I need that only the second function knows the uniforms. Also, I need that the second and third function receives parameters. In my real world scenario the second and the third functions does a lot of things with the values it received.
And just for clarification, what I am doing that needs this:
In the framework that I am developing, there are three different fragment shaders being used. The first one (main in my reference code), is the one that the user provides, this one may call functions (second in my reference code) that are defined in the framework. The third level is also user provided but the shader is only compiled once and does not know how many times it will be used and it which values, the second is the responsible for allocating the right number of buffers and calling the third for each.
Here is the code that I used to test the shaders:
#include <SDL.h>
#include <GL/glew.h>
#include <iostream>
#include <vector>
#include <cassert>
#include <sstream>
#include <stdexcept>
#define WIDTH 800
#define HEIGHT 640
void warn(const std::exception& e) {
#ifndef NDEBUG
std::cerr << "Warning: " << e.what() << std::endl;
#endif
};
namespace {
std::string tostr(unsigned a) {
std::stringstream ss;
ss << a;
return ss.str();
}
std::string errorname(unsigned a) {
switch(a) {
case GL_NO_ERROR: return "GL_NO_ERROR";
case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
case GL_INVALID_VALUE: return "GL_INVALID_VALUE";
case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION";
case GL_INVALID_FRAMEBUFFER_OPERATION: return "GL_INVALID_FRAMEBUFFER_OPERATION";
case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY";
}
return "";
}
}
void checkGlErrorImpl(unsigned line, const char* file) {
GLenum curerr = glGetError();
if( curerr == GL_NO_ERROR )
return;
auto err = std::runtime_error(std::string("OpenGL ")+errorname(curerr)+" error on "+file+":"+tostr(line));
warn(err);
throw err;
}
#define checkGlError() checkGlErrorImpl(__LINE__,__FILE__)
int create_shader(unsigned type, const char* shaderSource) {
unsigned id = glCreateShader(type);
const char* shaderSources[2] = {"#version 130\n",shaderSource};
glShaderSource(id,2,shaderSources,NULL);
glCompileShader(id);
GLint compileStatus;
glGetShaderiv(id, GL_COMPILE_STATUS, &compileStatus);
int msgLength;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &msgLength);
char* msg = new char[msgLength];
glGetShaderInfoLog(id, msgLength, &msgLength, msg);
std::cout << "(" << id << ") " << msg << std::endl;
std::runtime_error except(std::string("Error on compiling shader:\n")+msg);
delete[] msg;
if( compileStatus == GL_FALSE ) {
warn(except);
throw except;
}
checkGlError();
return id;
};
int create_program(const std::vector<int>& shaders) {
int id = glCreateProgram();
checkGlError();
for( unsigned int i=0; i< shaders.size(); ++i ) {
glAttachShader(id,shaders[i]);
}
glLinkProgram(id);
GLint linkStatus=-1;
glGetProgramiv(id, GL_LINK_STATUS, &linkStatus);
assert(linkStatus != -1);
checkGlError();
if( linkStatus == GL_FALSE ) {
int msgLength=-1;
glGetProgramiv(id, GL_INFO_LOG_LENGTH, &msgLength);
assert( msgLength != -1 );
char* msg = new char[msgLength+1];
msg[0] = '\0';
std::cout << "Buffer(" << msgLength+1 << ")" << msg << std::endl;
glGetProgramInfoLog(id, msgLength+1, &msgLength, msg);
std::cout << "Second length " << msgLength << std::endl;
std::cout << "Log " << msg << std::endl;
std::string errormsg("Error on linking shader: ");
errormsg += msg;
// delete[] msg;
auto err = std::runtime_error(errormsg);
warn(err);
throw err;
}
checkGlError();
return id;
}
int main(int argc, char** argv) {
if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
throw __LINE__;
}
int video_flags;
video_flags = SDL_OPENGL;
video_flags |= SDL_GL_DOUBLEBUFFER;
video_flags |= SDL_HWSURFACE;
video_flags |= SDL_HWACCEL;
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
SDL_Surface* surface = SDL_SetVideoMode( WIDTH, HEIGHT, 24, video_flags );
if( surface == NULL )
throw __LINE__;
unsigned width = WIDTH;
unsigned height = HEIGHT;
GLenum err = glewInit();
if (GLEW_OK != err) {
std::cerr << "Error: " << glewGetErrorString(err) << std::endl;
throw __LINE__;
}
std::vector<int> shaders;
shaders.push_back( create_shader(GL_VERTEX_SHADER,
"attribute vec4 vertex;\n"
"void main(void) {\n"
" gl_Position = vertex;\n"
"}\n"
));
shaders.push_back( create_shader(GL_FRAGMENT_SHADER,
"uniform sampler2D textures[2];\n"
"vec4 third(sampler2D texture) {\n"
" return texture2D(texture,vec2(0.5,0.5));\n"
"}\n"
"vec4 second(float a) {\n"
" return third(textures[0]);\n"
"}\n"
"\n"
"void main(void) {\n"
" gl_FragColor = second(0.0);\n"
"}\n"
));
int program = create_program(shaders);
try {
while( true ) {
SDL_Event event;
while( SDL_PollEvent(&event) ) {
switch( event.type ) {
case SDL_QUIT:
throw 0;
break;
}
}
SDL_Delay(10);
}
} catch( int returnal) {
return returnal;
}
return 0;
};
It depends on GLEW,SDL, OpenGL and C++11.
I'm totally new in COM programming.
I have big problem. I’m trying to handle events from CANoe application via COM Server. Firstly I tried do it in native C++ but without results. Now I’m trying it by using ATL. I'm doing something wrong but I don’t have any idea what. When the event occurs, my client application suspends itself and CANoe. After closing client application CANoe works fine. So I know that my client application handles Events from CANoe but it can’t serve it. The commented parts of code in my source code were also used but with the same results.
#import "CANoe.tlb" //importing CANoe type library
#include "stdafx.h"
#include <atlbase.h> //COM Server methods
#include <iostream>
#include <atlhost.h>
using namespace CANoe;
using namespace std;
_ATL_FUNC_INFO infoZero = { CC_STDCALL, VT_EMPTY, 0, 0};
_ATL_FUNC_INFO infoOne = { CC_STDCALL, VT_EMPTY, 1, { VT_I4 } };
class CANoeComClient :
//IDispEventSimpleImpl<1, CANoeComClient, &__uuidof(_IMeasurementEvents)>,
//IDispEventSimpleImpl<2, CANoeComClient, &__uuidof(_IEnvironmentVariableEvents)>
IDispEventSimpleImpl<1, CANoeComClient, &__uuidof(_IApplicationEvents)>
{
IApplicationPtr pApp; //Pointer to the Application Object
IMeasurementPtr pMeasure; //Pointer to the Measurement object
_IMeasurementEventsPtr pMEvent; //Pointer to the Measurement's Events
IEnvironmentPtr pEnvironment; //Pointer to the Environment Object
IEnvironmentVariable2Ptr pEnvironmentVar; //Pointer to the Environment Variable Object
ICAPL2Ptr pCAPL; //Pointer to the CAPL Object
CLSID clsid; //globally unique identifier that identifies a COM class object
HRESULT result; //results of COM functions
public:
//typedef IDispEventSimpleImpl<2, CANoeComClient, &__uuidof(CANoe::_IEnvironmentVariableEvents)> EnvVarEventsHandler;
//typedef IDispEventSimpleImpl<1, CANoeComClient, &__uuidof(CANoe::_IMeasurementEvents)> MeasurementEventsHandler;
typedef IDispEventSimpleImpl<1, CANoeComClient, &__uuidof(CANoe::_IApplicationEvents)> ApplicationEventsHandler;
void __stdcall OnStart(void);
void __stdcall OnStop(void);
void __stdcall OnOpen(void);
void __stdcall OnQuit(void);
BEGIN_SINK_MAP(CANoeComClient)
//SINK_ENTRY_INFO(1, __uuidof(CANoe::_IMeasurementEvents), 0x02, OnStart, &info)
//SINK_ENTRY_INFO(1, __uuidof(CANoe::_IMeasurementEvents), 0x03, OnStop, &infoZero)
SINK_ENTRY_INFO(1, __uuidof(CANoe::_IApplicationEvents), 0x01, OnOpen, &infoZero)
SINK_ENTRY_INFO(1, __uuidof(CANoe::_IApplicationEvents), 0x02, OnQuit, &infoZero)
END_SINK_MAP()
void __stdcall OnChange();
/*
BEGIN_SINK_MAP(CANoeComClient)
SINK_ENTRY_INFO(2, __uuidof(CANoe::_IEnvironmentVariableEvents), 0x01, OnChange, &info)
END_SINK_MAP()*/
CANoeComClient(_bstr_t configPath);
HRESULT createEventConnection();
HRESULT startMeasurement();
HRESULT stopMeasurement();
};
void CANoeComClient::OnStart()
{
cout << "kurka wodna 1" << endl;
}
void CANoeComClient::OnStop()
{
cout << "kurka wodna 2" << endl;
}
void CANoeComClient::OnChange()
{
cout << "kurka wodna 2" << endl;
}
void CANoeComClient::OnOpen()
{
cout << "kurka wodna 1" << endl;
}
void CANoeComClient::OnQuit()
{
cout << "kurka wodna 1" << endl;
}
CANoeComClient::CANoeComClient(_bstr_t configPath)
{
/* Initialization COM library: */
if (FAILED(CoInitialize(NULL)))
{
cerr << "Initialization COM Library error" << endl;
system("pause");
return;
}
/* Actualization clsid variable with CANoe.Application path: */
if((result = CLSIDFromProgID(L"CANoe.Application", &clsid)) != S_OK)
{
cerr << "Problem with opening application" << endl;
system("pause");
return;
}
/*Opening CANoe application: */
result = pApp.CreateInstance(__uuidof(CANoe::Application));
if(result != S_OK)
{
cerr << "pApp fault" << endl;
return;
}
else
cout << "CANoe opened succesfully" << endl;
/* Opening CANoe configuration: */
result = pApp->Open(configPath, FALSE, TRUE); //Opening test.cfg file
if(result != S_OK)
{
cerr << "Opening configuration fault" << endl;
return;
}
else
cout << "Configuration loaded succesfully" << endl;
/*Definitions of all objects: */
//pMeasure.CreateInstance(__uuidof(CANoe::Measurement));
pEnvironment = pApp->Environment;
pEnvironmentVar = pEnvironment->GetVariable(L"env_ClientReq");
pCAPL = pApp->CAPL;
result = ApplicationEventsHandler::DispEventAdvise(pApp);
// result = MeasurementEventsHandler::DispEventAdvise(pMeasure);
//result = EnvVarEventsHandler::DispEventAdvise(pEnvironmentVar);
if(result != S_OK)
{
cerr << "Creating connection fault" << endl;
return;
}
else
cout << "Creating conenction succesfully" << endl;
}
HRESULT CANoeComClient::startMeasurement()
{
return pMeasure->Start();
}
HRESULT CANoeComClient::stopMeasurement()
{
return pMeasure->Stop();
}
int _tmain(int argc, _TCHAR* argv[])
{
int tmp = 0; //temporary variable to used to get envVar values
HRESULT result; //results of COM functions
CANoeComClient client(L"C:\\test\\test.cfg");
while(1);
}
Here is description of Measurement Object and Event from OLE-COM object viewer:
[
uuid(CD866FB6-44BF-11D3-8538-00105A3E017B),
helpstring("Measurement Class")
]
coclass Measurement {
[default] interface IMeasurement2;
[default, source] dispinterface _IMeasurementEvents;
};
[
odl,
uuid(A844C1E0-F5CE-11D3-8612-00105A3E017B),
helpstring("IMeasurement2 Interface"),
dual,
oleautomation
]
interface IMeasurement2 : IMeasurement {
[id(0x0000000a), propget, helpstring("property Running")]
HRESULT Running([out, retval] VARIANT_BOOL* pVal);
};
[
uuid(A844C1E0-F5CE-11D3-8612-00105A3E017B),
helpstring("IMeasurement2 Interface"),
dual
]
dispinterface IMeasurement2 {
properties:
methods:
[id(0x00000001), propget, helpstring("property Application")]
IDispatch* Application();
[id(0x00000002), propget, helpstring("property Parent")]
IDispatch* Parent();
[id(0x00000003), helpstring("method Start")]
void Start();
[id(0x00000004), helpstring("method Stop")]
void Stop();
[id(0x00000005), helpstring("method Step")]
void Step();
[id(0x00000006), helpstring("method Animate")]
void Animate();
[id(0x00000007), helpstring("method Break")]
void Break();
[id(0x00000008), helpstring("method Reset")]
void Reset();
[id(0x00000009), propget, helpstring("property AnimationDelay")]
long AnimationDelay();
[id(0x00000009), propput, helpstring("property AnimationDelay")]
void AnimationDelay([in] long rhs);
[id(0x0000000a), propget, helpstring("property Running")]
VARIANT_BOOL Running();
};
[
uuid(CD866FB7-44BF-11D3-8538-00105A3E017B),
helpstring("_IMeasurementEvents Interface")
]
dispinterface _IMeasurementEvents {
properties:
methods:
[id(0x00000001), helpstring("method OnInit")]
HRESULT OnInit();
[id(0x00000002), helpstring("method OnStart")]
HRESULT OnStart();
[id(0x00000003), helpstring("method OnStop")]
HRESULT OnStop();
[id(0x00000004), helpstring("method OnExit")]
HRESULT OnExit();
};
I attach CANoe.tlb: http://www.sendspace.com/file/j2zloj
Thank you for your attention
Damian
You are initializing STA and you're doing while(1);, however note that you are expected to implement a message pump on the thread (hint: a quick check if this is the reason is to show a message box instead of endless loop)
Why SINK_ENTRY_INFO and not SINK_ENTRY as any tutorial would suggest?
Did you have a chance to see if the event handler is executed, and it reached pMeasure-> call there; did you check if it freezes inside this call, or it returns a failure result (or the event handler is called on wrong thread).
As console application has no Window (which handles events queue used by STA), you have either to call
CoInitializeEx(NULL,COINIT_MULTITHREADED);
to use MTA instead of STA
or implement Message pump
MSG msg;
while(GetMessage(&msg,0,0,0))
DispatchMessage(&msg);
I also had to add following code to stdafx.h to prevent crash in ATL classes:
class CDummyModule : public CAtlExeModuleT<CDummyModule> {};
CDummyModule _Module;