Are the interrupts in Linux queued - linux

I wrote a sample driver which disables keyboard interrupt for few seconds, and when i press keys at that duration, i get the pressed keys on the console when the interrupt is enabled?
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/irqflags.h>
#include <linux/interrupt.h>
unsigned int irq = 1;
module_param(irq, int, 0);
static int __init my_init(void)
{
pr_info("module is loaded on processor:%d\n", smp_processor_id());
pr_info("Disabling Interrupt:%u\n", irq);
disable_irq(irq);
pr_info("Disabled Interrupt:%u\n", irq);
mdelay(10000L);
pr_info("Enabling Interrupt:%u\n", irq);
enable_irq(irq);
pr_info("Enabled Interrupt:%u\n", irq);
return 0;
}
static void __exit my_exit(void)
{
}
MODULE_LICENSE("GPL");
module_init(my_init);
module_exit(my_exit);

Related

Crash system when the module is running

I need to write a module that creates a file and outputs an inscription with a certain frequency. I implemented it. But when this module is running, at some point the system crashes and no longer turns on.
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/kernel.h>
#include <linux/timer.h>
MODULE_LICENSE("GPL");
#define BUF_LEN 255
#define TEXT "Hello from kernel mod\n"
int g_timer_interval = 10000;
static struct file *i_fp;
struct timer_list g_timer;
loff_t offset = 0;
char buff[BUF_LEN + 1] = TEXT;
void timer_rest(struct timer_list *timer)
{
mod_timer(&g_timer, jiffies + msecs_to_jiffies(g_timer_interval));
i_fp = filp_open("/home/hajol/Test.txt", O_RDWR | O_CREAT, 0644);
kernel_write(i_fp, buff, strlen(buff), &offset);
filp_close(i_fp, NULL);
}
static int __init kernel_init(void)
{
timer_setup(&g_timer, timer_rest, 0);
mod_timer(&g_timer, jiffies + msecs_to_jiffies(g_timer_interval));
return 0;
}
static void __exit kernel_exit(void)
{
pr_info("Ending");
del_timer(&g_timer);
}
module_init(kernel_init);
module_exit(kernel_exit);
When the system crashes, you should get a very detailed error message from the kernel, letting you know where and why this happened (the "oops" message):
Read that error message
Read it again
Understand what it means (this often requires starting over from step 1 a couple of times :-) )
One thing that jumps out at me is that you're not going any error checking on the return value of filp_open. So you could very well be feeding a NULL pointer (or error pointer) into kernel_write.

Qt serial communication using UART RS232C

I want to connect qt and a device using UART cable (RS232C) in linux.
I´m writing code, making ui and operating, but it does not work.
I want to connect when i click some button(ui) device turn on and connect.
Also i want to make a function that if i enter some command device will recognize and execute.
Below is my code , someone help me please.
<mainwindow.cpp>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtSerialPort/QSerialPort>
#include <QMessageBox>
#include <QObject>
#include <QIODevice>
#include <QDebug>
QSerialPort serial;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
QSerialPort*port=new QSerialPort();
port->setPortName("/dev/ttyUSB0");
port->setBaudRate(QSerialPort::Baud19200);
port->setDataBits(QSerialPort::Data8);
port->setParity(QSerialPort::NoParity);
port->setStopBits(QSerialPort::OneStop);
port->setFlowControl(QSerialPort::NoFlowControl);
port->open(QIODevice::ReadWrite);
ui->setupUi(this);
serial = new QSerialPort(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_connect_clicked()
{
port=new QSerialPort();
QObject::connect(port,SIGNAL(readyRead()),this,
SLOT(on_pushButton_connect_clicked()));
if(!port->open(QIODevice::ReadWrite)){
QMessageBox::information(this, tr("connect"),
"serialcommunication start");
}
else
{
QMessageBox::critical(this, tr("fail"), serial-
>errorString());
}
}
void MainWindow::on_pushButton_disconnect_clicked()
{
port->close();
QMessageBox::information(this, tr("disconnect"), "serial
communication end");
}
<mainwindow.h>
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtSerialPort/QSerialPort>
#include <QMessageBox>
#include <QIODevice>
#include <QDebug>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
QSerialPort*serial; //plus
QSerialPort*port;
QWidget*main_widget;
void readData();
~MainWindow();
private slots:
void on_pushButton_connect_clicked();
void on_pushButton_disconnect_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
<main.cpp>
#include "mainwindow.h"
#include <QApplication>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QDebug>
#include <QMessageBox>
#include <QIODevice>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
foreach(const QSerialPortInfo
&info,QSerialPortInfo::availablePorts()){
QSerialPort serial;
serial.setPort(info);
if (serial.open(QIODevice::ReadWrite))
serial.close();
}
MainWindow w;
w.show();
return a.exec();
}
First of all it is not guaranteed that your device will be always connected to /dev/ttyUSB0 so you'l better search for your device by QSerialPortInfo with parameter
QString manufacturer() const or quint16 productIdentifier() const or QString serialNumber() const.
Also you are creating too many QSerialPort and don't handle it. Create just one.
Here is sample code:
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class QSerialPort;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
//! Receives all the data from serial port
void readSerialData();
void on_pushButton_connect_clicked();
void on_pushButton_disconnect_clicked();
private:
Ui::MainWindow *ui;
QSerialPort *mSerialPort;
};
#endif // MAINWINDOW_H
Next check your Your product manufacturer or serial number and set here.
Also you need separate handler for received data like I created readSerialData
mainwindows.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QMessageBox>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
mSerialPort{new QSerialPort}
{
ui->setupUi(this);
mSerialPort->setBaudRate(QSerialPort::Baud19200);
mSerialPort->setDataBits(QSerialPort::Data8);
mSerialPort->setParity(QSerialPort::NoParity);
mSerialPort->setStopBits(QSerialPort::OneStop);
mSerialPort->setFlowControl(QSerialPort::NoFlowControl);
connect(mSerialPort, SIGNAL(readyRead()), this, SLOT(readSerialData()));
}
MainWindow::~MainWindow()
{
delete mSerialPort;
delete ui;
}
void MainWindow::readSerialData()
{
QByteArray lTmpBA;
lTmpBA = mSerialPort->readAll();
qDebug() << "Received data: " << lTmpBA;
}
void MainWindow::on_pushButton_connect_clicked()
{
foreach(QSerialPortInfo item, QSerialPortInfo::availablePorts()) {
if (item.manufacturer() == "Your product") { //past your manufacturer here
mSerialPort->setPort(item);
if(!mSerialPort->open(QIODevice::ReadWrite)){
QMessageBox::information(this, tr("connect"),
"serialcommunication start");
} else {
QMessageBox::critical(this, tr("fail"), mSerialPort->errorString());
}
} else {
qDebug() << "No connected device found";
}
}
}
void MainWindow::on_pushButton_disconnect_clicked()
{
mSerialPort->close();
}
latter if you want to send some data to your UART device just implemente slot and call method:
mSerialPort->write("Some command");

setsockopt IPT_SO_SET_REPLACE flag return error (linux)

I try to use setsockopt with the flag IPT_SO_SET_REPLACE but i keep getting the wired error from errno Protocol not available this is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sched.h>
#include <linux/sched.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <netinet/in.h>
#include <net/if.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <fcntl.h>
int main(void) {
int sock;
int ret;
void *data;
size_t size;
struct ipt_replace *repl;
sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
if (sock == -1) {
perror("socket");
return -1;
}
size = sizeof(struct ipt_replace);
data = malloc(size); Protocol not available
if (data == NULL) {
perror("malloc");
return -1;
}
memset(data, 0, size);
repl = (struct ipt_replace *) data;
repl->num_counters = 0x1;
repl->size = 0xffffffff;
repl->valid_hooks = 0x1;
repl->num_entries = 0x1;
ret = setsockopt(sock, SOL_IP, IPT_SO_SET_REPLACE, (void *) data, size);
printf("\ndone %d\n", ret);
perror("error: ");
return 0;
}
this is the output :
sock:3
data:
size:92
done -1
error: : Protocol not available
Looking briefly at the kernel code, this would seem to indicate that the IP tables module isn't available (i.e. the kernel wasn't built with it configured, or it can't be found or loaded).
It appears to me that for a socket of the kind you created, the code flow is:
enter raw_setsockopt: level != SOL_RAW so...
call ip_setsockopt: level == SOL_IP but option isn't any of the IP_xxx options so...
call nf_setsockopt: Search loaded netfilter modules for one that has registered IPT_SO_SET_REPLACE.
I think the last must have failed, so you get ENOPROTOOPT back (== Protocol not available)

How does ptrace work with 2 different processes?

I was reading about ptrace on the net and found that a process can request to trace another process by using PTRACE_ATTACH but apparently all the examples available involve the use of fork().
What I want is to have 2 programs - prg1.c and prg2.c where prg2.c should trace prg1.c. I tried using PTRACE_ATTACH in prg2.c but it seems that the call failed - prg2.c couldn't trace prg1.c . How does ptrace work ? Can anybody explain ?
Code for prg1.c :
#include <stdio.h>
#include <sys/ptrace.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
printf("Hello world\n");
sleep(20);
execl("/bin/ls", "ls", NULL);
return 0;
}
Code for prg2.c :
#include <stdio.h>
#include <sys/ptrace.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc , char **argv)
{
int pid = atoi(argv[1]);
int status;
if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) {
printf("ptrace attach failed!");
return 0;
}
wait(&status);
sleep(5);
ptrace(PTRACE_DETACH, pid, NULL, NULL);
return 0;
}
I have included a sleep() to get the pid of prg1's executable(during that time) using ps -af and give it as an input to the executable of prg2.

Sending structure through sockets in Qt

I am writing a client server application to transfer data in linux platform. I am developing a GUI application for client side in QT.I am just a beginner in QT and please help in transferring a structure from server side to client side.
The server side code written for non-GUI environment
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#pragma pack(1)
struct basestruct
{
int element1;
int element2;
};
#pragma pack(0)
struct basestruct newstruct;
int main(int argc, char *argv[])
{
int listenfd = 0, connfd = 0,n=0;
struct sockaddr_in serv_addr;
char sendBuff[1025];
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listenfd, 10);
while(1)
{
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
newstruct.element1=1;
newstruct.element2=2;
if((n=send(connfd,(void *)&newstruct,sizeof(struct basestruct),0))<0)
perror("Write error");
printf("sent items :%d \n",n);
close(connfd);
sleep(1);
}}`
The client side code written in QT
#include "dialog.h"
#include "ui_dialog.h"
#include <QString>
#include <QDebug>
#include <QTextStream>
#include <QByteRef>
struct basestruct
{
int element1;
int element2;
};
basestruct newstruct;
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
ui->pushButton->setText("Connect");
ui->pushButton_2->setText("Ok");
ui->pushButton_3->setText("Close");
ui->pushButton_4->setText("Disconnect");
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::Read()
{
socket->waitForReadyRead(-1);
QByteArray byteArray;
byteArray=socket->readAll();
deserialize(byteArray);
qDebug()<<socket->readAll();
qDebug()<<"Read contents";
socket->flush();
}
void Dialog::on_pushButton_clicked()
{
socket=new QTcpSocket(this);
socket->connectToHost("127.0.0.1",5000);
qDebug()<<"Connected";
Read();
}
void Dialog::on_pushButton_4_clicked()
{
socket->close();
qDebug()<<"Disconnected";
}
void Dialog::deserialize(const QByteArray& byteArray)
{
QDataStream stream(byteArray);
stream.setVersion(QDataStream::Qt_4_0);
qDebug()<<"size received" <<byteArray.size();
stream >> newstruct.element1
>> newstruct.element2;
qDebug()<<"Element1"<<newstruct.element1<<"Element2"<<newstruct.element2;
}
When I receive the structure and print using qDebug() I am getting some garbage values. Kindly help me and point where I have gone wrong.Is there any easy alternative method to transfer structure in QT without serialising (similar to Non-GUI applications).
Thanks in advance
The Endianness problem can be overcome by specifying the Endianess as:
stream.setByteOrder(QDataStream::LittleEndian);
in the deserialise function after declaring Qdatastream.

Resources