DBus在Hi3515中的移植
发布日期:2021-08-12 01:50:54 浏览次数:4 分类:技术文章

本文共 16635 字,大约阅读时间需要 55 分钟。

1.基础环境:

虚拟机:VMware Workstation8  操作系统:Ubuntu12.04  

交叉编译工具 arm-hismall-linux

以下为需要安装的库:

DBus版本:1.6.4    glib版本:2.32.4    libxml2版本:2.6.8   gettext版本:0.18

其中glib与gettext直接运行./configuire、make、make install进行安装

DBus需要libxml2动态链接库的支持,所以libxml2需要交叉编译 ./configure --host=arm-hismall-linux 、make、 make install 来安装

可能遇见的问题:

configure error: you must have either have gettext support in your C library, or use the***

编译glib时,先安装好gettext,遇到上述问题,运行ldconfig

 

2.交叉编译DBus

2.1 执行configure

./configure --host=arm-hismall-linux --with-xml=libxml (使用libxml解析器,如不用--with会遇到 expand.h:No such file or directory)

 

可能遇到的问题:

encoding.h:28:19: iconv.h: No such file or director

此种情况为glibxml2的版本太低。

 

libxml2.so: could not read symbols: File in wrong format

需要交叉编译libxml2库,并安装

 

checking for libxml-2.0 >= 2.6.0... configure: error: Explicitly requested libxml but libxml not found

其实已经安装上 libxml2 了的,这里只是一环境变量没有设置好而已。

解决办法:

echo $PKG_CONFIG_PATH

(1)确定 /usr/local/libxml2/lib/pkgconfig 目录下有 libxml-2.0.pc
(2)export PKG_CONFIG_PATH=/usr/local/libxml2/lib/pkgconfig:$PKG_CONFIG_PATH
(3)再./configure一次,到没有出现错误就OK了。

 

2.2 执行make

可能遇到问题:

arm-hisi-linux/bin/ld: cannot find -lz

缺少libz库 sudo apt-get install lib64z1-dev

 

bus.c:694: undefined reference to `bus_set_watched_dirs'

缺少函数bus_set_watched_dirs的定义,具体可见  

修改bus-1.6.4/bus/dir-watch-dnotify.c  如下为部分代码  (//add为添加部分)

1 #include 
2 #include
3 #include "dir-watch.h" //add 4 5 #define MAX_DIRS_TO_WATCH 128 6 7 /* use a static array to avoid handling OOM */ 8 static int fds[MAX_DIRS_TO_WATCH]; 9 static int num_fds = 0;10 void bus_watch_directory(const char *dir, BusContext *context); //add11 //add function12 void bus_set_watched_dirs(BusContext *context,DBusList **directories)13 {14 DBusList *link=_dbus_list_get_first_link(directories);15 while(link!=NULL)16 {17 bus_watch_directory(link->data,context);18 link=_dbus_list_get_next_link(directories,link);19 }20 }

修改bus-1.6.4/bus/bus.c  添加头文件

#include "dir-watch.h"

 

2.3 sudo make install

 

3. 运行dbus-daemon

以上执行完成后,可以在bus-1.6.4/bus/目录下找到dbus-daemon,即为交叉编译后的dbus应用;bus-1.6.4/tools/目录下找到dbus-launch,为启动并配置dbus-daemon的程序,编写脚本dbus_run来启动dbus-launch

#!/bin/shif test -z "$DBUS_SESSION_BUS_ADDRESS" ; then## if not found, launch a new oneeval `dbus-launch --sh-syntax --exit-with-session`echo "D-Bus per-session daemon address is: $DBUS_SESSION_BUS_ADDRESS"fi

将dbus-daemon、dbus-launch放到开发板上/usr/bin/目录下 将libxml2.so.2 放到/usr/lib/ 下

 

在开发板上运行dbus-daemon进行测试

可能遇到的问题:

# dbus-daemon --system

Failed to start message bus: Failed to open "/usr/local/etc/dbus-1/system.conf":

No such file or directory

于是我又到dbus-1.6.4/bus中找到system.conf  session.conf(针对--session参数)

# dbus-daemon --system

Failed to start message bus: Failed to open :".....system.d" No such file or directory

于是响应目录下建了个system.d文件夹 (创建session.d 针对--session参数)

# dbus-daemon --system

Failed to start message bus: Failed to bind socket "/var/run/dbus/system_bus_soc ket

No such file or directory

在相应目录下创建system_bus_socket,结果

# dbus-daemon --system

Failed to start message bus: Failed to bind socket "/var/run/dbus/system_bus_soc ket:Address already in use

郁闷,删掉system_bus_socket,只留/var/run/dbus/

# dbus-daemon --system

Failed to start message bus:Could not get UID and GID for username "messagebus"

通过添加用户解决 adduser messagebus 密码设为dbus 也可以在/etc/passwd后添加 

messagebus:$1$$YwM2vWXS3L4EbCfJU4I7N0:500:500:Linux User,,,:/home/messagebus:/bi   //为adduser messagebus命令生成

到这一步dbus-daemon可正常运行

 

4.编写应用测试DBus

4.1 gcc编译

在网上找了一段代码,感觉还不错 代码贴出如下 引用地址:

1 /*  2 * Example low-level D-Bus code.  3 * Written by Matthew Johnson 
4 * 5 * This code has been released into the Public Domain. 6 * You may do whatever you like with it. 7 */ 8 #include
9 #include
10 #include
11 #include
12 #include
13 14 /** 15 * Connect to the DBUS bus and send a broadcast signal 16 */ 17 void sendsignal(char* sigvalue) 18 { 19 DBusMessage* msg; 20 DBusMessageIter args; 21 DBusConnection* conn; 22 DBusError err; 23 int ret; 24 dbus_uint32_t serial = 0; 25 26 printf("Sending signal with value %s\n", sigvalue); 27 28 // initialise the error value 29 dbus_error_init(&err); 30 31 // connect to the DBUS system bus, and check for errors 32 conn = dbus_bus_get(DBUS_BUS_SESSION, &err); 33 if (dbus_error_is_set(&err)) { 34 fprintf(stderr, "Connection Error (%s)\n", err.message); 35 dbus_error_free(&err); 36 } 37 if (NULL == conn) { 38 exit(1); 39 } 40 41 // register our name on the bus, and check for errors 42 ret = dbus_bus_request_name(conn, "test.signal.source", DBUS_NAME_FLAG_REPLACE_EXISTING , &err); 43 if (dbus_error_is_set(&err)) { 44 fprintf(stderr, "Name Error (%s)\n", err.message); 45 dbus_error_free(&err); 46 } 47 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { 48 exit(1); 49 } 50 51 // create a signal & check for errors 52 msg = dbus_message_new_signal("/test/signal/Object", // object name of the signal 53 "test.signal.Type", // interface name of the signal 54 "Test"); // name of the signal 55 if (NULL == msg) 56 { 57 fprintf(stderr, "Message Null\n"); 58 exit(1); 59 } 60 61 // append arguments onto signal 62 dbus_message_iter_init_append(msg, &args); 63 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &sigvalue)) { 64 fprintf(stderr, "Out Of Memory!\n"); 65 exit(1); 66 } 67 68 // send the message and flush the connection 69 if (!dbus_connection_send(conn, msg, &serial)) { 70 fprintf(stderr, "Out Of Memory!\n"); 71 exit(1); 72 } 73 dbus_connection_flush(conn); 74 75 printf("Signal Sent\n"); 76 77 // free the message 78 dbus_message_unref(msg); 79 } 80 81 /** 82 * Call a method on a remote object 83 */ 84 void query(char* param) 85 { 86 DBusMessage* msg; 87 DBusMessageIter args; 88 DBusConnection* conn; 89 DBusError err; 90 DBusPendingCall* pending; 91 int ret; 92 bool stat; 93 dbus_uint32_t level; 94 95 printf("Calling remote method with %s\n", param); 96 97 // initialiset the errors 98 dbus_error_init(&err); 99 100 // connect to the system bus and check for errors101 conn = dbus_bus_get(DBUS_BUS_SESSION, &err);102 if (dbus_error_is_set(&err)) {103 fprintf(stderr, "Connection Error (%s)\n", err.message);104 dbus_error_free(&err);105 }106 if (NULL == conn) {107 exit(1);108 }109 110 // request our name on the bus111 ret = dbus_bus_request_name(conn, "test.method.caller", DBUS_NAME_FLAG_REPLACE_EXISTING , &err);112 if (dbus_error_is_set(&err)) {113 fprintf(stderr, "Name Error (%s)\n", err.message);114 dbus_error_free(&err);115 }116 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {117 exit(1);118 }119 120 // create a new method call and check for errors121 msg = dbus_message_new_method_call("test.method.server",// target for the method call122 "/test/method/Object", // object to call on123 "test.method.Type", // interface to call on124 "Method"); // method name125 if (NULL == msg) {126 fprintf(stderr, "Message Null\n");127 exit(1);128 }129 130 // append arguments131 dbus_message_iter_init_append(msg, &args);132 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &param)) {133 fprintf(stderr, "Out Of Memory!\n");134 exit(1);135 }136 137 // send message and get a handle for a reply138 if (!dbus_connection_send_with_reply (conn, msg, &pending, -1)) { // -1 is default timeout139 fprintf(stderr, "Out Of Memory!\n");140 exit(1);141 }142 if (NULL == pending) {143 fprintf(stderr, "Pending Call Null\n");144 exit(1);145 }146 dbus_connection_flush(conn);147 148 printf("Request Sent\n");149 150 // free message151 dbus_message_unref(msg);152 153 // block until we recieve a reply154 dbus_pending_call_block(pending);155 156 // get the reply message157 msg = dbus_pending_call_steal_reply(pending);158 if (NULL == msg) {159 fprintf(stderr, "Reply Null\n");160 exit(1);161 }162 // free the pending message handle163 dbus_pending_call_unref(pending);164 165 // read the parameters166 if (!dbus_message_iter_init(msg, &args))167 fprintf(stderr, "Message has no arguments!\n");168 else if (DBUS_TYPE_BOOLEAN != dbus_message_iter_get_arg_type(&args))169 fprintf(stderr, "Argument is not boolean!\n");170 else171 dbus_message_iter_get_basic(&args, &stat);172 173 if (!dbus_message_iter_next(&args))174 fprintf(stderr, "Message has too few arguments!\n");175 else if (DBUS_TYPE_UINT32 != dbus_message_iter_get_arg_type(&args))176 fprintf(stderr, "Argument is not int!\n");177 else178 dbus_message_iter_get_basic(&args, &level);179 180 printf("Got Reply: %d, %d\n", stat, level);181 182 // free reply183 dbus_message_unref(msg); 184 }185 186 187 void reply_to_method_call(DBusMessage* msg, DBusConnection* conn)188 {189 DBusMessage* reply;190 DBusMessageIter args;191 bool stat = true;192 dbus_uint32_t level = 21614;193 dbus_uint32_t serial = 0;194 char* param = "";195 196 // read the arguments197 if (!dbus_message_iter_init(msg, &args))198 fprintf(stderr, "Message has no arguments!\n");199 else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args))200 fprintf(stderr, "Argument is not string!\n");201 else202 dbus_message_iter_get_basic(&args, &param);203 204 printf("Method called with %s\n", param);205 206 // create a reply from the message207 reply = dbus_message_new_method_return(msg);208 209 // add the arguments to the reply210 dbus_message_iter_init_append(reply, &args);211 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_BOOLEAN, &stat)) {212 fprintf(stderr, "Out Of Memory!\n");213 exit(1);214 }215 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT32, &level)) {216 fprintf(stderr, "Out Of Memory!\n");217 exit(1);218 }219 220 // send the reply && flush the connection221 if (!dbus_connection_send(conn, reply, &serial)) {222 fprintf(stderr, "Out Of Memory!\n");223 exit(1);224 }225 dbus_connection_flush(conn);226 227 // free the reply228 dbus_message_unref(reply);229 }230 231 232 233 /**234 * Server that exposes a method call and waits for it to be called235 */236 void listen()237 {238 DBusMessage* msg;239 DBusMessage* reply;240 DBusMessageIter args;241 DBusConnection* conn;242 DBusError err;243 int ret;244 char* param;245 246 printf("Listening for method calls\n");247 248 // initialise the error249 dbus_error_init(&err);250 251 // connect to the bus and check for errors252 conn = dbus_bus_get(DBUS_BUS_SESSION, &err);253 if (dbus_error_is_set(&err)) {254 fprintf(stderr, "Connection Error (%s)\n", err.message);255 dbus_error_free(&err);256 }257 if (NULL == conn) {258 fprintf(stderr, "Connection Null\n");259 exit(1);260 }261 262 // request our name on the bus and check for errors263 ret = dbus_bus_request_name(conn, "test.method.server",264 DBUS_NAME_FLAG_REPLACE_EXISTING , &err);265 if (dbus_error_is_set(&err)) {266 fprintf(stderr, "Name Error (%s)\n", err.message);267 dbus_error_free(&err);268 }269 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {270 fprintf(stderr, "Not Primary Owner (%d)\n", ret);271 exit(1);272 }273 274 // loop, testing for new messages275 while (true) {276 // non blocking read of the next available message277 dbus_connection_read_write(conn, 0);278 msg = dbus_connection_pop_message(conn);279 280 // loop again if we haven't got a message281 if (NULL == msg) {282 sleep(1);283 continue;284 }285 286 // check this is a method call for the right interface & method287 if (dbus_message_is_method_call(msg, "test.method.Type", "Method"))288 reply_to_method_call(msg, conn);289 290 // free the message291 dbus_message_unref(msg);292 }293 }294 295 296 297 /**298 * Listens for signals on the bus299 */300 void receive()301 {302 DBusMessage* msg;303 DBusMessageIter args;304 DBusConnection* conn;305 DBusError err;306 int ret;307 char* sigvalue;308 309 printf("Listening for signals\n");310 311 // initialise the errors312 dbus_error_init(&err);313 314 // connect to the bus and check for errors315 conn = dbus_bus_get(DBUS_BUS_SESSION, &err);316 if (dbus_error_is_set(&err)) {317 fprintf(stderr, "Connection Error (%s)\n", err.message);318 dbus_error_free(&err);319 }320 if (NULL == conn) {321 exit(1);322 }323 324 // request our name on the bus and check for errors325 ret = dbus_bus_request_name(conn, "test.signal.sink", DBUS_NAME_FLAG_REPLACE_EXISTING , &err);326 if (dbus_error_is_set(&err)) {327 fprintf(stderr, "Name Error (%s)\n", err.message);328 dbus_error_free(&err);329 }330 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {331 exit(1);332 }333 334 // add a rule for which messages we want to see335 dbus_bus_add_match(conn, "type='signal',interface='test.signal.Type'", &err); // see signals from the given interface336 dbus_connection_flush(conn);337 if (dbus_error_is_set(&err)) {338 fprintf(stderr, "Match Error (%s)\n", err.message);339 exit(1);340 }341 printf("Match rule sent\n");342 343 // loop listening for signals being emmitted344 while (true) {345 346 // non blocking read of the next available message347 dbus_connection_read_write(conn, 0);348 msg = dbus_connection_pop_message(conn);349 350 // loop again if we haven't read a message351 if (NULL == msg) {352 sleep(1);353 continue;354 }355 356 // check if the message is a signal from the correct interface and with the correct name357 if (dbus_message_is_signal(msg, "test.signal.Type", "Test")) {358 359 // read the parameters360 if (!dbus_message_iter_init(msg, &args))361 fprintf(stderr, "Message Has No Parameters\n");362 else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args))363 fprintf(stderr, "Argument is not string!\n");364 else365 dbus_message_iter_get_basic(&args, &sigvalue);366 367 printf("Got Signal with value %s\n", sigvalue);368 }369 370 // free the message371 dbus_message_unref(msg);372 }373 }374 375 376 377 int main(int argc, char** argv)378 {379 if (2 > argc) {380 printf ("Syntax: dbus-example [send|receive|listen|query] [
]\n");381 return 1;382 }383 char* param = "no param";384 if (3 >= argc && NULL != argv[2]) param = argv[2];385 if (0 == strcmp(argv[1], "send"))386 sendsignal(param);387 else if (0 == strcmp(argv[1], "receive"))388 receive();389 else if (0 == strcmp(argv[1], "listen"))390 listen();391 else if (0 == strcmp(argv[1], "query"))392 query(param);393 else {394 printf ("Syntax: dbus-example [send|receive|listen|query] [
]\n");395 return 1;396 }397 return 0;398 }

gcc编译问题:

错误1:$ gcc test.ctest.c:8:23: 错误: dbus/dbus.h:No such file or directory......$错误提示,dbus库的头文件位置不正确(如果已经安装了dbus的话)$ sudo updatedb$ sudo locate dbus.h (查看dbus.h的所在位置)/usr/local/include/dbus-1.0/dbus/dbus.h/usr/include/dbus-1.0/dbus/dbus.h看来dbus.h的存放位置的确不正确,这可能是由于dbus-1.0的安装位置有问题,没关系,调整一下dbus的头文件位置就可以了(调整方法如下):root@zxl:/usr/include# ln -sf dbus-1.0/dbus错误2:$ gcc test.c在包含自 test.c:8 的文件中:/usr/include/dbus/dbus.h:29:33: 错误: dbus/dbus-arch-deps.h:No such file or directory......依然有头文件无法正确定位的问题,从错误提示来看,该文件应该在/usr/include/dbus/目录下,可是进入该目录查看竟然没有,那就在整个系统中查找该文件。root@zxl:/usr/include/dbus# locate dbus-arch-deps.h/usr/local/lib/dbus-1.0/include/dbus/dbus-arch-deps.h/usr/lib/dbus-1.0/include/dbus/dbus-arch-deps.h将该文件复制到/usr/include/dbus目录下错误3:$ gcc test.c......test.c:(.text+0xbb6): undefined reference to `dbus_message_iter_get_basic'test.c:(.text+0xbd4): undefined reference to `dbus_message_unref'collect2: ld 返回 1需要连接动态库dbus$ cd /usr/lib$ ls *dbus*libdbus-1.a   libdbus-1.so.3      libdbus-glib-1.solibdbus-1.la libdbus-1.so.3.2.0 libdbus-glib-1.so.2libdbus-1.so libdbus-glib-1.a    libdbus-glib-1.so.2.1.0$ gcc test.c -l dbus-1 -o dbus

 

gcc执行:

$ ./dbus receiveListening for signalsMatch rule sentGot Signal with value doctorQBW  $ ./dbus send doctorQBW    (再开一个标签)Sending signal with value doctorQBWSignal Sent

 

4.2 交叉编译

交叉编译过程如下:

将该文件命名dbustest.c

$ arm-hismall-linux-gcc send.c

会出现 error:dbus/dbus.h:No such file or directory 即使gcc可以编译而且 dbus/dbus.h就在/usr/include中 也找不到dbus/dbus.h,没办法把bus-1.6.4/dbus目录拷贝到dbustest当前目录,

将dbustest中的 #include <dbus/dbus.h> 改为 #include "dbus/dbus.h"

将dbus.h中的 #include <dbus/xxx.h> 都改为 #include "dbus/xxx.h" 

将bus-1.6.4/dbus/.libs/libdbus-1.so拷贝到 dbustest当前目录

$ arm-hismall-linux-gcc dbustest.c -o dbustest -I./ -L ./ -ldbus-1

即可编译通过

ps:不知道怎么让交叉编译工具通过#include <dbus/xxx.h> 找到/usr/include/dbus下的头文件,若知道请留言指教

 

4.3 dbustest测试

将bus-1.6.4/dbus/.libs/libdbus-1.so.3拷贝到开发板/usr/lib/

在已经运行dbus-daemon进程的开发板上执行dbustest(命令同gcc测试处)

 

可能出现的问题:

Connection Error (Using X11 for dbus-daemon autolaunch was disabled at compile time, set your DBUS_SESSION_BUS_ADDRESS instead)

需要设置DBUS_SESSION_BUS_ADDRESS,在执行脚本dbus_run时,会显示

D-Bus per-session daemon address is: unix:path=/tmp/dbus-pebh4YY2Pp,guid=3ab7577588cdf4e7773663ae38792d8d

 设置环境变量: 

export DBUS_SESSION_BUS_ADDRESS=‘unix:path=/tmp/dbus-pebh4YY2Pp’

 

到此可正常运行dbustest。

 

 如有错误请指出,如果引用请注明出处: 

转载于:https://www.cnblogs.com/doctorqbw/archive/2012/08/23/2652785.html

转载地址:https://blog.csdn.net/weixin_30642305/article/details/96023268 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:MATLAB——颜色梯度显示
下一篇:Asp.Net细节性问题技巧精萃

发表评论

最新留言

哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年04月19日 21时00分04秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

PL/SQL数据库管理工具的使用 2019-04-27
史上最简单的spring-boot集成websocket的实现方式 2019-04-27
带你玩转属于自己的spring-boot-starter系列(一) 2019-04-27
带你玩转属于自己自己的spring-boot-starter系列(二) 2019-04-27
带你玩转属于自己的spring-boot-starter系列(三) 2019-04-27
基于SnowFlake算法如何让分库分表中不同的ID落在同一个库的算法的实现 2019-04-27
基于springboot的ShardingSphere5.X的分库分表的解决方案之分库解决方案(二) 2019-04-27
基于springboot的ShardingSphere5.X的分库分表的解决方案之分表解决方案(一) 2019-04-27
基于springboot的ShardingSphere5.X的分库分表的解决方案之关联查询解决方案(三) 2019-04-27
基于springboot的ShardingSphere5.X的分库分表的解决方案之基于seata的分布式事务的解决方案(十五) 2019-04-27
Linux文件管理参考 2019-04-27
FTP文件管理项目(本地云)项目日报(一) 2019-04-27
FTP文件管理项目(本地云)项目日报(二) 2019-04-27
FTP文件管理项目(本地云)项目日报(三) 2019-04-27
FTP文件管理项目(本地云)项目日报(四) 2019-04-27
【C++】勉强能看的线程池详解 2019-04-27
FTP文件管理项目(本地云)项目日报(五) 2019-04-27
FTP文件管理项目(本地云)项目日报(关于不定长包的测试) 2019-04-27
FTP文件管理项目(本地云)项目日报(六) 2019-04-27
FTP文件管理项目(本地云)项目日报(七) 2019-04-27