linux嵌入式驱动架构,嵌入式系统最小驱动框架(类似linux驱动程序架构)

2010年就打算把linux里的驱动框架核心代码抠出来的,但是由于懒而且linux代码量大,一直下不了手。最近调试的intel curie里驱动架构也类似linux,代码就少多了,由于工作需要不得不梳理一下这一堆代码,今天花了一下午,把整个BSP部分的驱动核心抽离出来了,并且做了几个小sample。

最小驱动框架核心代码

1、设备管理

device.c

#include #include#include#include#include#include"../../bsp/soc/soc_config.h"#include"../../bsp/soc/device.h"

static struct td_device **all_devices =NULL;static uint32_t all_devices_count = 0;void init_devices(struct td_device **_all_devices, uint32_t _all_devices_count)

{if (all_devices !=NULL)/*Devices already init*/

return;/*Link array with root device*/all_devices=_all_devices;

all_devices_count=_all_devices_count;

uint32_t i;int ret = 0;for (i = 0; i < all_devices_count; ++i)

{struct td_device *dev =all_devices[i];if (dev->driver->init && (ret = dev->driver->init(dev)))

{

dev->powerstate =PM_NOT_INIT;

printf("dev(%d) is not init",dev->id);

}

dev->powerstate =PM_RUNNING;

}

}static voidresume_devices_from_index(uint32_t i)

{int ret = 0;struct td_device *dev =NULL;for (; i < all_devices_count; ++i)

{

dev=all_devices[i];

printf("resume device %d", dev->id);if (dev->powerstate <=PM_SHUTDOWN)

{

ret= -EINVAL;gotoerr_resume_device;

}if (dev->powerstate ==PM_RUNNING)/*Device already running*/

continue;if (dev->driver->resume && (ret = dev->driver->resume(dev)))gotoerr_resume_device;/*Current device resumed*/dev->powerstate =PM_RUNNING;

}return;

err_resume_device:

printf("failed to resume device %d (%d)", dev->id,ret);

}void resume_devices(void)

{

resume_devices_from_index(0);

}intsuspend_devices(PM_POWERSTATE state)

{

int32_t i;int ret = 0;/*Use the reverse order used for init, i.e. we suspend bus devices first,

* then buses, then top level devices*/

for (i = all_devices_count - 1; i >= 0; --i)

{struct td_device *dev =all_devices[i];//device already suspended

if (dev->powerstate <=state)continue;

printf("suspend dev %d", dev->id);if (!dev->driver->suspend)

{

dev->powerstate =state;continue;

}

ret= dev->driver->suspend(dev, state);if (!ret)

{

dev->powerstate =state;continue;

}break;

}if (!ret)return 0;/*Suspend aborted, resume all devices starting from where we had

* an issue*/

if (state >PM_SHUTDOWN)

resume_devices_from_index(i+ 1);return -1;

}

device.h

#ifndef __DEVICE_H_#define __DEVICE_H_#includetypedefenum{

PM_NOT_INIT= 0,

PM_SHUTDOWN,

PM_SUSPENDED,

PM_RUNNING,

PM_COUNT

} PM_POWERSTATE;structtd_device;structdriver;//struct __packed __aligned(4) td_device

structtd_device

{void *priv;struct driver *driver;

PM_POWERSTATE powerstate :8;

uint8_t id;

};structdriver

{int (*init)(struct td_device *dev);int (*suspend)(struct td_device *dev, PM_POWERSTATE state);int (*resume)(struct td_device *dev);

};intsuspend_devices(PM_POWERSTATE state);void resume_devices(void);void init_devices(struct td_device **all_devices, uint32_t all_devices_count);void init_all_devices(void);#endif

2、驱动程序配置文件,我这里配置了WDT , CLK , TEST 三个简单的驱动程序。

soc_config.c

#include #include#include#include#include"../soc/soc_config.h"#include"../soc/device.h"#include"../driver/wdt/wdt.h"#include"../driver/clk/clk.h"#include"../driver/test/test.h"typedefenum{

WDT_ID= 0,

CLK_ID=1,

TEST_ID=2,

} DEVICE_ID;struct td_device pf_device_wdt ={

.id=WDT_ID,

.driver= &watchdog_driver,

.priv= &(structwdt_pm_data){

.a= 1,

.b=2,

},

};struct td_device pf_device_clk ={

.id=CLK_ID,

.driver= &clk_driver,

.priv= &(structclk_data){

.a=5,

.b=6,

},

};struct td_device pf_device_test ={

.id=TEST_ID,

.driver= &test_driver,

.priv= &(structtest_data){

.a=3,

.b=4,

},

};static struct td_device *qrk_platform_devices[] ={&pf_device_wdt,&pf_device_clk,&pf_device_test,

};#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))

void init_all_devices(void)

{/*Init plateform devices and buses*/init_devices(qrk_platform_devices, ARRAY_SIZE(qrk_platform_devices));

}

soc_config.h

#ifndef __SOC_CONFIG_H_#define __SOC_CONFIG_H_

extern structtd_device pf_device_wdt;extern structtd_device pf_device_clk;extern structtd_device pf_device_test;#endif

3、以上就是驱动架构的最小系统,下面添加一个驱动程序例子test_driver

test.c

#include #include#include"../../soc/soc_config.h"#include"../../soc/device.h"#include"../../driver/test/test.h"

int test_init(struct td_device *dev)

{return 0;

}static int test_suspend(struct td_device *dev, PM_POWERSTATE state)

{return 0;

}static int test_resume(struct td_device *dev)

{return 0;

}struct driver test_driver ={

.init=test_init,

.suspend=test_suspend,

.resume=test_resume

};

test.h

#ifndef _TEST_H_#define _TEST_H_#include

extern structdriver test_driver;structtest_data

{

uint32_t a;

uint32_t b;

};#endif

5、再写个驱动程序调用实例

main.c

#include #include"../bsp/soc/device.h"#include"../bsp/soc/soc_config.h"#include"../bsp/driver/test/test.h"

intmain()

{//driver framework test!

init_all_devices();//driver struct test!

struct td_device *test_device =(struct td_device *)&pf_device_test;

printf("\r\n===test device(%d) ok!===\r\n",test_device->id);//driver api test!

struct driver *test_driver = (struct driver *)test_device->driver;if(test_driver->init(wdt_device)==0) printf("test init ok!\n");//driver data test!

struct test_data *data = (struct test_data *)test_device->priv;

printf("test_data a:%d,b:%d!\n",data->a,data->b);return 0;

}

用code::blocks可以直接编译运行。

原文:http://www.cnblogs.com/dong1/p/6786056.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值