Boot固化部分API函数

因为我现在使用的单片机使用了大量原厂提供的库函数和标准初始化例程,而这一部分例程很大程度上都是通用的,而且无论是在boot里还是APP1还是APP2都要调用这部分程序,那为什么不将这部分共用的程序都放在同一片FLASH里,通过某种方式统一调用呢?

而实现这种方法的方式其实非常简单就是使用函数指针,只要函数指针指能够指向对应API所在Flash的地址,就能实现相应的功能。

具体方法如下:在boot中的某个位置固定好函数映射的地址表,然后再APP中调用

/*boot中使用*/
#if ThisBoot==1
/*----------------------------------------------------------------------
//固化API函数表
-----------------------------------------------------------------------*/
const uint32_t func_table[] __attribute__((section(".ARM.__at_0x00001000"))) = 
{ 	
	//注:这里会存在一些警告,无可避免
  //注:顺序要想改必须同步更改 API_xxx_Loc
	#if API_UseADC>0
	(uint32_t)&API_ADC,
	#else
	(uint32_t)API_ADC_Loc, //如果不用于占位
	#endif
	#if API_UseETIM>0
	(uint32_t)&API_Etim_Init,
	#else
	(uint32_t)API_ETIM_Loc,//如果不用于占位
	#endif
	#if API_UseIIC>0
	(uint32_t)&API_I2C_Init,
	(uint32_t)&API_EEPROM_Read,
	(uint32_t)&API_EEPROM_Write,
	#else
	(uint32_t)API_I2C_Init_Loc,//如果不用于占位
	(uint32_t)API_I2C_Read_Loc,
	(uint32_t)API_I2C_Write_Loc,
	#endif
	#if API_UseLPTIM>0
	(uint32_t)&API_LPTIM_Init,
	#else
	(uint32_t)API_LPTIM_Loc,//如果不用于占位
	#endif
	#if API_UseRTC>0  
	(uint32_t)&API_RTC_Init,
	(uint32_t)&API_GetTime,
	(uint32_t)&API_SetTIME,
	#else
	(uint32_t)API_RTC_Init_Loc,//如果不用于占位
	(uint32_t)API_GetTime_Loc,
	(uint32_t)API_SetTIME_Loc,
	#endif
	#if API_UseUart>0
	(uint32_t)&API_Uartx_Init,
	(uint32_t)&API_Uart_Send,
	#else
	(uint32_t)API_Uart_Init_Loc,//如果不用于占位
	(uint32_t)API_Uart_Send_Loc,
	#endif
	#if API_UseLPUart>0
	(uint32_t)&API_LPUart_Init,
	(uint32_t)&API_LPUart_Send,
	#else
	(uint32_t)API_LPUart_Init_Loc,//如果不用于占位
	(uint32_t)API_LPUart_Send_Loc,
	#endif
	#if API_UseDataUp>0
	(uint32_t)&API_UpData,
	#else
	(uint32_t)API_UpData_Loc,
	#endif
	#if API_UseNB>0
	(uint32_t)&API_NB_Init,
	(uint32_t)&API_NB_Link,
	(uint32_t)&API_NB_Connect,
	(uint32_t)&API_NB_UartRx,
	(uint32_t)&API_NB_UartTx,
	(uint32_t)&API_NB_Clock,
	(uint32_t)&API_NB_End,
	(uint32_t)&API_NB_RxData,
	#else
	(uint32_t)API_NB_Init_Loc,      
	(uint32_t)API_NB_Link_Loc,      
	(uint32_t)API_NB_Connect_Loc,   
	(uint32_t)API_NB_UartRx_Loc,    
	(uint32_t)API_NB_UartTx_Loc,   
	(uint32_t)API_NB_Clock_Loc,     
	(uint32_t)API_NB_End_Loc, 
	(uint32_t)API_NB_RXDATA_Loc,	
	#endif
	#if API_UseLCD>0
	(uint32_t)&API_Init_LCD,
	#else
	(uint32_t)API_LCD_Loc,
	#endif
	
	#if API_UseAES>0
	(uint32_t)&API_AES,
	#else
	(uint32_t)API_AES_Loc,
	#endif
	
	#if API_UseIIC>0
	(uint32_t)&G_I2C_Read_Contin_Step,
	(uint32_t)&G_I2C_Write_Contin_Step,
	#else
	(uint32_t)API_I2C_Read_Com_Loc,//如果不用于占位
	(uint32_t)API_I2C_Write_Com_Loc,
	#endif
	
  (uint32_t)99		
};

/*----------------------------------------------------------------------
//固化SYS函数表,不可更改
-----------------------------------------------------------------------*/
const uint32_t sys_table[] __attribute__((section(".ARM.__at_0x00000950"))) = 
{
	(uint32_t)&TicksDelayMs,
	(uint32_t)&TicksDelayUs,
	(uint32_t)&AnalogIO,
	(uint32_t)&InputtIO,
	(uint32_t)&OutputIO,
	(uint32_t)&AltFunIO,
	(uint32_t)&CloseeIO,
	(uint32_t)&Init_System, 
	(uint32_t)&Sleep,
	(uint32_t)&RchfAdjust
};
#endif

然后定义好函数指针,在APP中使用,方法如下

/*在APP中调用固化在boot中的函数*/
#if API_UseIIC>0
void API_I2C_Init(void)
{
	api_iicinit iic=(void (*)(void))(table_base[API_I2C_Init_Loc] | 0x1);
	iic();
}

uint08 API_EEPROM_Read(uint08 Device, uint16 Addr, uint08 AddrLen, uint08 *Buf, uint16 Len)
{
	api_iicop iicrd=(uint08 (*)(uint08 Device, uint16 Addr, uint08 AddrLen, uint08 *Buf, uint16 Len))(table_base[API_I2C_Read_Loc] | 0x1);
	return iicrd(Device,Addr,AddrLen,Buf,Len);
}

uint08 API_EEPROM_Write(uint08 Device, uint16 Addr, uint08 AddrLen, uint08 *Buf, uint16 Len)
{
	api_iicop iicwt=(uint08 (*)(uint08 Device, uint16 Addr, uint08 AddrLen, uint08 *Buf, uint16 Len))(table_base[API_I2C_Write_Loc] | 0x1);
	return iicwt(Device,Addr,AddrLen,Buf,Len);
}

uint08 API_I2C_Read_Com(uint08 Device, uint16 Addr, uint08 AddrLen, uint08 *Buf, uint16 Len)
{
	api_iicop iicrd=(uint08 (*)(uint08 Device, uint16 Addr, uint08 AddrLen, uint08 *Buf, uint16 Len))(table_base[API_I2C_Read_Com_Loc] | 0x1);
	return iicrd(Device,Addr,AddrLen,Buf,Len);
}

uint08 API_I2C_Write_Com(uint08 Device, uint16 Addr, uint08 AddrLen, uint08 *Buf, uint16 Len)
{
	api_iicop iicwt=(uint08 (*)(uint08 Device, uint16 Addr, uint08 AddrLen, uint08 *Buf, uint16 Len))(table_base[API_I2C_Write_Com_Loc] | 0x1);
	return iicwt(Device,Addr,AddrLen,Buf,Len);
}
#endif

通过这种方式,原先APP需要50K左右的代码量,减少至20K,boot原先16K代码量增至进40K,如果不使用外挂Flash远程升级APP2,可以节约很多空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜暝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值