使用HAL开发硬件监控程序

使用HAL开发硬件监控程序
     在开发系统的时候经常会遇到支持hot-plug的硬件,例如USB设备,如果需要对系统的硬件进行管理,或一些依赖硬件的程序就需要知道硬件的状态,而通用的系统调用一般和平台有一定关系,缺乏移植性,这里我在开发中发现使用HAL(硬件抽象层)可以解决这个问题。
这里先简单介绍一下HAL:
它是一个位于操作系统和驱动程序之上,运行在用户空间中的服务程序。
它的目的是对上层应用提供一个统一的简单的查询硬件设备的接口。它所谓的抽象,基本上也就仅限于这一功能,它通常并不提供对硬件的实际操作,对硬件的操作,还是由应用程序来完成。
细化来说,除了提供标准的硬件查询接口,它甚至并不考虑如何对硬件进行配置,这不是它要完成的工作,但它确实提供了存储硬件配置相关信息的空间。下面我们会说到,那被称为属性。
所以,简单的说,你可以把HAL理解为:一堆的硬件列表以及他们的相关属性的集合。
那么,这一堆硬件列表能有什么用呢?应该说,它简化了应用的查询逻辑,把这一部分的复杂性转移到了应用程序之外,由HAL统一处理,其次,当一些库函数也开始使用HAL的时候,应用程序甚至可以把对不同硬件的实际操作的复杂性也交给库函数来自动处理。

这里我用一个简单的程序来说明一下HAL的开发,非常的简单
需求:检测USB无线网卡的插拔
static LibHalContext *hal_ctx = NULL;
static char * g_udi = "";
int check()
{
  struct   ifreq   ifr;  
  struct   ethtool_value   edata;  
  char * ifname="eth1";
  int netfd=socket(AF_INET,SOCK_DGRAM,0);
  memset(&ifr,   0,   sizeof(ifr));  
  edata.cmd   =   ETHTOOL_GLINK;  
   
  strncpy(ifr.ifr_name,   ifname,   sizeof(ifr.ifr_name)-1);  
  ifr.ifr_data   =   (char   *)   &edata;  
   
  if(ioctl(netfd,   SIOCETHTOOL,   &ifr)   ==   -1){  
  printf("ETHTOOL_GLINK   failed:   %s/n",   strerror(errno));  
  return   2;  
  }  
  return(edata.data   ?   0   :   1); 
}

static void
print_props (LibHalContext * ctx,const char *udi ,int add)
{
    DBusError error;
    LibHalPropertySet *props;
    LibHalPropertySetIterator it;
    int type;

    dbus_error_init (&error);
    if (!add && !strcmp(g_udi,udi))
    {
        printf("[liyou]****************wireless removed***********************/n");
        system ("up_to_down_wireless");
    }
    props = libhal_device_get_all_properties (hal_ctx, udi, &error);

    /* NOTE : This may be NULL if the device was removed
     *        in the daemon; this is because
     *        hal_device_get_all_properties() is a in
     *        essence an IPC call and other stuff may
     *        be happening..
     */
    if (props == NULL) {
        LIBHAL_FREE_DBUS_ERROR (&error);
        return;
    }

    libhal_property_set_sort (props);

    for (libhal_psi_init (&it, props); libhal_psi_has_more (&it); libhal_psi_next (&it)) {
        type = libhal_psi_get_type (&it);
        switch (type) {
        case LIBHAL_PROPERTY_TYPE_STRING:
            printf ("  %s = '%s'  (string)/n",
                libhal_psi_get_key (&it),
                libhal_psi_get_string (&it));
            if (!strcmp(libhal_psi_get_key (&it),"info.category") &&
                !strcmp(libhal_psi_get_string (&it),"net.80211"))
            {
                g_udi=strdup(udi);
                printf("[liyou]**********************************wireless device added*************/n");
                system();
            }
            break;

        default:
        //    printf ("Unknown type %d=0x%02x/n", type, type);
            break;
        }
    }

    libhal_free_property_set (props);
}

static void device_added(LibHalContext * ctx,const char * udi)
{
    printf("device added  %s/n",udi);
    print_props(ctx,udi,TRUE);
}
static void device_removed(LibHalContext * ctx,const char * udi)
{
    printf("device removed %s/n",udi);
    print_props(ctx,udi,FALSE);
}
static void libhal_init()
{

    DBusConnection *conn = dbus_bus_get(DBUS_BUS_SYSTEM,NULL);
    if(!conn)
    {
        printf("conn == null/n");
    }
    dbus_connection_setup_with_g_main(conn,NULL);
    if (hal_ctx != NULL)
    {
        printf("hal_ctx == NULL/n");
        return;
    }
    hal_ctx = libhal_ctx_new();
   
    if (libhal_ctx_set_dbus_connection(hal_ctx,conn) == FALSE)
    {
        printf("set_dbus_connection/n");
        libhal_ctx_free(hal_ctx);
        return;
    }
    if(libhal_ctx_init(hal_ctx,NULL) == FALSE)
    {
        printf("ctx_init/n");
        libhal_ctx_free(hal_ctx);
        return;
    }
    libhal_ctx_set_device_added(hal_ctx,device_added);
    libhal_ctx_set_device_removed(hal_ctx,device_removed);
    libhal_device_property_watch_all(hal_ctx,NULL);
}

你可能感兴趣的:(其它技术)