CH549的pdata实际地址问题

我的某个xdata数组跨越了1024地址,然后我就发现从1024往后的几个字节会被莫名其妙篡改。

经检查,发现定义的几个pdata实际就在这几个字节,所以pdata是不是实际是映射到了从1024开始位置?

但问题是编译器似乎以为pdata是映射到了xdata的0地址?

因为我尝试声明UINT8X test[256] _at_ 0;编译器直接报错说:

*** ERROR L107: ADDRESS SPACE OVERFLOW

    SPACE:   PDATA

说pdata没空间可用了

但声明UINT8X test[256] _at_ 1024;编译却通过了。


所以关于pdata的实际地址,我希望能确认一下。

这样测试没有出现报错。

image.png

上面的变量定义后,查看MAP文件:

image.png

因为前面Xdata指定了从0地址开始,Pdata从0x100开始。

您可以再检查下代码是否还有其他变量指定了0地址导致报错。



你好,我把工程删减到几乎最简,依然是会出现我说的错误的,附上截图和工程附件:

image.png

icon_rar.gifTest.zip

然后就是,pdata是xdata的其中256字节,那么pdata这256字节究竟在CH549的2048字节的xdata的什么位置?



取消勾选这个选项,即可编译成功

image.png

在勾选这个选项时,查看map文件,发现pdata声明的变量会默认设置0地址开始,因此当Xdata定义 _at_ 0时会出现报错现象。
image.png



你好,换链接器是可以编译成功,但是我觉得还是有问题,比如以下代码:

image.png

我已经把2k的xdata全部占满,但是它还是能编译成功,而且直接把这个pdata放到了2048这个超出芯片内存的地址:

image.png

看起来用这个链接器它就不在乎芯片真实的内存大小,我试了只有总量超过64k无法分配地址了它才会报错。

如果我写 UINT8X arrayU8X[1024*64-1] _at_ 0;

那么m51文件里它甚至会写  X:FFFFH         PUBLIC        testU8P  也即把它扔到物理不存在的最后一个字节。


然后就是,我用循环查找到这个pdata的真实位置然后打印输出,它和m51里写的也是对不上的,你们可以试一下,感谢

icon_rar.gifTest20241102.zip


您好

超过手册描述范围的RAM肯定是不能使用的,编译器可以加上对RAM的真实地址限制,这样可以提醒您使用超范围。
image.png


你好,感谢提示。超过芯片内存我肯定是不会用的哈。

但是我的主要问题不在这里,主要是我对pdata实际的地址感到疑惑。

比如把这个工程里改为UINT8X arrayU8X[1024] _at_ 0;这样不超范围

这时m51里写的是 X:0400H         PUBLIC        testU8P,看上去把pdata放到1024地址了

但是重点是,我把xdata清空,然后仅把pdata那一字节置1,然后用循环查找它的位置,

看串口打印,会输出1792,即2048-256,这是很奇怪的

image.png


you are using pdata the wrong way! pdata is a special fast way to access xdata. You need to modify startup.a51 and set the pdata page address in BL51 locate option if you want to use it.


pdata.png


@usbman

Thanks! I realized that my understanding of PDATA was insufficient.

I tried to find startup.a51, but there are multiple startup.a51 in "C51" folder in the installation directory.

I tried to find which one was used by removing them one by one and clicking "build", but after removing all of them, I was still able to build successfully...

However, I found another keypoint (Also my knowledge blind spot):

P2 register selects the page that PDATA use (I have been wondering these days that no matter how the compiling and linking process goes, there must be a register in the hardware that determines the page used by PDATA. Now I know it's P2).

CH549 has 2k XRAM, which means 8 pages (256B/page), so bit2~bit0 in P2 register are effective for this.

The default value of P2 is 0xFF, so bit2~bit0 = 0x07, and that means the last page is selected, which explains the printed number "1792".

When P2 is 0x04, PDATA start from 1024, and this corresponds exactly to when I first encountered the problem.


for the E51 core it does not make sense to deal with pdata. I dont know why WCH is still using that declarations in their header files... pdada is potentially dangerous as you already found out. All MOVX commands just use one cycle. This was different in the old days. Some derivates use a special page register for addressing otherwise P2 is used. Which is complicated because the bits of P2 are used for alternate functions too.

If you want to use a modified startup.a51 you have to put a copy in your working directory and include the startup.a51 to your project. Otherwise a simple version from the lib is used. I do that for example because i always clear all th internal Ram from 00 to FF. Libcode just clears 00 to 7F to ensure the data seg is cleared and leaves the iseg untouched.


@usbman

You are right.

I once looked at the instruction set, but didn't pay attention to the part about MOVX.

Now it seems that using PDATA will not bring much benefit so I will change them to XDATA.

By the way, thank you for your explanation about startup.a51.


@半山竹梢

pdata 需要 “页”支持,WCH的 E-8051 系列单片机,因为没有开发单独的PPAGE 寄存器,而是沿用AT89C51的标准,用P2寄存器行使的 PPAGE 功能,所以,只有 CH551/552/554 因为没有P2引脚。所以,对pdata的支持的比较好。对于,CH548/549 因为有用到 P2 引脚,所以,建议不要使用pdata。而在CH558/559 系列中,pdata 被用做了扩展寄存器,算是WCH对pdata 一个不错的安置吧。其实,你如果灵活使用了 双DPTR指针的话,xdata 不会比 pdata 效率低多少。


只有登录才能回复,可以选择微信账号登录