Good morning.
On CCS 5.3 is an issue when I use optimization.
The issue is this:
CPUIntStatus:
8051524c: E10F0000 MRS R0, CPSR
80515250: E20000C0 AND R0, R0, #192
80515254: E12FFF1E BX R14
CPUirqd:
804d1e5c: E10F0000 MRS R0, CPSR
804d1e60: E3800080 ORR R0, R0, #128
804d1e64: E121F000 MSR CPSR_c, R0
804d1e68: E12FFF1E BX R14
The up two functions is writed in ASM linguage.
When I compile the "sys_arch_protect" funcion from lwip 1.4.0 without optimization, all is compiled correct.
sys_arch_protect:
8050c684: E92D4008 STMFD R13!, {R3, R14}
62 status = (IntMasterStatusGet() & 0xFF);
8050c688: EBFF16F3 BL IntMasterStatusGet
8050c68c: E5CD0000 STRB R0, [R13]
64 IntMasterIRQDisable();
8050c690: EBFF16E8 BL IntMasterIRQDisable
65 return status;
8050c694: E5DD0000 LDRB R0, [R13]
66 }
8050c698: E8BD8008 LDMFD R13!, {R3, PC}
With optimization level 3, this is the result:
sys_arch_protect:
804d2280: E92D4008 STMFD R13!, {R3, R14}
593 return CPUIntStatus();
804d2284: EB00AE5D BL CPUIntStatus
545 CPUirqd();
804d2288: EBFFFFF8 BL CPUirqd
65 return status;
804d228c: E6EF0070 UXTB R0, R0, ROR #0
804d2290: E8BD8008 LDMFD R13!, {R3, PC}
Can be observed that both of ASM functions use the R0 register, but the "CPUIntStatus" function return the CPSR value in R0, the "CPUirqd" will modify the R0 register, and finally the "sys_arch_protect" will return the R0 register modified by the "CPUirqd". This is an issue of compiler, that can not back-up the R0 register when is used by the "CPUirqd".
I correct this issue with these changes:
In lwip libray:
on sys_arch.c
from:
sys_prot_t
sys_arch_protect(void)
{
sys_prot_t status;
status = (IntMasterStatusGet() & 0xFF);
IntMasterIRQDisable();
return status;
}
to
sys_prot_t
sys_arch_protect(void)
{
volatile sys_prot_t status;
status = (IntMasterStatusGet() & 0xFF);
IntMasterIRQDisable();
return status;
}
The same issue is present in "usbhostenum.c" on "USBHCDMain".
But if I changed from:
unsigned int ulIntState;
to volatile unsigned int ulIntState;
will go to abort.
I changed from:
ulIntState = IntDisable();
to
IntDisable();
and from:
IntEnable(ulIntState);
to
IntEnable(0);
With these changes everything works OK the lwip library and USB host.