单片机开发,MCU开发网,电子设计
做最优秀的电子开发团队
做最优秀的电子开发团队
十一 8th
之前在学习如何在C语言中嵌入汇编时有了解到C语言之前的参数调用是使用寄存器R0传递第一个参数,R1传递到第二个..一直到R3传递第四个参数.但是实际上有时可能传递的参数非常多,超过8个,或是参数中有浮点数之类,参数也会超过4个寄存器,对于超出的部份并不使用R4,而是使用堆栈的方式,但具体是如何的方式很多网站就没了下文了,好在在GG的帮助下,让我在凌晨1.30找到了(为啥老是在半夜呢?)
—————————————————-华丽的分割线————————————————
对于ARM体系来说,不同语言撰写的函数之间相互调用(mix calls)遵循的是 ATPCS(ARM-Thumb Procedure Call Standard),ATPCS主要是定义了函数呼叫时参数的传递规则以及如何从函数返回,关于ATPCS的详细内容可以查看ADS1.2 Online Books ——Developer Guide的2.1节。这篇文档要讲的是 汇编代码中对C函数调用时如何进行参数的传递以及如何从C函数正确返回
不同于x86的参数传递规则,ATPCS建议函数的形参不超过4个,如果形参个数少于或等于4,则形参由R0,R1,R2,R3四个寄存器进行传递;若形参个数大于4,大于4的部分必须通过堆栈进行传递。
我们先讨论一下形参个数为4的情况. 实例1: test_asm_args.asm //——————————————————————————– IMPORT test_c_args ;声明test_c_args函数 AREA TEST_ASM, CODE, READONLY EXPORT test_asm_args test_asm_args STR lr, [sp, #-4]! ;保存当前lr ldr r0,=0×10 ;参数 1 ldr r1,=0×20 ;参数 更多 >
十一 7th
找遍了整个网络,百度大妈,GG大婶都问过了,就是没找到如何在allegro16.2中设置等长线,十分郁闷,研究了几个小时,终于在一个角落找到,发到PCB设计网上做了个记念,当然顺便也是要转到这里来的.
在allergo16.2中设置等长线的方法与15.X版本有很大的变化,16.2版本中更为方便与强大.其方法为:
选择”Setup”–>”Constrains”–>”Electrical”,强出Allegro Constraint Manager如图一所示:
图一 这里我们选择”Electrical”栏下的”NET”选项中的”routing->Min/Max Propagation delays”,然后就可以在右侧进行相关设置:如图2 图2 这里可以为每个不同的网络进行设置一个范围.如图所示,我们为部分网络设为了1166MIL-1168MIL的范围. 其中红色表示当前的走线并不在所设定范围,并将其差值都显示出来,非常直观. 设定好后,保存并返回到布线器中,须要选将线走好后才能进行等长修正: 点选快捷图标或是选择”Route”–>”Delay Tune”对已走好的线进行修正,此时应注意右下角的长度提示,当它为中心那格时绿色表示达到规定 绿色刚好. 超过了中心值,偏长.须要修改.
十一 4th
十一 2nd
当然动态储器(DRAM)与静态存储器(SRAM)除了速度外,它们的价格也是一个天一个地,依据实际情况进行设计,以降底产品成本,下面是它们的价绍.
SRAM(静态存储器)的特点是工作速度快,只要电源不撤除,写入SRAM的信息就不会消失,不需要刷新电路,同时在读出时不破坏原来存放的信息,一经写入可多次读出,但集成度较低,功耗较大。并且连接的管脚很多.SRAM一般用来作为计算机中的高速缓冲存储器(Cache)。
DRAM是动态随机存储器(Dynamic Random Access Memory),它是利用场效应管的栅极对其衬底间的分布电容来保存信息,以存储电荷的多少,即电容端电压的高低来表示“1”和“0”。DRAM每个存储单元所需的场效应管较少,常见的有4管,3管和单管型DRAM。因此它的集成度较高,功耗也较低,但缺点是保存在DRAM中的信息__场效应管栅极分布电容里的信息随着电容器的漏电而会逐渐消失,一般信息保存时间为2ms左右。为了保存DRAM中的信息,必须每隔1~2ms对其刷新一次。因此,采用 DRAM的计算机必须配置动态刷新电路,防止信息丢失。DRAM一般用作计算机中的主存储器。
十一 1st
OSTaskStkInit()在Cortex-M3中主要功能为初始化任务的栈的桔构,使任务的栈看起来就好像刚发生了一个中断一样的结构,这些UC/OS的作者都有说到.现在我们须要了解的是Cortex-M3在发生中断时,它的堆栈结构.在我们之前有提它中断时的压栈过程为xPSR–>PC–>LR–>R12–>R3-R0(详情点这里:Cortex-M3中断时,自动压栈的顺序),推断出中断后的任务堆栈应该为下图:
所以OSTaskStkInit()的作用就是将传递过来的参数(其中包含了堆栈地址与任务入口地址等)
标准的OSTaskStkInit()的原型为:
OS_STK *OSTaskStkInit(void (*task)(void *pd),void *pdata,OS_STK *ptos,INT16U opt);
ptos是传入是堆栈的初始值,task则是任务PC的起始地址指针.opt则是操作数,一般的任务都没用上.
所以我们最主要的任务就是把ptos,task按中断的方式压入堆栈中,堆栈的地址由ptos给出,然后再把新的堆栈的值传回去.方法:
opt=opt; //未使用,防止编译器警告 OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt) { OS_STK *stk; //定义一个指针变量,用来对堆栈的操作
stk = ptos; //将传递过来的堆栈指针值赋值给STK
*(stk) = (INT32U)0x01000000L; //首先压入的是xPSR *(–stk) = (INT32U)task; //然后自减一后把任务的入口地址压入 *(–stk) = (INT32U)0xFFFFFFFEL; //接下来压入LR,由于CORTEX-M3的LR在中断时是非常特殊值,所以这经的值须要根据实际情况去确定,比如在任务模式下使用PSP那么就得把LR的值设定为FFFFFFFE
*(–stk) = (INT32U)0x12121212L; /* R12 */ *(–stk) = (INT32U)0x03030303L; /* R3 */ *(–stk) 更多 >
十 30th
最近在看UCOS,才忽然发现自已连它的自动压栈顺序都还没有了解,找遍整个互连网,全都在谈CORTEX-M3与ARM7相比的优势等等,于是再翻它的白皮书看,终于找到了它自动压栈的顺序了..
位置从先到后
xPSR–>PC–>LR–>R12–>R3-R0;
Cortex-M3比起ARM7/ARM9来说,在中断处理能力上已经高了不是一个档次,最明显的就是固定的中断向量与自动压栈等,由于内核变动较大,以前在ARM7/ARM9上移植好的操作系统在CORTEX-M3里就须要大改才行了.