1. /***********************************************************************************
  2. * am335x Qt SocketCAN Demo hacking
  3. * 说明:
  4. * 本源代码来自OK335xS,主要是为分析如何在Qt中使用SocketCAN的这种通信方式。
  5. *
  6. * 2015-9-12 晴 深圳 南山平山村 曾剑锋
  7. **********************************************************************************/
  8.  
  9.  
  10. cat main.c
  11. #include <QtGui/QApplication>
  12. #include "mainwindow.h"
  13. #include "myinputpanelcontext.h"
  14.  
  15. int main(int argc, char *argv[])
  16. {
  17. QApplication a(argc, argv);
  18. /**
  19. * 创建软键盘
  20. */
  21. MyInputPanelContext *ic = new MyInputPanelContext;
  22. /**
  23. * This function replaces the QInputContext instance used by the application with inputContext.
  24. * Qt takes ownership of the given inputContext.
  25. *
  26. * 设置软键盘
  27. */
  28. a.setInputContext(ic); //将输入上下文与应用程序关联
  29.  
  30. MainWindow w;
  31. /**
  32. * Qt::WindowMaximizeButtonHint:
  33. * Adds a maximize button. On some platforms this implies Qt::WindowSystemMenuHint for it to work.
  34. * Qt::WindowMinimizeButtonHint:
  35. * Adds a minimize button. On some platforms this implies Qt::WindowSystemMenuHint for it to work.
  36. */
  37. w.setWindowFlags(w.windowFlags()& ~Qt::WindowMaximizeButtonHint& ~Qt::WindowMinimizeButtonHint);
  38. w.showMaximized();
  39. w.show();
  40.  
  41. return a.exec();
  42. }
  43.  
  44. cat mainwindow.h
  45. #ifndef MAINWINDOW_H
  46. #define MAINWINDOW_H
  47.  
  48. #include <QMainWindow>
  49. #include <QProcess>
  50. #include <sys/ioctl.h>
  51. #include <net/if.h>
  52. #include <linux/can.h>
  53. #include "thread.h"
  54. #include <QButtonGroup>
  55.  
  56. /**
  57. * 引入界面文件生成的UI类
  58. */
  59. namespace Ui {
  60. class MainWindow;
  61. }
  62.  
  63. class MainWindow : public QMainWindow
  64. {
  65. Q_OBJECT
  66.  
  67. public:
  68. explicit MainWindow(QWidget *parent = );
  69. ~MainWindow();
  70. protected:
  71. void moveEvent(QMoveEvent *); // 界面移动事件
  72. void resizeEvent(QResizeEvent *); // 界面重绘大小事件
  73. void closeEvent(QCloseEvent *); // 界面关闭事件
  74. private slots:
  75. void on_send_clicked(); // 发送按钮点击槽
  76. void msg(QString str); // 信息处理信号槽
  77. void stopcan(int v); // 停止can信号槽
  78. void startcan(int v); // 开始can信号槽
  79. void on_can0_toggled(bool checked); // can0 被点击翻转信号槽
  80. void on_can1_toggled(bool checked); // can1 被点击翻转信号槽
  81.  
  82. private:
  83. Ui::MainWindow *ui; // 声明图形界面指针
  84. int socket; // can socket 描述符
  85. struct sockaddr_can addr; // can socket 地址结构体
  86. Thread *t; // 线程
  87. QButtonGroup* btg; // 按钮
  88. };
  89.  
  90. #endif // MAINWINDOW_H
  91.  
  92. cat mainwindow.c
  93. #include <sys/ioctl.h>
  94. #include <fcntl.h>
  95. #include "mainwindow.h"
  96. #include "ui_mainwindow.h"
  97. #include <QMessageBox>
  98. #include <unistd.h>
  99.  
  100. MainWindow::MainWindow(QWidget *parent) :
  101. QMainWindow(parent), // 构造函数初始化父类构造函数
  102. ui(new Ui::MainWindow) // 创建ui实体,并赋值
  103. {
  104. ui->setupUi(this); // 设置将图形界面放置在哪个对象上
  105.  
  106. btg = new QButtonGroup; // 创建分组,多选一
  107. btg->addButton(ui->can0,);
  108. btg->addButton(ui->can1,);
  109.  
  110. startcan();
  111. }
  112.  
  113. MainWindow::~MainWindow()
  114. {
  115. /**
  116. * 这里让人怀疑,都已经删除了ui界面,button group又怎么能够获取到ui里面的checkedId呢?
  117. * 唯一的解释就是button group里面保存了最后一次toggle事件获取的checkedId值,而不是运行
  118. * checkedId()的时候去获取checkedId
  119. */
  120. delete ui;
  121. stopcan(btg->checkedId());
  122. }
  123.  
  124. void MainWindow::msg(QString str)
  125. {
  126. /**
  127. * 将获取到的信息放到显示文本框的最后去
  128. */
  129. ui->label->append(str);
  130. }
  131.  
  132. void MainWindow::on_send_clicked()
  133. {
  134. /**
  135. * struct can_frame - basic CAN frame structure
  136. * @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
  137. * @can_dlc: frame payload length in byte (0 .. 8) aka data length code
  138. * N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1
  139. * mapping of the 'data length code' to the real payload length
  140. * @data: CAN frame payload (up to 8 byte)
  141. *
  142. * struct can_frame {
  143. * canid_t can_id; // 32 bit CAN_ID + EFF/RTR/ERR flags
  144. * __u8 can_dlc; // frame payload length in byte (0 .. CAN_MAX_DLEN)
  145. * __u8 data[CAN_MAX_DLEN] __attribute__((aligned(8)));
  146. * };
  147. */
  148. struct can_frame frame;
  149. /**
  150. * 获取将要发送的文本内容
  151. * Returns a std::string object with the data contained in this QString.
  152. * The Unicode data is converted into 8-bit characters using the toUtf8() function.
  153. */
  154. std::string str=ui->edit->text().toStdString();
  155.  
  156. /**
  157. * 如果文本的长度大于8,那么将给出提示信息,并直接返回,不发送数据
  158. */
  159. if(str.length() > )
  160. {
  161. QMessageBox::about(this,"error","length of send string must less than 8 bytes");
  162. return;
  163. }
  164.  
  165. /**
  166. * 默认发送的can id是0x123
  167. *
  168. * 扩展格式识别符由 29 位组成。其格式包含两个部分:11 位基本 ID、18 位扩展 ID。
  169. * Controller Area Network Identifier structure:
  170. *
  171. * bit 0-28 : CAN识别符 (11/29 bit)
  172. * bit 29 : 错误帧标志 (0 = data frame, 1 = error frame)
  173. * bit 30 : 远程发送请求标志 (1 = rtr frame)
  174. * bit 31 : 帧格式标志 (0 = standard 11 bit, 1 = extended 29 bit)
  175. *
  176. * typedef __u32 canid_t;
  177. *
  178. * struct can_frame {
  179. * canid_t can_id; // 32 bit CAN_ID + EFF/RTR/ERR flags
  180. * __u8 can_dlc; // 数据长度: 0 .. 8
  181. * __u8 data[8] __attribute__((aligned(8)));
  182. * };
  183. */
  184. frame.can_id = 0x123;
  185. /**
  186. * Returns a pointer to an array that contains a null-terminated sequence of
  187. * characters (i.e., a C-string) representing the current value of the string object.
  188. * This array includes the same sequence of characters that make up the value of
  189. * the string object plus an additional terminating null-character ('\0') at the end.
  190. */
  191. strcpy((char*)frame.data, str.c_str());
  192. /**
  193. * 目前猜测:dlc --> data length count
  194. * 于是可以很好的解释:can 发送的数据长度,是按字节算的
  195. */
  196. frame.can_dlc = str.length();
  197.  
  198. /**
  199. * Send N bytes of BUF on socket FD to peer at address ADDR (which is
  200. * ADDR_LEN bytes long). Returns the number sent, or -1 for errors.
  201. *
  202. * This function is a cancellation point and therefore not marked with
  203. * __THROW.
  204. *
  205. * extern ssize_t sendto (int __fd, __const void *__buf, size_t __n,
  206. * int __flags, __CONST_SOCKADDR_ARG __addr,
  207. * socklen_t __addr_len);
  208. */
  209. sendto(socket,&frame,sizeof(struct can_frame),,(struct sockaddr*)&addr,sizeof(addr));
  210. }
  211.  
  212. void MainWindow::moveEvent(QMoveEvent *)
  213. {
  214. /**
  215. * 让测试窗口不会被移动
  216. */
  217. this->move(QPoint(,));
  218. }
  219.  
  220. void MainWindow::resizeEvent(QResizeEvent *)
  221. {
  222. /**
  223. * 让窗口最大化显示
  224. */
  225. this->showMaximized();
  226. }
  227.  
  228. void MainWindow::closeEvent(QCloseEvent *)
  229. {
  230. /**
  231. * 直接退出,不用关闭can口么?也就是说程序会在真正推出前,先解析掉所有当前生成的类实体?
  232. */
  233. exit();
  234. }
  235.  
  236. void MainWindow::startcan(int v)
  237. {
  238. /**
  239. * 从提示信息可以看出,使用125000作为默认的波特率
  240. */
  241. if(v == )
  242. {
  243. system("canconfig can0 bitrate 125000 ctrlmode triple-sampling on");
  244. system("canconfig can0 start");
  245. }
  246. else
  247. {
  248. system("canconfig can1 bitrate 125000 ctrlmode triple-sampling on");
  249. system("canconfig can1 start");
  250. }
  251.  
  252. /**
  253. * Create a new socket of type TYPE in domain DOMAIN, using
  254. * protocol PROTOCOL. If PROTOCOL is zero, one is chosen automatically.
  255. * Returns a file descriptor for the new socket, or -1 for errors.
  256. *
  257. * extern int socket (int __domain, int __type, int __protocol) __THROW;
  258. *
  259. * #define PF_CAN 29 // Controller Area Network.
  260. *
  261. * SOCK_RAW = 3, // Raw protocol interface.
  262. * #define SOCK_RAW SOCK_RAW
  263. *
  264. * particular protocols of the protocol family PF_CAN
  265. * #define CAN_RAW 1 // RAW sockets
  266. *
  267. */
  268. socket = ::socket(PF_CAN, SOCK_RAW, CAN_RAW);
  269.  
  270. /**
  271. * struct ifreq
  272. * {
  273. * # define IFHWADDRLEN 6
  274. * # define IFNAMSIZ IF_NAMESIZE
  275. * union
  276. * {
  277. * char ifrn_name[IFNAMSIZ]; // Interface name, e.g. "en0".
  278. * } ifr_ifrn;
  279. *
  280. * union
  281. * {
  282. * struct sockaddr ifru_addr;
  283. * struct sockaddr ifru_dstaddr;
  284. * struct sockaddr ifru_broadaddr;
  285. * struct sockaddr ifru_netmask;
  286. * struct sockaddr ifru_hwaddr;
  287. * short int ifru_flags;
  288. * int ifru_ivalue;
  289. * int ifru_mtu;
  290. * struct ifmap ifru_map;
  291. * char ifru_slave[IFNAMSIZ]; // Just fits the size
  292. * char ifru_newname[IFNAMSIZ];
  293. * __caddr_t ifru_data;
  294. * } ifr_ifru;
  295. * };
  296. * # define ifr_name ifr_ifrn.ifrn_name // interface name
  297. * # define ifr_hwaddr ifr_ifru.ifru_hwaddr // MAC address
  298. * # define ifr_addr ifr_ifru.ifru_addr // address
  299. * # define ifr_dstaddr ifr_ifru.ifru_dstaddr // other end of p-p lnk
  300. * # define ifr_broadaddr ifr_ifru.ifru_broadaddr // broadcast address
  301. * # define ifr_netmask ifr_ifru.ifru_netmask // interface net mask
  302. * # define ifr_flags ifr_ifru.ifru_flags // flags
  303. * # define ifr_metric ifr_ifru.ifru_ivalue // metric
  304. * # define ifr_mtu ifr_ifru.ifru_mtu // mtu
  305. * # define ifr_map ifr_ifru.ifru_map // device map
  306. * # define ifr_slave ifr_ifru.ifru_slave // slave device
  307. * # define ifr_data ifr_ifru.ifru_data // for use by interface
  308. * # define ifr_ifindex ifr_ifru.ifru_ivalue // interface index
  309. * # define ifr_bandwidth ifr_ifru.ifru_ivalue // link bandwidth
  310. * # define ifr_qlen ifr_ifru.ifru_ivalue // queue length
  311. * # define ifr_newname ifr_ifru.ifru_newname // New name
  312. * # define _IOT_ifreq _IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0)
  313. * # define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0)
  314. * # define _IOT_ifreq_int _IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)
  315. *
  316. * SIOCGIFINDEX:
  317. * Retrieve the interface index of the interface into ifr_ifindex.
  318. */
  319. struct ifreq ifr;
  320. strcpy((char *)(ifr.ifr_name),v == ? "can0" : "can1");
  321. ioctl(socket,SIOCGIFINDEX,&ifr);
  322.  
  323. /**
  324. * 绑定socket
  325. */
  326. addr.can_family = AF_CAN;
  327. addr.can_ifindex = ifr.ifr_ifindex;
  328. bind(socket,(struct sockaddr*)&addr,sizeof(addr));
  329.  
  330. /**
  331. * 这里是存在问题,每次线程并没有关闭,而是直接不管,可能导致一些问题
  332. * 从后续的代码可以看出,每次都已经停止了线程,delete了对象实体。
  333. */
  334. t = NULL;
  335.  
  336. /**
  337. * 创建线程,并将socket文件描述符作为参数传入线程,主要作为接受数据线程
  338. */
  339. t = new Thread(socket);
  340.  
  341. /**
  342. * 用于处理线程发出的信号
  343. */
  344. connect(t,SIGNAL(msg(QString)),this,SLOT(msg(QString)));
  345.  
  346. /**
  347. * 开启线程
  348. */
  349. t->start();
  350. }
  351.  
  352. void MainWindow::stopcan(int v)
  353. {
  354. /**
  355. * 关闭对应的can之前,先关闭对应socket接受线程
  356. */
  357. if(t)
  358. {
  359. t->stop();
  360. t->deleteLater();
  361. }
  362.  
  363. /**
  364. * 关闭socket文件描述符
  365. */
  366. ::close(socket);
  367.  
  368. /**
  369. * 给出相关的提示信息
  370. */
  371. if(v == )
  372. system("canconfig can0 stop");
  373. else
  374. system("canconfig can1 stop");
  375. }
  376.  
  377. void MainWindow::on_can0_toggled(bool checked)
  378. {
  379. /**
  380. * 根据对应的情况,打开,或者关闭对应的can设备
  381. */
  382. if(checked)
  383. {
  384. stopcan();
  385. startcan();
  386. }
  387. }
  388.  
  389. void MainWindow::on_can1_toggled(bool checked)
  390. {
  391. /**
  392. * 根据对应的情况,打开,或者关闭对应的can设备
  393. */
  394. if(checked)
  395. {
  396. stopcan();
  397. startcan();
  398. }
  399. }

am335x Qt SocketCAN Demo hacking的更多相关文章

  1. Linux SocketCan client server demo hacking

    /*********************************************************************** * Linux SocketCan client se ...

  2. Qt QML referenceexamples attached Demo hacking

    /********************************************************************************************* * Qt ...

  3. Cmockery macro demo hacking

    /********************************************************************* * Cmockery macro demo hacking ...

  4. ti processor sdk linux am335x evm setup.sh hacking

    #!/bin/sh # # ti processor sdk linux am335x evm setup.sh hacking # 说明: # 本文主要对TI的sdk中的setup.sh脚本进行解读 ...

  5. linux watchdog demo hacking

    /********************************************************************** * linux watchdog demo hackin ...

  6. linux SPI bus demo hacking

    /********************************************************************** * linux SPI bus demo hacking ...

  7. qt的demo中,经常可以看到emum

    最近开始看QT的文档,发现了很多好东西,至少对于我来说 收获很多~~~ 当然很多东西自己还不能理解的很透彻,也是和朋友讨论以后才渐渐清晰的,可能对于QT中一些经典的用意我还是存在会有些认识上的偏差,欢 ...

  8. Qt: 时钟Demo

    其实是一个很简单的Demo,可以编译了拿NSIS打包.最近在做富文本编辑器和补C++不记得的东西吧,项目遥遥无期. //clock.pro #----------------------------- ...

  9. QT Linux Demo程序编译

    我手上的qt源码包为:qt-everywhere-opensource-src-4.7.0.tar.gz 在Linux下编译比较容易,解压后直接 ./configure,一般会报缺少什么库这些.自己遇 ...

随机推荐

  1. MVC扩展Url.Action方法解决复杂对象参数问题

    1:问题描述 @Url.Action("Index", "Home", new { Key = "Key", Val = new { Nam ...

  2. cygwin install git

    Installation with Cygwin If you're comfortable with Cygwin, then use it to install git, ssh, wget an ...

  3. Java 集合-集合介绍

    2017-10-30 00:01:09 一.Java集合的类关系图 二.集合类的概述 集合类出现的原因:面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,Java就提供了集合类. ...

  4. B2B、B2C、C2C、O2O 和 P2P 的含义

    B2C(Business-to-Customer)商家对客户 我开一家公司卖东西,你来买,即B2C.生活中常用的比如我们经常在天猫旗舰店上面购物,天猫入驻的都是商家,而我们买东西的就是客户,这就是B2 ...

  5. English trip -- Review Unit 10 Leisure 休闲

    Words dance exercise fish play basketball play cards swim cook play the guitar listen to music watch ...

  6. English trip -- VC(情景课)10 B Around the house 在家里

    Vocablulary focus  核心词汇 cook play the guitar listen to music watch TV read magazines work in the gar ...

  7. linux之CentOS7在线安装Mysql

    下载和添加仓库     1.wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm     2.sudo rpm -iv ...

  8. Spring Boot 文档

    本节对 Spring Boot 的参考文档做了一个简单概述.本章节对全文的参考手册进行内容上的一些索引. 你可以参考本节,从头到尾依次阅读该文档,也可以跳过不感兴趣的内容. Spring Boot 参 ...

  9. Confluence 6 使用 LDAP 授权连接一个内部目录 - Schema 设置

    基本 DN(Base DN) 根专有名称(DN),这个名称在你对目录服务器上进行查询的时候使用.例如: o=example,c=com cn=users,dc=ad,dc=example,dc=com ...

  10. Confluence 6 使用 LDAP 授权连接一个内部目录概述

    你可以为你的 Confluence 连接 LDAP 服务器使用使用委托认证.这个意思是 Confluence 将会设置一个内部目录,这个目录仅被用来处理 LDAP 的授权. 这个设置将会为尝试登录系统 ...