qjhu0433 发表于 2006-3-18 14:05:49

用在RTOS中的GCC库函数itoa的悬疑:结果错,需要关中断处理才能获得正确的结果?

用在RTOS中的GCC库函数itoa的悬疑



94:               itoa(gRHcnt,r,10);

+000017F1:   E04A      LDI   R20,0x0A         Load immediate

+000017F2:   E050      LDI   R21,0x00         Load immediate

+000017F3:   E16F      LDI   R22,0x1F         Load immediate

+000017F4:   E073      LDI   R23,0x03         Load immediate

+000017F5:   91800311    LDS   R24,0x0311       Load direct from data space

+000017F7:   91900312    LDS   R25,0x0312       Load direct from data space

+000017F9:   940E1D9C    CALL    0x00001D9C       Call subroutine



+00001D9C:   01FB      MOVW    R30,R22          Copy register pair

+00001D9D:   019F      MOVW    R18,R30          Copy register pair

+00001D9E:   94E8      CLT                      Clear T in SREG

+00001D9F:   3042      CPI   R20,0x02         Compare with immediate

+00001DA0:   F0C4      BRLT    PC+0x19          Branch if less than, signed

+00001DA1:   3245      CPI   R20,0x25         Compare with immediate

+00001DA2:   F4B4      BRGE    PC+0x17          Branch if greater or equal, signed

+00001DA3:   304A      CPI   R20,0x0A         Compare with immediate

+00001DA4:   F429      BRNE    PC+0x06          Branch if not equal

+00001DA5:   FB97      BST   R25,7            Bit store from register to T

+00001DA6:   F41E      BRTC    PC+0x04          Branch if T flag cleared

+00001DA7:   9590      COM   R25            One's complement

+00001DA8:   9581      NEG   R24            Two's complement

+00001DA9:   4F9F      SBCI    R25,0xFF         Subtract immediate with carry

+00001DAA:   2F64      MOV   R22,R20          Copy register

+00001DAB:   2777      CLR   R23            Clear Register

+00001DAC:   940E1E2D    CALL    0x00001E2D       Call subroutine

+00001DAE:   5D80      SUBI    R24,0xD0         Subtract immediate

+00001DAF:   338A      CPI   R24,0x3A         Compare with immediate

+00001DB0:   F00C      BRLT    PC+0x02          Branch if less than, signed

+00001DB1:   5D89      SUBI    R24,0xD9         Subtract immediate

+00001DB2:   9381      ST      Z+,R24         Store indirect and postincrement

+00001DB3:   01CB      MOVW    R24,R22          Copy register pair

+00001DB4:   9700      SBIW    R24,0x00         Subtract immediate from word

+00001DB5:   F7A1      BRNE    PC-0x0B          Branch if not equal

+00001DB6:   F416      BRTC    PC+0x03          Branch if T flag cleared

+00001DB7:   E25D      LDI   R21,0x2D         Load immediate

+00001DB8:   9351      ST      Z+,R21         Store indirect and postincrement

+00001DB9:   8210      STD   Z+0,R1         Store indirect with displacement

---- No Source ------------------------------------------------------------------------------------

+00001DBA:   01C9      MOVW    R24,R18          Copy register pair

+00001DBB:   940C1DBD    JMP   0x00001DBD       Jump

+00001DBD:   01DC      MOVW    R26,R24          Copy register pair

+00001DBE:   01FC      MOVW    R30,R24          Copy register pair

+00001DBF:   9001      LD      R0,Z+            Load indirect and postincrement

+00001DC0:   2000      TST   R0               Test for Zero or Minus

+00001DC1:   F7E9      BRNE    PC-0x02          Branch if not equal

+00001DC2:   9732      SBIW    R30,0x02         Subtract immediate from word

+00001DC3:   17AE      CP      R26,R30          Compare

+00001DC4:   07BF      CPC   R27,R31          Compare with carry

+00001DC5:   F430      BRCC    PC+0x07          Branch if carry cleared

+00001DC6:   917C      LD      R23,X            Load indirect

+00001DC7:   8160      LDD   R22,Z+0          Load indirect with displacement

+00001DC8:   8370      STD   Z+0,R23          Store indirect with displacement

+00001DC9:   9731      SBIW    R30,0x01         Subtract immediate from word

+00001DCA:   936D      ST      X+,R22         Store indirect and postincrement

+00001DCB:   CFF7      RJMP    PC-0x0008      Relative jump

+00001DCC:   9508      RET



+00001E2D:   1BAA      SUB   R26,R26          Subtract without carry

+00001E2E:   1BBB      SUB   R27,R27          Subtract without carry

+00001E2F:   E151      LDI   R21,0x11         Load immediate

+00001E30:   C007      RJMP    PC+0x0008      Relative jump

+00001E31:   1FAA      ROL   R26            Rotate Left Through Carry

+00001E32:   1FBB      ROL   R27            Rotate Left Through Carry

+00001E33:   17A6      CP      R26,R22          Compare

+00001E34:   07B7      CPC   R27,R23          Compare with carry

+00001E35:   F010      BRCS    PC+0x03          Branch if carry set

+00001E36:   1BA6      SUB   R26,R22          Subtract without carry

+00001E37:   0BB7      SBC   R27,R23          Subtract with carry

+00001E38:   1F88      ROL   R24            Rotate Left Through Carry

+00001E39:   1F99      ROL   R25            Rotate Left Through Carry

+00001E3A:   955A      DEC   R21            Decrement

+00001E3B:   F7A9      BRNE    PC-0x0A          Branch if not equal

+00001E3C:   9580      COM   R24            One's complement

+00001E3D:   9590      COM   R25            One's complement

+00001E3E:   01BC      MOVW    R22,R24          Copy register pair

+00001E3F:   01CD      MOVW    R24,R26          Copy register pair

+00001E40:   9508      RET



这段代码是我从avr-gcc的库文件中提取出来的,是itoa的实现。然而这个函数在抢占式的多线程环境有时得到的结果却不正常,

但只要在调用这个函数前加关中断处理就可以每次都获得正确的结果。我把这个函数的汇编实现提出来之后仔细看了好几遍,没

有发现使用除了寄存器之外其它的资源,我的任务切换如下保护:



register uint8 Os_Enter_Sum asm("r2");         // 关中断计数器使用的寄存器



#define POPALL()            \



{                \



__asm__ __volatile__(      \



"POP R31"          "
\t"      \

"POP R30"          "
\t"      \

"POP R29"               "
\t"    \

"POP R28"               "
\t"   \

"POP R27"          "
\t"      \

"POP R26"          "
\t"      \

"POP R25"          "
\t"      \

"POP R24"          "
\t"      \

"POP R23"          "
\t"      \

"POP R22"          "
\t"      \

"POP R21"          "
\t"      \

"POP R20"          "
\t"      \

"POP R19"          "
\t"      \

"POP R18"          "
\t"      \

"POP R17"          "
\t"      \

"POP R16"          "
\t"      \

"POP R15"          "
\t"      \

"POP R14"          "
\t"      \

"POP R13"          "
\t"      \

"POP R12"          "
\t"      \

"POP R11"          "
\t"      \

"POP R10"          "
\t"      \

"POP R9"          "
\t"      \

"POP R8"          "
\t"      \

"POP R7"          "
\t"      \

"POP R6"          "
\t"      \

"POP R5"          "
\t"      \

"POP R4"          "
\t"      \

"POP R3"          "
\t"      \

"POP R2"          "
\t"      \

"POP R0"         "
\t"      \



"OUT 0x3F,R0"          "
\t"      \

"POP R0"         "
\t"      \

"POP R1"         "
\t"      \

);                \



}





#define PUSHALL()               \



{                \



__asm__ __volatile__(      \



"PUSH R1"         "
\t"   \

"PUSH R0"         "
\t"      \

"IN R0,0x3F"            "
\t"      \



"PUSH R0"         "
\t"      \

"CLRR1"                  "
\t"\

"PUSH R2"         "
\t"      \

"PUSH R3"         "
\t"      \

"PUSH R4"         "
\t"      \

"PUSH R5"         "
\t"      \

"PUSH R6"         "
\t"      \

"PUSH R7"         "
\t"      \

"PUSH R8"         "
\t"      \

"PUSH R9"         "
\t"      \

"PUSH R10"         "
\t"      \

"PUSH R11"         "
\t"      \

"PUSH R12"         "
\t"      \

"PUSH R13"         "
\t"      \

"PUSH R14"         "
\t"      \

"PUSH R15"         "
\t"      \

"PUSH R16"         "
\t"      \

"PUSH R17"         "
\t"      \

"PUSH R18"         "
\t"      \

"PUSH R19"         "
\t"      \

"PUSH R20"         "
\t"      \

"PUSH R21"         "
\t"      \

"PUSH R22"         "
\t"      \

"PUSH R23"         "
\t"      \

"PUSH R24"         "
\t"      \

"PUSH R25"         "
\t"      \

"PUSH R26"         "
\t"      \

"PUSH R27"            "
\t"      \

"PUSH R28"         "
\t"    \

"PUSH R29"      "
\t"    \

"PUSH R30"      "
\t"    \

"PUSH R31"      "
\t"    \



);                \



}





但为什么有时会到不到正确的结果呢,有句话说的好“众人拾材火焰高”,希望各位网友献计献策。

HJJourAVR 发表于 2006-3-18 14:14:09

可能是 itoa 的运行时间太长了,超出了你的系统时隙,或被其他中断所打断,被错误修改了SRAM区的数据,所以导致结果出错。



字符缓冲区足够大吗?

Note:

The minimal size of the buffer s depends on the choice of radix. For example, if the radix is 2 (binary), you need to supply a buffer with a minimal length of 8 * sizeof (int) + 1 characters, i.e. one character for each bit plus one for the string terminator. Using a larger radix will require a smaller minimal buffer size.

Warning:

If the buffer is too small, you risk a buffer overflow.





是那款RTOS?
页: [1]
查看完整版本: 用在RTOS中的GCC库函数itoa的悬疑:结果错,需要关中断处理才能获得正确的结果?