I.MX6ULL开发板基于阿里云项目实战 6:遇到的问题,解决方法及项目总结

总体里说,阿里云IOT-SDK的编译,遇到的问题还是很少的。只要保证所使用的编译器和编译内核按照官网提供的例程,可以正确编译。我遇到的问题,是在修改源码的过程中。

问题1:服务器推送的数据成功解析(控灯指令),但是灯没有反应。见下图:

I.MX6ULL开发板基于阿里云项目实战 6:遇到的问题,解决方法及项目总结_第1张图片
原因分析:我们是使用write()函数对led设备节点将进行操作的。既然能够解析,就说明数据的推送没有问题,问题应该出来write()函数。
分析write()函数:
函数原型:

ssize_t write(int fd, const void *buf, size_t count);

我使用的:

write(fd,json_led->valueint, 1);  

write()函数的第二个参数,应该是一个指针类型的。
我们这里,变量json_led-是cJSON类型的。cJSON结构的内容如下:

typedef struct cJSON {
		struct cJSON*next,*prev;    /* 遍历数组或对象链的前向或后向链表指针*/
		struct cJSON *child; 		/*数组或对象的孩子节点*/
		int type;				    /* key的类型*/
		char *valuestring;			/*字符串值*/
		int valueint;				/* 整数值*/
		char *string;			    /* key的名字*/
} cJSON;

valueint是他的成员变量,是int类型,不是指针类型。所以出错。

问题1解决方法

write(fd,&(json_led->valueint), 4);  

问题2:在使用read()函数读传感器数据,读到的是0

原因分析:首先,我的程序中有read()返回值的判断,read()函数的返回值是没有问题的。为进一步分析其原因,我编写了一个简单的测试程序,运行结果如下:
I.MX6ULL开发板基于阿里云项目实战 6:遇到的问题,解决方法及项目总结_第2张图片
结果发现,每次执行,刚开始三个测量值都为0。推测是因为三合传感器的初始化需要时间,如果马上读取,三合传感器的值还没有显示到设备节点。所以读出的是0。

问题2解决方法:

在read()函数之前,使程序休眠一段时间。

usleep(100000);

问题解决。

问题3:补丁问题,修改补丁后报错:patch: **** malformed patch at line 199:

问题分析:
补丁文件中,会有类似这样一行代码:

@@ -1045,6 +1045,15 @@ 

数字6,表示记录了6行原始文件,数字15表示记录了15行目标文件(补丁文件)。
如果你这时手工加了一行:
这是你应用这个补丁,patch 就会提示失败,并输出:
patch: malformed patch at line xxx
应用时,patch 都会检查受影响的行是否与记录在两个 @@ 之间的数值一致,手工加一行后,记录的目标文件行数为16,因此patch会失败。****
我的总结,就是串行了!

扩展:Linux的补丁内容包括三个部分:

修改语句前三句(用来给补丁定位,因为只单靠行数来确定补丁修改的位置是不对) 
+ 修改语句 + 
修改语句后三句(补丁结束的标志,也需要匹配,以便检查我们的补丁是否合适)。

问题4:补丁问题,修改补丁后报错:Hunk #5 FAILED at 147. 1 out of 5 hunks FAILED – saving rejects to file src/mqtt/examples/mqtt_example.c.rej

原因分析:
要对补丁进行修改,首先,要撤销补丁,再对齐修改,修改好以后,再打补丁。如果没有撤销补丁就直接修改,会报这个错误。

问题4解决方法:

在修改补丁之前,要先撤销该补丁。

总结

整个项目的,做的工作如下:
1、登录阿里云,创建产品和设备.
2、下载阿里云IOT-SDK源码。进行配置和编译,生成可用于ARM板的可执行文件
3、编写led和传感器驱动。这里我们使用的传感器是AP32164三合一传感器
4、对源码进行修改,在原有功能的基础上,对源码进行修改。使其实现将板载传感器数据上报到阿里云以及通过阿里云推送命令,控制开发板灯的亮灭。
之前用stm32也进行过相关的开始,实现温湿度的上传以及风扇,电机灯控制。对比二者的开发过程,有如下感受:
1、从应用的角度来说,ARM板的开发,更加简洁:
stm32是利用程序发送报文连接阿里云服务器以及后续的推送和发布,并通过定时器来控制心跳时间,定时发送保活报文(心跳包)(一共好像是用了4个定时器),代码量大,程序复杂;而在ARM板的开发过程中,我们使用的是IOT-SDK,通过调用IOT_MQTT_Construct() (其参数是一个结构体,结构体的成员就包括心跳时间,消息发送和接受buffer的最大长度等)、IOT_MQTT_Subscribe() 、IOT_MQTT_Publish() 或IOT_MQTT_Publish_Simple()、IOT_MQTT_Yield()这四个函数,即可实现基本的设备和服务器之间的发布和推送,通过cJSON_Parse()h和cJSON_GetObjectItem()这两个函数,实现对服务器推送数据的解析,程序十分简洁。
注:
IOT_MQTT_Construct() 接口调用, 建立设备和云平台之间的长连接
IOT_MQTT_Subscribe() 接口调用, 可以向云平台表达设备将接收哪些Topic上的报文
IOT_MQTT_Publish() 或 IOT_MQTT_Publish_Simple(), 可将消息上报到云端
IOT_MQTT_Yield()用于接收云端下发的消息, 并调用用户在 IOT_MQTT_Subscribe() 时指定的回调函数,用于对数据进行处理
2、从底层实现上来说:
以服务器推送数据给开发板,实现电灯为例。
stm32,是根据解析出来的数据,直接对寄存器进行操作(写0写1),以此,来实现对灯的亮灭控制。
而ARM板,是对设备节点(也就是,设备文件)进行操作。通过向设备节点写0写1,来实现对灯的亮灭控制。这就要求,在使用之前,必须先编写led驱动,以生成设备节点。然后根据应用程序向设备节点中写的值,在驱动程序中,控制对应的寄存器,从而实现灯的亮灭控制。也就是间接的控制寄存器。
3、函数的执行逻辑
32中,因为不是实时操作系统,所以,都是使用函数调用的方式来实现功能。eg:对推送数据的处理函数。而ARM中的IOT-SDK,提供了回调函数。提高程序的运行效率。
扩展:
1、回调函数的介绍:
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
2、普通的函数调用,一般都是由main函数直接或间接调用的。调用函数对普通函数进行调用以后,程序就会转到被调用函数出开始执行,直到被调用函数执行完毕,在返回调用函数继续执行。
3、而回调函数是系统调用,与main函数无关。当满足某个条件或事件的时候,回调函数就会被调用。但是,调用程序不用等待被调函数执行结束才继续执行,而是可以和被调函数同时执行。当被调执行完毕,被调函数会通知调用函数,调用结束。

引用一个例子:

https://blog.csdn.net/yilovexing/article/details/93192484?utm_source=app&app_version=4.5.2
在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做 触发回调事件,店员给你打电话叫做 调用回调函数,你到店里去取货叫做 响应回调事件。

题外话:

linux针对不同类型的设备,具有不同的框架。学linux驱动,我感觉,本质就是在学习框架。Linux下的各种驱动的开发,一定要满足框架。驱动最终表现就是/dev/xxx 文件。通过open(),close(),read(),write()对文件进行操作。

你可能感兴趣的:(linux实战项目,linux)