杨为民
发表于 2024-3-31 20:34:49
本帖最后由 杨为民 于 2024-3-31 20:37 编辑
fanxsp 发表于 2024-3-31 20:06
pdataxdata用户是可配置的,可以根据实际情况而定。主要原因是,pdata的指针是 1个字节,xdata 的指针 ...
(1)既然是“用户是可配置的”,那就不要用PDATA数据类型。
(2)PDATA的用法见下图:C51的帮助手册:
上面那段话百度翻译为:
XDATA存储器类可以通过寄存器DPTR与指令MOVX一起访问。XDATA存储器的单个页面也可以经由寄存器R0、R1来访问。在C编译器级别,这种内存类型被称为updatea,而段前缀?PD?使用。
此更新页的高地址通常是用P2寄存器设置的。但在新的8051变体中,也有定义XDATA页地址的专用特殊功能寄存器。
(3)XDATA的地址是16位的,形式为“0XXYYH”,可以分成高8位XX和低8位YY。 也就是说PDATA的高8位地址“XX”是由P2端口寄存器的内容来决定的:
比如对于同样的8位PDATA地址YY(比如任务堆栈地址),如果运行时P2的内容发生变化,该PDATA映射到XDATA的地址就变了。
换言之,随着P2的内容不同,同一个任务的堆栈就被存到XDATA的不同地方,不仅可能覆盖真正的XDATA变量数据,在切换任务时也不一定能切换回正确的任务现场,造成系统崩溃。
(4)因此,对于早期的和某些型号的单片机可以使用PDATA来提高存取速度,但是对于STC的任何单片机,请不要使用PDATA数据类型。
fanxsp
发表于 2024-3-31 20:48:34
杨为民 发表于 2024-3-31 20:34
(1)既然是“用户是可配置的”,那就不要用PDATA数据类型。
(2)PDATA的用法见下图:C51的帮助手册:
实际编译后对比,xdata比pdata ,代码要大 46字节,具体情况,我再深入了解一下。
杨为民
发表于 2024-3-31 21:07:26
本帖最后由 杨为民 于 2024-3-31 21:11 编辑
fanxsp 发表于 2024-3-31 20:06
pdataxdata用户是可配置的,可以根据实际情况而定。主要原因是,pdata的指针是 1个字节,xdata 的指针 ...
(1)16位的MOVX指令:xdata 的指针是2个字节
1)MOVXA,@DPTR;
2)MOVX@DPTR, A;
在这两条指令中:DPTR为16 bit地址寄存器,地址高8 bit存于DPH,地址低8 bit存于DPL。
用这两条指令中,CPU既可以存取外部XRAM存储器,也可以存取片内的XDATA储存器。
(2)8位的MOVX指令: pdata的指针是 1个字节
3)MOVXA, @RI;
4)MOVX@RI, A。
在这两条指令中:Ri(i=0,1)是8 bit寄存器,作为地址指针时仅存低8 bit地址.
用这两条指令,CPU在存取外部XRAM存储器时,P2口在指令过程中必须一直输出高8 bit地址。
用这两条指令,CPU在存取片内的XDATA储存器时, 存取的高8位地址是多少?是否与P2端口的值有关?这取决于具体的单片机型号。
对于STC单片机,这个问题的答案是我们不知道。所以STC把不使用PDATA数据类型作为警告写在手册里了。
神农鼎
发表于 2024-3-31 21:08:25
现在 64K 的 STC8H8K64U-45I-TSSOP20 才人民币1.4,
不要在乎 几十个字节到 几K 字节 !
要防止编译器公司的年轻人将来升级改版编译器可能会改出潜在的错误 !!!
我不看具体的程序N年了,但总感觉这 谁还用 pdata 发表文章,谁就是将来要害人,
他编译器哪天改版改错了咋办,还是把 pdata 去了 !!!
我们数据手册现在都无法交代 如何用 pdata, 这东西将来是要害人的,
是片内还是片外的 pdata, 片内 P2又起不到作用,讲不清了
谁能保证自己不犯错,编译器也是
速度差不多,价格不在乎
fanxsp
发表于 2024-3-31 21:13:27
神农鼎 发表于 2024-3-31 21:08
现在 64K 的 STC8H8K64U-45I-TSSOP20 才人民币1.4,
不要在乎 几十个字节到 几K 字节 !
明白了
tzz1983
发表于 2024-3-31 21:28:53
本帖最后由 tzz1983 于 2024-3-31 21:32 编辑
楼主真{:4_250:}
今晚才开始,看了一小会.代码和说明文档,都特别工整,正规军!
本来就想露个脸,给老朋友加个人气,顺路问个问题.
不知道大家有没有注意到:
if(OSTcbArea.pree)
{
#pragma ASM
POP AR7
POP AR6
POP AR5
POP AR4
POP AR3
POP AR2
POP AR1
POP AR0
POP PSW
POP DPL
POP DPH
POP B
POP ACC
#pragma ENDASM
}
这里的出栈是有条件的!
我还没看完,我大致的理解是任务级切换,是不用保存寄存器的.
脑瓜子还在转,好像还真可以这么玩,火花带闪电啊.
这么做还是头一次见,是国外OS限制了我的想象,还是我孤陋寡闻。
楼主,这应该是你自己想出来的吧,还有谁这么玩过?
大锤子
发表于 2024-3-31 21:46:21
正打算学习rtos
fanxsp
发表于 2024-3-31 21:59:38
tzz1983 发表于 2024-3-31 21:28
楼主真
今晚才开始,看了一小会.代码和说明文档,都特别工整,正规军!
如果任务是调用任务级任务切换函数,主动放弃控制权时,不用保存寄存器,编译器可以保证。比如函数A调用了另一个函数B,当B返回时,寄存器的值已经改变,但是我们并没有保存和恢复寄存器,同时B里面也没有保存和恢复寄存器。为什么可以呢?因为编译器可以保证这一点。如果编译器发现有些寄存器的值在调用B后还会用到,就会在调用前先保存起来。Keil C 不是把寄存器值保存到推栈,而是保存在一个固定的数据段(用来保存局部变量的可覆盖段),这也是造成函数不可重入的主要原因。
tzz1983
发表于 2024-3-31 22:04:23
fanxsp 发表于 2024-3-31 21:59
如果任务是调用任务级任务切换函数,主动放弃控制权时,不用保存寄存器,编译器可以保证。比如函数A调用 ...
是的,看到代码的时候,我也想到了,受教了.
另外:
#pragma ASM
MOV A,#LOW (OSCtxSw)
PUSH ACC
MOV A,#HIGH (OSCtxSw)
PUSH ACC
#pragma ENDASM
是否可改为:
#pragma ASM
AJMP OSCtxSw
#pragma ENDASM
同一文档可以直接跳,好像快一点.只是结构好像没那么正规了.
fanxsp
发表于 2024-3-31 22:07:42
tzz1983 发表于 2024-3-31 22:04
是的,看到代码的时候,我也想到了,受教了.
另外:
这个可以试一下
页:
1
2
3
[4]
5
6
7
8
9
10
11
12
13