am335x Qt SocketCAN Demo hacking
/***********************************************************************************
* am335x Qt SocketCAN Demo hacking
* 说明:
* 本源代码来自OK335xS,主要是为分析如何在Qt中使用SocketCAN的这种通信方式。
*
* 2015-9-12 晴 深圳 南山平山村 曾剑锋
**********************************************************************************/ cat main.c
#include <QtGui/QApplication>
#include "mainwindow.h"
#include "myinputpanelcontext.h" int main(int argc, char *argv[])
{
QApplication a(argc, argv);
/**
* 创建软键盘
*/
MyInputPanelContext *ic = new MyInputPanelContext;
/**
* This function replaces the QInputContext instance used by the application with inputContext.
* Qt takes ownership of the given inputContext.
*
* 设置软键盘
*/
a.setInputContext(ic); //将输入上下文与应用程序关联 MainWindow w;
/**
* Qt::WindowMaximizeButtonHint:
* Adds a maximize button. On some platforms this implies Qt::WindowSystemMenuHint for it to work.
* Qt::WindowMinimizeButtonHint:
* Adds a minimize button. On some platforms this implies Qt::WindowSystemMenuHint for it to work.
*/
w.setWindowFlags(w.windowFlags()& ~Qt::WindowMaximizeButtonHint& ~Qt::WindowMinimizeButtonHint);
w.showMaximized();
w.show(); return a.exec();
} cat mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H #include <QMainWindow>
#include <QProcess>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/can.h>
#include "thread.h"
#include <QButtonGroup> /**
* 引入界面文件生成的UI类
*/
namespace Ui {
class MainWindow;
} class MainWindow : public QMainWindow
{
Q_OBJECT public:
explicit MainWindow(QWidget *parent = );
~MainWindow();
protected:
void moveEvent(QMoveEvent *); // 界面移动事件
void resizeEvent(QResizeEvent *); // 界面重绘大小事件
void closeEvent(QCloseEvent *); // 界面关闭事件
private slots:
void on_send_clicked(); // 发送按钮点击槽
void msg(QString str); // 信息处理信号槽
void stopcan(int v); // 停止can信号槽
void startcan(int v); // 开始can信号槽
void on_can0_toggled(bool checked); // can0 被点击翻转信号槽
void on_can1_toggled(bool checked); // can1 被点击翻转信号槽 private:
Ui::MainWindow *ui; // 声明图形界面指针
int socket; // can socket 描述符
struct sockaddr_can addr; // can socket 地址结构体
Thread *t; // 线程
QButtonGroup* btg; // 按钮
}; #endif // MAINWINDOW_H cat mainwindow.c
#include <sys/ioctl.h>
#include <fcntl.h>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <unistd.h> MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), // 构造函数初始化父类构造函数
ui(new Ui::MainWindow) // 创建ui实体,并赋值
{
ui->setupUi(this); // 设置将图形界面放置在哪个对象上 btg = new QButtonGroup; // 创建分组,多选一
btg->addButton(ui->can0,);
btg->addButton(ui->can1,); startcan();
} MainWindow::~MainWindow()
{
/**
* 这里让人怀疑,都已经删除了ui界面,button group又怎么能够获取到ui里面的checkedId呢?
* 唯一的解释就是button group里面保存了最后一次toggle事件获取的checkedId值,而不是运行
* checkedId()的时候去获取checkedId
*/
delete ui;
stopcan(btg->checkedId());
} void MainWindow::msg(QString str)
{
/**
* 将获取到的信息放到显示文本框的最后去
*/
ui->label->append(str);
} void MainWindow::on_send_clicked()
{
/**
* struct can_frame - basic CAN frame structure
* @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
* @can_dlc: frame payload length in byte (0 .. 8) aka data length code
* N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1
* mapping of the 'data length code' to the real payload length
* @data: CAN frame payload (up to 8 byte)
*
* struct can_frame {
* canid_t can_id; // 32 bit CAN_ID + EFF/RTR/ERR flags
* __u8 can_dlc; // frame payload length in byte (0 .. CAN_MAX_DLEN)
* __u8 data[CAN_MAX_DLEN] __attribute__((aligned(8)));
* };
*/
struct can_frame frame;
/**
* 获取将要发送的文本内容
* Returns a std::string object with the data contained in this QString.
* The Unicode data is converted into 8-bit characters using the toUtf8() function.
*/
std::string str=ui->edit->text().toStdString(); /**
* 如果文本的长度大于8,那么将给出提示信息,并直接返回,不发送数据
*/
if(str.length() > )
{
QMessageBox::about(this,"error","length of send string must less than 8 bytes");
return;
} /**
* 默认发送的can id是0x123
*
* 扩展格式识别符由 29 位组成。其格式包含两个部分:11 位基本 ID、18 位扩展 ID。
* Controller Area Network Identifier structure:
*
* bit 0-28 : CAN识别符 (11/29 bit)
* bit 29 : 错误帧标志 (0 = data frame, 1 = error frame)
* bit 30 : 远程发送请求标志 (1 = rtr frame)
* bit 31 : 帧格式标志 (0 = standard 11 bit, 1 = extended 29 bit)
*
* typedef __u32 canid_t;
*
* struct can_frame {
* canid_t can_id; // 32 bit CAN_ID + EFF/RTR/ERR flags
* __u8 can_dlc; // 数据长度: 0 .. 8
* __u8 data[8] __attribute__((aligned(8)));
* };
*/
frame.can_id = 0x123;
/**
* Returns a pointer to an array that contains a null-terminated sequence of
* characters (i.e., a C-string) representing the current value of the string object.
* This array includes the same sequence of characters that make up the value of
* the string object plus an additional terminating null-character ('\0') at the end.
*/
strcpy((char*)frame.data, str.c_str());
/**
* 目前猜测:dlc --> data length count
* 于是可以很好的解释:can 发送的数据长度,是按字节算的
*/
frame.can_dlc = str.length(); /**
* Send N bytes of BUF on socket FD to peer at address ADDR (which is
* ADDR_LEN bytes long). Returns the number sent, or -1 for errors.
*
* This function is a cancellation point and therefore not marked with
* __THROW.
*
* extern ssize_t sendto (int __fd, __const void *__buf, size_t __n,
* int __flags, __CONST_SOCKADDR_ARG __addr,
* socklen_t __addr_len);
*/
sendto(socket,&frame,sizeof(struct can_frame),,(struct sockaddr*)&addr,sizeof(addr));
} void MainWindow::moveEvent(QMoveEvent *)
{
/**
* 让测试窗口不会被移动
*/
this->move(QPoint(,));
} void MainWindow::resizeEvent(QResizeEvent *)
{
/**
* 让窗口最大化显示
*/
this->showMaximized();
} void MainWindow::closeEvent(QCloseEvent *)
{
/**
* 直接退出,不用关闭can口么?也就是说程序会在真正推出前,先解析掉所有当前生成的类实体?
*/
exit();
} void MainWindow::startcan(int v)
{
/**
* 从提示信息可以看出,使用125000作为默认的波特率
*/
if(v == )
{
system("canconfig can0 bitrate 125000 ctrlmode triple-sampling on");
system("canconfig can0 start");
}
else
{
system("canconfig can1 bitrate 125000 ctrlmode triple-sampling on");
system("canconfig can1 start");
} /**
* Create a new socket of type TYPE in domain DOMAIN, using
* protocol PROTOCOL. If PROTOCOL is zero, one is chosen automatically.
* Returns a file descriptor for the new socket, or -1 for errors.
*
* extern int socket (int __domain, int __type, int __protocol) __THROW;
*
* #define PF_CAN 29 // Controller Area Network.
*
* SOCK_RAW = 3, // Raw protocol interface.
* #define SOCK_RAW SOCK_RAW
*
* particular protocols of the protocol family PF_CAN
* #define CAN_RAW 1 // RAW sockets
*
*/
socket = ::socket(PF_CAN, SOCK_RAW, CAN_RAW); /**
* struct ifreq
* {
* # define IFHWADDRLEN 6
* # define IFNAMSIZ IF_NAMESIZE
* union
* {
* char ifrn_name[IFNAMSIZ]; // Interface name, e.g. "en0".
* } ifr_ifrn;
*
* union
* {
* struct sockaddr ifru_addr;
* struct sockaddr ifru_dstaddr;
* struct sockaddr ifru_broadaddr;
* struct sockaddr ifru_netmask;
* struct sockaddr ifru_hwaddr;
* short int ifru_flags;
* int ifru_ivalue;
* int ifru_mtu;
* struct ifmap ifru_map;
* char ifru_slave[IFNAMSIZ]; // Just fits the size
* char ifru_newname[IFNAMSIZ];
* __caddr_t ifru_data;
* } ifr_ifru;
* };
* # define ifr_name ifr_ifrn.ifrn_name // interface name
* # define ifr_hwaddr ifr_ifru.ifru_hwaddr // MAC address
* # define ifr_addr ifr_ifru.ifru_addr // address
* # define ifr_dstaddr ifr_ifru.ifru_dstaddr // other end of p-p lnk
* # define ifr_broadaddr ifr_ifru.ifru_broadaddr // broadcast address
* # define ifr_netmask ifr_ifru.ifru_netmask // interface net mask
* # define ifr_flags ifr_ifru.ifru_flags // flags
* # define ifr_metric ifr_ifru.ifru_ivalue // metric
* # define ifr_mtu ifr_ifru.ifru_mtu // mtu
* # define ifr_map ifr_ifru.ifru_map // device map
* # define ifr_slave ifr_ifru.ifru_slave // slave device
* # define ifr_data ifr_ifru.ifru_data // for use by interface
* # define ifr_ifindex ifr_ifru.ifru_ivalue // interface index
* # define ifr_bandwidth ifr_ifru.ifru_ivalue // link bandwidth
* # define ifr_qlen ifr_ifru.ifru_ivalue // queue length
* # define ifr_newname ifr_ifru.ifru_newname // New name
* # define _IOT_ifreq _IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0)
* # define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0)
* # define _IOT_ifreq_int _IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)
*
* SIOCGIFINDEX:
* Retrieve the interface index of the interface into ifr_ifindex.
*/
struct ifreq ifr;
strcpy((char *)(ifr.ifr_name),v == ? "can0" : "can1");
ioctl(socket,SIOCGIFINDEX,&ifr); /**
* 绑定socket
*/
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
bind(socket,(struct sockaddr*)&addr,sizeof(addr)); /**
* 这里是存在问题,每次线程并没有关闭,而是直接不管,可能导致一些问题
* 从后续的代码可以看出,每次都已经停止了线程,delete了对象实体。
*/
t = NULL; /**
* 创建线程,并将socket文件描述符作为参数传入线程,主要作为接受数据线程
*/
t = new Thread(socket); /**
* 用于处理线程发出的信号
*/
connect(t,SIGNAL(msg(QString)),this,SLOT(msg(QString))); /**
* 开启线程
*/
t->start();
} void MainWindow::stopcan(int v)
{
/**
* 关闭对应的can之前,先关闭对应socket接受线程
*/
if(t)
{
t->stop();
t->deleteLater();
} /**
* 关闭socket文件描述符
*/
::close(socket); /**
* 给出相关的提示信息
*/
if(v == )
system("canconfig can0 stop");
else
system("canconfig can1 stop");
} void MainWindow::on_can0_toggled(bool checked)
{
/**
* 根据对应的情况,打开,或者关闭对应的can设备
*/
if(checked)
{
stopcan();
startcan();
}
} void MainWindow::on_can1_toggled(bool checked)
{
/**
* 根据对应的情况,打开,或者关闭对应的can设备
*/
if(checked)
{
stopcan();
startcan();
}
}
am335x Qt SocketCAN Demo hacking的更多相关文章
- Linux SocketCan client server demo hacking
/*********************************************************************** * Linux SocketCan client se ...
- Qt QML referenceexamples attached Demo hacking
/********************************************************************************************* * Qt ...
- Cmockery macro demo hacking
/********************************************************************* * Cmockery macro demo hacking ...
- ti processor sdk linux am335x evm setup.sh hacking
#!/bin/sh # # ti processor sdk linux am335x evm setup.sh hacking # 说明: # 本文主要对TI的sdk中的setup.sh脚本进行解读 ...
- linux watchdog demo hacking
/********************************************************************** * linux watchdog demo hackin ...
- linux SPI bus demo hacking
/********************************************************************** * linux SPI bus demo hacking ...
- qt的demo中,经常可以看到emum
最近开始看QT的文档,发现了很多好东西,至少对于我来说 收获很多~~~ 当然很多东西自己还不能理解的很透彻,也是和朋友讨论以后才渐渐清晰的,可能对于QT中一些经典的用意我还是存在会有些认识上的偏差,欢 ...
- Qt: 时钟Demo
其实是一个很简单的Demo,可以编译了拿NSIS打包.最近在做富文本编辑器和补C++不记得的东西吧,项目遥遥无期. //clock.pro #----------------------------- ...
- QT Linux Demo程序编译
我手上的qt源码包为:qt-everywhere-opensource-src-4.7.0.tar.gz 在Linux下编译比较容易,解压后直接 ./configure,一般会报缺少什么库这些.自己遇 ...
随机推荐
- XML_CPP_资料_libXml2_01_Code
ZC: 这里的代码,就是 http://www.cnblogs.com/cppskill/p/6207609.html(我的文章"XML_CPP_资料_libXml2_01 - CppSki ...
- [原][JSBSim]基于qt代码实现:TCP|UDP与飞行模拟软件JSBSim的通信,现实模型飞行!
废话没有,上关键代码 头文件 #include <QUdpSocket> #include <qtcpsocket.h> #ifndef vrUDP #define vrUDP ...
- 【Jmeter】Linux(Mac)上使用最新版本Jmeter(5.0)做性能测试
本文我们一起来学习在Linux(Mac)上利用Jmeter进行性能测试并生成测试报告的方法. 环境准备 JDK 访问这个地址 [JDK11.01],根据实际环境下载一个JDK. Jmeter Jmet ...
- FastJson之JsonObject, JsonString, JavaBean,List快速转换
// 将json字符串转换为json对象 JSONObject jsonObject = JSON.parseObject(jsonStr); // {"retState":&qu ...
- 微信公众号菜单添加小程序,miniprogram,pagepath参数详解,php开发公众号
随着微信小程序功能的开发, 已经可以跟公众号打通了, 主要有两种方式: 1) 在公众号文章中插入小程序 2) 在公众号菜单中添加小程序 第一种方式, 子恒老师在前面的课程已经详细介绍过, 今天来讲第二 ...
- Linux crontab定时执行任务 命令格式与详细例子(转)
基本格式 : * * * * * command 分 时 日 月 周 命令 第1列表示分钟1-59 每分钟用*或者 */1表示 第2列表示小时1-23(0表示0点) 第3列表示日期1-31 第4列表示 ...
- C++虚函数与多态
C++多态性是通过虚函数来实现的,虚函数允许子类重新定义成员函数,而子类重新定义父类的做法称为覆盖(override),或者称为重写.(这里我觉得要补充,重写的话可以有两种,直接重写成员函数和重写虚函 ...
- uinex 常用命令
删除文件夹实例:rm -rf /var/log/httpd/access将会删除/var/log/httpd/access目录以及其下所有文件.文件夹 删除文件使用实例:rm -f /var/log/ ...
- Oracle 账户锁定问题解决办法
1 打开 SQL PLUS 2 登录数据库 3 输入 conn/as sysdba; 4 输入 alter user 数据库名 account unlock;
- shell 命令参数
$# 是传给脚本的参数个数$0 是脚本本身的名字$1 是传递给该shell脚本的第一个参数$2 是传递给该shell脚本的第二个参数$@ 是传给脚本的所有参数的列表$* 是以一个单字符串显示所有向脚本 ...