QNX SPI驱动

QNX驱动的入口从main开始,把每一个驱动看做一个进程模块。

int main(int argc, char *argv[])

{
spi_dev_t *head = NULL, *tail = NULL, *dev;
void *drventry, *dlhdl;
siginfo_t info;
sigset_t set;
int i, c, devnum = 0;


if (ThreadCtl(_NTO_TCTL_IO, 0) == -1) { /*获取IO控制权*/
perror("ThreadCtl");
return (!EOK);
}

      /*初始化连接函数,通过 iofunc_func_init()函数初始化,通过连接和POSIX默认IO结构层功能。有关默认函数的信息,*/
_spi_init_iofunc();

/*获取 配置选项参数,通过build 相关命令可以配置SPI相关参数*/
while ((c = getopt(argc, argv, "u:d:")) != -1) {
switch (c) {
case 'u':
devnum = strtol(optarg, NULL, 0);
break;
case 'd':/*加载SPI驱动 以动态链接库方式加载 直接和底层相关*/
if ((drventry = _spi_dlload(&dlhdl, optarg)) == NULL) {
perror("spi_load_driver() failed");
return (-1);
}


do {
if ((dev = calloc(1, sizeof(spi_dev_t))) == NULL)
goto cleanup;

if (argv[optind] == NULL || *argv[optind] == '-')
dev->opts = NULL;
else
dev->opts = strdup(argv[optind]);
++optind;
dev->funcs  = (spi_funcs_t *)drventry;/**/
dev->devnum = devnum++;
dev->dlhdl  = dlhdl;


i = _spi_create_instance(dev);/*创建线程*/


if (i != EOK) {
perror("spi_create_instance() failed");


if (dev->opts)
free(dev->opts);


free(dev);
goto cleanup;
}


if (head) {
tail->next = dev;
tail = dev;
}
else
head = tail = dev;
} while (optind < argc && *(optarg = argv[optind]) != '-'); 


/* 
* Now we only support one dll
*/
goto start_spi;


break;
}
}


start_spi:
if (head) {
/* background the process */
procmgr_daemon(0, PROCMGR_DAEMON_NOCLOSE | PROCMGR_DAEMON_NODEVNULL);


sigemptyset(&set);
sigaddset(&set, SIGTERM);


for (;;) {
if (SignalWaitinfo(&set, &info) == -1)
continue;


if (info.si_signo == SIGTERM)
break;
}
}


cleanup:
dev=head;
while (dev) {
if (dev->ctp) {
dispatch_unblock(dev->ctp);


}


if (dev->drvhdl) {
resmgr_detach(dev->dpp, dev->id, _RESMGR_DETACH_ALL);
dev->funcs->fini(dev->drvhdl);
}


if (dev->dpp) {
dispatch_destroy(dev->dpp);
}


head = dev->next;


if (dev->opts)
free(dev->opts);


free(dev);
dev=head;
}


dlclose(dlhdl);


return (EOK);
}

猜你喜欢

转载自blog.csdn.net/u011996698/article/details/79536679
今日推荐