WX:jump_table

第一次接触dialog 
看SDK代码注意到一个有意思的数组 jump_table_base
并且第二个成员是main函数
现在仅凭个人经验分析一下
注意它是一个数组哦!
const uint32_t* const jump_table_base[92] __attribute__((section("jump_table_mem_area"))) =
        {
                (const uint32_t*) TASK_APP,                  
                (const uint32_t*) main_func,   
                 XXXXX
		}				
既然是数组那么每个成员都是	uint32_t *
它对于 数据 和 函数 不做区分 统统放进去!

1---这样做是干啥呢?	
官方工程师的回答
https://support.dialog-semiconductor.com/jumptablebase88
The jump_table is an array in retention memory where pointers to different functions and variables are stored. 
This memory area is powered even in Deep Sleep mode and will retain its content.

It is not advised to make changes to this array 

2---函数如何调用呢?
参考
jump table usage
https://stackoverflow.com/questions/9932212/jump-table-examples-in-c
小弟不才曾经写过一个复旦微电子FM1208的CPU的操作模块 和上位机对应的 乱点鸳鸯谱 原来学名叫做函数指针jumptable
XXXXXX
但是 这样的操作 需要数组的每一个成员都是函数!

现在dialog 这个数组每个都是U32* 
现在测试一下 它的好处


#include<stdio.h>
#include <string.h>
typedef unsigned char  uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int   uint32_t;


typedef void (*Cmdfunc)(void);
#define SHOWME  rt_kprintf("---%s--%d---\n",__FUNCTION__,__LINE__);
void fun0(void){SHOWME}
void fun1(void){SHOWME}
void fun2(void){SHOWME} 
void jumptest()
{
    Cmdfunc FunList[3]={fun0,fun1,fun2};
    for(int i=0;i<3;i++)
        FunList[i]();

}

int main(void)
{
	jumptest();
    return 0;
}


typedef void (*Cmdfunc)(void);
typedef int  (*Cmdfunc2)(void);

#define SHOWME  rt_kprintf("---%s--%d---\n",__FUNCTION__,__LINE__);
void fun0(void){SHOWME}
void fun1(void){SHOWME}
int  fun2(void){SHOWME} 
void jumptest()
{
	uint32_t* FunList[3]={(uint32_t*)fun0,(uint32_t*)fun1,(uint32_t*)fun2};

	Cmdfunc pf;
	Cmdfunc2 pf2;
	pf  = (Cmdfunc)FunList[0];
	pf2 = (Cmdfunc2)FunList[2];
	pf();
	pf2();

}


这样的好处是可以差异化!!!FunList 只是中间桥梁而已
比如先是Cmdfunc fun0--在转为uint32_t放在数组--在转回Cmdfunc执行
所以中间的数组写为	uint32_t FunList[3]={(uint32_t)fun0,(uint32_t)fun1,(uint32_t)fun2};
也是没有问题!!!

http://blog.sina.cn/dpool/blog/s/blog_abee94340102xdox.html 
描述了main函数的调用


想到另外一个JUMP的问题

以前项目在STM32OTA升级 有这个函数

void jump_application( void )
{
    if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x1FFE0000 ) == 0x10000000) //stack use ram1
    {
      log(DEBUG,"跳转至应用程序\n\n\n");
      /* Jump to user application */
      __set_PRIMASK(1); //must be close en all
      JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
      JumpToApplication = (pFunction) JumpAddress;
      /* Initialize user application's Stack Pointer */
      __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
      JumpToApplication();
    } 
    else  
    {  
        log(DEBUG,"没有应用程序\n");  
    } 
}
或者
typedef  void (*iapfun)(void);				
iapfun jump2app; 
void iap_load_app(uint32_t appxaddr)
{//*(uint32_t*)appxaddr = 0X20017450
	printf("[%08x]--[%08X]\r\n",*(uint32_t*)appxaddr,((*(uint32_t*)appxaddr)&0x2FFE0000));
	if(((*(uint32_t*)appxaddr)&0x2FFE0000)==0x20000000)	//¼ì²éÕ»¶¥µØÖ·ÊÇ·ñºÏ·¨.
	{ 
		__set_PRIMASK(1);//ûÓÐÕâ¾ä»°-¹Ø±ÕÖжÏ-¾Í»áÌøתʧ°Ü£¡£¡
		printf("--JUMP--\r\n");
		jump2app=(iapfun)*(uint32_t*)(appxaddr+4);		//Óû§´úÂëÇøµÚ¶þ¸ö×ÖΪ³ÌÐò¿ªÊ¼µØÖ·(¸´Î»µØÖ·)		
		MSR_MSP(*(uint32_t*)appxaddr);					      //³õʼ»¯APP¶ÑÕ»Ö¸Õë(Óû§´úÂëÇøµÄµÚÒ»¸ö×ÖÓÃÓÚ´æ·ÅÕ»¶¥µØÖ·)
		jump2app();									                  //Ìøתµ½APP.
	}
}	


我能不能这样 把一个函数放在绝对的地址 然后在调用这个地址呢?


#define SHOWME  rt_kprintf("---%s--%d---\n",__FUNCTION__,__LINE__);
void kfun(void) __attribute((section(".ARM.__at_0x08008000")));
void kfun(void)
{SHOWME}

typedef  void (*iapfun)(void);		
	
int main(void)
{
	  kfun();//可以执行成功
	  iapfun jump2app; 
	  jump2app=(iapfun) *(uint32_t*)(0x08008000);
	  jump2app();	//马上死机	
      return 0;
}

看上去 是函数 放在绝对地址 这个操作有问题

可以把函数放在绝对地址吗?

 

 

 

地址有问题!!

#define SHOWME  rt_kprintf("---%s--%d---\n",__FUNCTION__,__LINE__);
void kfun(void){SHOWME}

typedef  void (*iapfun)(void);		
int main(void)
{
	  kfun();
	  iapfun jump2app; 
	  uint32_t   JumpAddress = ( uint32_t) (kfun);
	  jump2app=(iapfun) JumpAddress;
	  jump2app();	
    return 0;
}



#define SHOWME  rt_kprintf("---%s--%d---\n",__FUNCTION__,__LINE__);
void kfun(void){SHOWME}

typedef  void (*iapfun)(void);		
int main(void)
{
	  kfun();
	  iapfun jump2app; 
	  uint32_t   JumpAddress = ( uint32_t) (&kfun);
	  jump2app=(iapfun) JumpAddress;
	  jump2app();	
    return 0;
}





#define SHOWME  rt_kprintf("---%s--%d---\n",__FUNCTION__,__LINE__);
void kfun(void) __attribute((section(".ARM.__at_0x08000140")));
void kfun(void){SHOWME}

typedef  void (*iapfun)(void);		
int main(void)
{
	  kfun();
	  iapfun jump2app; 
	  uint32_t   JumpAddress = ( uint32_t) (&kfun);
	  jump2app=(iapfun) JumpAddress;
	  jump2app();	
    return 0;
}

下面也可以!
void kfun(void) __attribute((section(".ARM.__at_0x08000200")));
main.o(.text) refers to main.o(.ARM.__at_0x08000200) for kfun
kfun                                     0x08000201   Thumb Code    14  main.o(.ARM.__at_0x08000200)







可以写到绝对地址 但是自动偏移一位!!!
#define SHOWME  rt_kprintf("---%s--%d---\n",__FUNCTION__,__LINE__);
void kfun(void) __attribute((section(".ARM.__at_0x08000200")));
void kfun(void){SHOWME}

typedef  void (*iapfun)(void);		
int main(void)
{
	  kfun();
	  iapfun jump2app; 
	#if 1 
  	uint32_t   JumpAddress = ( uint32_t) (kfun);
		jump2app=(iapfun) JumpAddress;
	#else
	  jump2app=(iapfun) 0x08000201;//WHY 这里+1了?MAP文件也是的
	#endif
	  rt_kprintf("--0X%X---\n",jump2app);
	  jump2app();	
    return 0;
}

         我想写一个函数放在绝对地址  然后用指针去指向这个地址调用 实际我发现这个函数好像会自动偏移一个字节  这是为啥呢

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值