在keil环境下实现类似linux中 module_exit module_init的效果


在使用keil开发较大的项目时常常存在驱动之间耦合性太大,增加或减少驱动会涉及到对工程中其他部分代码的更改,比如新增一个驱动需要把初始化代码放到main函数中执行,去除一个驱动又需要在main函数中去掉对应的函数调用,本例方法可降低驱动代码之间的耦合性。

一,设置keil为使用加载文件

keil设置

二,编写链接脚本

LR_IROM1 0x08020000 0x001E0000  {    ; load region size_region
  ER_IROM1 0x08020000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
   my_section0 +0 {
	*.o(my_section0)
   }
   my_section1 +0{
	*.o(my_section1)
   }
   my_section2 +0{
	*.o(my_section2)
   }
  RW_IRAM1 0x20000008 0x0009FFF8  {  ; RW data
   .ANY (+RW +ZI)
  }
}

三,定义module_exit module_init 宏

struct my_model_struct
{
	void (*init)(void);
	void (*exit)(void);
	void (*enter_lp)(void);
	void (*exit_lp)(void);
};






//定义节调用结构体
struct my_section_struct
{
	char *name;
	struct my_model_struct *model;
};


//定义总线节
#define bus_extern(model_,name_) \
const static struct my_section_struct model_##_extern __attribute__((used,section("my_section0"))) =\
{\
	.name=name_,\
	.model=(struct my_model_struct *)&model_,\
}



//定义驱动节
#define driver_extern(model_,name_) \
const static struct my_section_struct model_##_extern __attribute__((used,section("my_section1"))) =\
{\
	.name=name_,\
	.model=(struct my_model_struct *)&model_,\
}



//定义设备节
#define device_extern(model_,name_) \
const static struct my_section_struct model_##_extern __attribute__((used,section("my_section2"))) =\
{\
	.name=name_,\
	.model=(struct my_model_struct *)&model_,\
}

四,编写统一初始化函数

//声明初始化节的地址和长度
extern const unsigned int Load$$my_section0$$Base;
extern const unsigned int Load$$my_section0$$Length;

extern const unsigned int Load$$my_section1$$Base;
extern const unsigned int Load$$my_section1$$Length;

extern const unsigned int Load$$my_section2$$Base;
extern const unsigned int Load$$my_section2$$Length;


/******************************************************

			在指定section中定义变量

#pragma arm section rodata = "my_init_start"
const static unsigned int g_my_init_start;
#pragma arm section     
#pragma arm section rodata = "my_init_end"
const static unsigned int g_my_init_end;
#pragma arm section     

*******************************************************/




//运行初始化节
void my_section_do_init (void)
{
	
	//首先初始化总线
	struct my_section_struct *start=(struct my_section_struct *)&Load$$my_section0$$Base;
	int length=(unsigned int)&Load$$my_section0$$Length;
	int num=length/sizeof (struct my_section_struct);
	
	for (int i=0;i<num;i++)
	{
		struct my_model_struct *model=start->model;
		if (model->init) 
			model->init();
		start++;
	}
	
	//然后初始化驱动
	start=(struct my_section_struct *)&Load$$my_section1$$Base;
	length=(unsigned int)&Load$$my_section1$$Length;
	num=length/sizeof (struct my_section_struct);
	
	for (int i=0;i<num;i++)
	{
		struct my_model_struct *model=start->model;
		if (model->init) 
			model->init();
		start++;
	}

	//最后初始化设备
	start=(struct my_section_struct *)&Load$$my_section2$$Base;
	length=(unsigned int)&Load$$my_section2$$Length;
	num=length/sizeof (struct my_section_struct);
	
	for (int i=0;i<num;i++)
	{
		struct my_model_struct *model=start->model;
		if (model->init) 
			model->init();
		start++;
	}
}

五,编写驱动时在文件中加入类似代码

void mymem_init (void)
{
	mem_init ();
	exmem_init( );
}

const static struct my_model_struct mymem_model=
{
	.init=mymem_init,
};


device_extern(mymem_model,"mymem");

六,在main函数中调用

在main函数中调用 my_section_do_init () 函数即可对所有驱动进行初始化,实现驱动模块之间的去耦合。

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值