S12X Function pointers to paged flash.

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

S12X Function pointers to paged flash.

跳至解决方案
3,518 次查看
quasio
Contributor I

Hi All,

I'm trying to store a long/far address in a variable, cast and then jump to that specific address. with the code below:

 

uint32_t appl_start_address;  

appl_start_address = 0x701234;  
((void(*_far) (void))(appl_start_address))();

 

in the debugger, it does the FCALL, but the PC seems to only go to 7012, and the PPAGE is set to 34.

Shouldn't the Program at least jump to address 0x347012?

 

Essentially i would like to jump and run program at address 0x701234. however, so i'm doing something majorly wrong.

 

thanks in advance.

 

Regards

Quasio

 


标签 (1)
标记 (1)
0 项奖励
回复
1 解答
1,749 次查看
stanish
NXP Employee
NXP Employee

quasio,

 

I'd suggest you to use logical addresses in this case since global addresses can be used to access data only (not call subroutines).

 

Banked function pointer allocation expects page pointer located at third position. So if you change the application start address to 0x9234C0 it should work.

 

appl_start_address =  0x9234C0; // 0xC0_9234'L = 0x701234'G;

((void(* far) (void))(appl_start_address))();
  

 

Stanish

在原帖中查看解决方案

0 项奖励
回复
4 回复数
1,750 次查看
stanish
NXP Employee
NXP Employee

quasio,

 

I'd suggest you to use logical addresses in this case since global addresses can be used to access data only (not call subroutines).

 

Banked function pointer allocation expects page pointer located at third position. So if you change the application start address to 0x9234C0 it should work.

 

appl_start_address =  0x9234C0; // 0xC0_9234'L = 0x701234'G;

((void(* far) (void))(appl_start_address))();
  

 

Stanish

0 项奖励
回复
1,749 次查看
quasio
Contributor I

Ah that worked well.

 

So whats the best way to convert global addresses to logical addresses during runtime?

Is there a macro or a function i can use?

 

 

Message Edited by quasio on 2009-09-01 02:29 AM
0 项奖励
回复
1,749 次查看
CompilerGuru
NXP Employee
NXP Employee

If possible avoid the conversions.

 

The plain global to paged conversion can is done by the compiler when assigning a global (__far) data pointer to a paged data pointer, see the code below.

 

Note that no conversion is done from or to function pointers and in addition function pointers use a different byte ordering so when using data pointers the bytes have to be swapped before used as function pointer.

 

Why do you have to convert a global to a __far function pointer?

 

Daniel

 

 

 

void* __far far_ptr;void* __pptr p_ptr;long long_log_addr;long far_adr = 0x701234;long long_log_addr2;void main(void) {  far_ptr = (void* __far)0x701234;  p_ptr = (void* __pptr)far_ptr;  long_log_addr = (long)p_ptr;  long_log_addr2 = (long) (void* __pptr) (void* __far) far_adr;    for(;;) {}}

 

 

 

0 项奖励
回复
1,749 次查看
kef
Specialist I

You may use this macro to convert from global appl_start_address to PPAGE banked appl_start_address:

 

#define GLOBAL2LOGICAL(x) (((x & 0x3FFFul | 0x8000) << 8) | ((x >> 14) & 0xFF))

PPAGE = global_address / size_of_ppage_window & 0xFF

PPAGE offset = global_address % size_of_ppage_window + start_of_ppage_window(=0x8000)

 

0 项奖励
回复