UCOS FPU功能开启比较困难;需要在target/C++/C菜单下定义宏:
__TARGET_FPU_VFP,ARM_MATH_CM4,__FPU_PRESENT=1
而且需要修改OS_PENDSV_HANDLER中的代码,以区别__FPU_PRESENT=1和__FPU_USED=1时的情况。
void SysTick_Handler(void)
{
if(OSRunning==1) //OS开始跑了,才执行正常的调度处理
{
OSIntEnter(); //进入中断
OSTimeTick(); //调用ucos的时钟服务程序
OSIntExit(); //触发任务切换软中断
}
}
OS_CPU_PendSVHandler
CPSID I ; Prevent interruption during context switch
MRS R0, PSP ; PSP is process stack pointer
CBZ R0, OS_CPU_PendSVHandler_nosave ; Skip register save the first time
;#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SUBS R0, R0, #0x40 ; Save remaining regs S16-S31 on process stack
VSTM R0, {S16-S31}
;#endif
SUBS R0, R0, #0x20 ; Save remaining regs r4-11 on process stack
STM R0, {R4-R11}
LDR R1, =OSTCBCurPtr ; OSTCBCurPtr->OSTCBStkPtr = SP;
LDR R1, [R1]
STR R0, [R1] ; R0 is SP of process being switched out
; At this point, entire context of process has been saved
OS_CPU_PendSVHandler_nosave
PUSH {R14} ; Save LR exc_return value
LDR R0, =OSTaskSwHook ; OSTaskSwHook();
BLX R0
POP {R14}
LDR R0, =OSPrioCur ; OSPrioCur = OSPrioHighRdy;
LDR R1, =OSPrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
LDR R0, =OSTCBCurPtr ; OSTCBCurPtr = OSTCBHighRdyPtr;
LDR R1, =OSTCBHighRdyPtr
LDR R2, [R1]
STR R2, [R0]
LDR R0, [R2] ; R0 is new process SP; SP = OSTCBHighRdyPtr->StkPtr;
LDM R0, {R4-R11} ; Restore r4-11 from new process stack
ADDS R0, R0, #0x20
;#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
VLDM R0, {S16-S31} ; Restore S16-S31 from new process stack
ADDS R0, R0, #0x40
;#endif
MSR PSP, R0 ; Load PSP with new process SP
ORR LR, LR, #0x04 ; Ensure exception return uses process stack
CPSIE I
BX LR ; Exception return will restore remaining context
END
LWIP:
很多宏定义需要根据实际需要进行修改。
必须有这么一句: if(lwip_comm_mem_malloc())return 1; //内存申请失败。
另外发现Wireshark可以发现报文而客户端却收不到,原来是没有FCS,必须使能CHECKSUM才行,而且必须使能软件检验,因为采用的ENC28J60.
把ETH改为ENC28J60时,需要很多问题,如外部中断使能,SPI端口设置等,不一一枚举了。