3个月了,终于把这个问题搞定了,前后学习加动手可能花了1个半月在这个系统搭建上面。我怀着复杂的心情写这篇文章,对很多懂这方面的专家我无话可说,对自己我更不知道该爱还是该恨。
6月中的时候我来到新的公司,接到的第一个任务就是交叉编译dbus,并在目标机上跑起来。我工作快3年了,一直搞的嵌入式开发,说实话在FSK很失败,以前开发环境都是搭好了,我们只是做一些应用程序的开发而已,我自认为最有成就的就是写了LCD和LED驱动。新公司真的有很多牛人,软硬件都懂,自己开始有点自卑。对第一个任务我甚至不知道怎么搭建嵌入式交叉编译环境,指定一个交叉编译工具链都花了我半天的时间,更不要说交叉编译dbus这么复杂的东西了,依赖的库太多,遇到的编译错误也让我摸不着头脑。幸好,这些东西做过就会了,在师傅的带领下我花了10天的时间把dbus交叉编译搞定。编译过程如下:
http://blog.chinaunix.net/u3/99283/showart.php?id=1971652 其中有一个隐患在里面。
好了,该运行测试程序,运行的时候发现一些错误一个个解决掉,发现通信有问题。(其实就是交叉编译里面的一个隐患造成的)
http://blog.chinaunix.net/u3/99283/showart.php?id=1976658
接下来的1个月被师傅叫去接别的任务,说这个问题可以先缓一下以后解决。1个月后又开始接着搞,这次的任务是要把input subsystem、udev、hal、dbus全部搭建起来,预期的的效果是,当触摸屏有按键事件的时候能通过input驱动-> hal(addon)->dbus并被应用程序接收到。这个架构我花了3天的事件看,并找了一些资料,感觉给我的2个礼拜应该足够了,可是接下来并没有想象的那么顺利。
重新运行dbus-daemon后台进程,感觉OK, 但是我这里有个测试程序收发消息确不能向网上所说的那么顺畅:
/********************************************************************************/
/*
* Example low-level D-Bus code.
* Written by Matthew Johnson< dbus@matthew.ath.cx >
*
* This code has been released into the Public Domain.
* You may do whatever you like with it.
*/
#include #include #include #include #include
/**
* Connect to the DBUS bus and send a broadcast signal
*/
void sendsignal(char* sigvalue)
{
DBusMessage* msg;
DBusMessageIter args;
DBusConnection* conn;
DBusError err;
int ret;
dbus_uint32_t serial = 0;
printf("Sending signal with value %s\n", sigvalue);
// initialise the error value
// connect to the DBUS system bus, and check for errors
conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
if (dbus_error_is_set(&err)) {
fprintf(stderr, "Connection Error (%s)\n", err.message);
dbus_error_free(&err);
}
if (NULL == conn) {
exit(1);
}
// register our name on the bus, and check for errors
ret = dbus_bus_request_name(conn, "test.signal.source", DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
if (dbus_error_is_set(&err)) {
fprintf(stderr, "Name Error (%s)\n", err.message);
dbus_error_free(&err);
}
if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
exit(1);
}
// create a signal & check for errors
msg = dbus_message_new_signal("/test/signal/Object", // object name of the signal
"test.signal.Type", // interface name of the signal
"Test"); // name of the signal
if (NULL == msg)
{
fprintf(stderr, "Message Null\n");
exit(1);
}
// append arguments onto signal
dbus_message_iter_init_append(msg, &args);
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &sigvalue)) {
fprintf(stderr, "Out Of Memory!\n");
exit(1);
}
// send the message and flush the connection
if (!dbus_connection_send(conn, msg, &serial)) {
fprintf(stderr, "Out Of Memory!\n");
exit(1);
}
dbus_connection_flush(conn);
printf("Signal Sent\n");
// free the message
dbus_message_unref(msg);
}
/**
* Call a method on a remote object
*/
void query(char* param)
{
DBusMessage* msg;
DBusMessageIter args;
DBusConnection* conn;
DBusError err;
DBusPendingCall* pending;
int ret;
bool stat;
dbus_uint32_t level;
printf("Calling remote method with %s\n", param);
// initialiset the errors
// connect to the system bus and check for errors
conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
if (dbus_error_is_set(&err)) {
fprintf(stderr, "Connection Error (%s)\n", err.message);
dbus_error_free(&err);
}
if (NULL == conn) {
exit(1);
}
// request our name on the bus
ret = dbus_bus_request_name(conn, "test.method.caller", DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
if (dbus_error_is_set(&err)) {
fprintf(stderr, "Name Error (%s)\n", err.message);
dbus_error_free(&err);
}
if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
exit(1);
}
// create a new method call and check for errors
msg = dbus_message_new_method_call("test.method.server",// target for the method call
"/test/method/Object", // object to call on
"test.method.Type", // interface to call on
"Method"); // method name
if (NULL == msg) {
fprintf(stderr, "Message Null\n");
exit(1);
}
// append arguments
dbus_message_iter_init_append(msg, &args);
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, ¶m)) {
fprintf(stderr, "Out Of Memory!\n");
exit(1);
}
// send message and get a handle for a reply
if (!dbus_connection_send_with_reply (conn, msg, &pending, -1)) { // -1 is default timeout
fprintf(stderr, "Out Of Memory!\n");
exit(1);
}
if (NULL == pending) {
fprintf(stderr, "Pending Call Null\n");
exit(1);
}
dbus_connection_flush(conn);
printf("Request Sent\n");
// free message
dbus_message_unref(msg);
// block until we recieve a reply
dbus_pending_call_block(pending);
// get the reply message
msg = dbus_pending_call_steal_reply(pending);
if (NULL == msg) {
fprintf(stderr, "Reply Null\n");
exit(1);
}
// free the pending message handle
dbus_pending_call_unref(pending);
// read the parameters
if (!dbus_message_iter_init(msg, &args))
fprintf(stderr, "Message has no arguments!\n");
else if (DBUS_TYPE_BOOLEAN != dbus_message_iter_get_arg_type(&args))
fprintf(stderr, "Argument is not boolean!\n");
else
dbus_message_iter_get_basic(&args, &stat);
if (!dbus_message_iter_next(&args))
fprintf(stderr, "Message has too few arguments!\n");
else if (DBUS_TYPE_UINT32 != dbus_message_iter_get_arg_type(&args))
fprintf(stderr, "Argument is not int!\n");
else
dbus_message_iter_get_basic(&args, &level);
printf("Got Reply: %d, %d\n", stat, level);
// free reply
dbus_message_unref(msg);
}
void reply_to_method_call(DBusMessage* msg, DBusConnection* conn)
{
DBusMessage* reply;
DBusMessageIter args;
bool stat = true;
dbus_uint32_t level = 21614;
dbus_uint32_t serial = 0;
char* param = "";
// read the arguments
if (!dbus_message_iter_init(msg, &args))
fprintf(stderr, "Message has no arguments!\n");
e