像LM4F232H5QD的浮点运算单元(FPU)默认是disable的,而M3本身没有FPU,而且M3的指令集本身就是M4指令集的子集,所以移植的时候基本上可以直接移植M3的代码。目前micrium还没有提供Cortex M4的Port接口示例代码,如果移植好了,和大家分享一下吧。
谢谢大家的支持,我把把一个UART的例子移植到M4上了,显示屏有显示了,串口测试结果:按复位键上位机能收到数据,但是上位机发数据显示屏上没有显示,用示波仪测相应的RX/TX端口都有数据变化。调试程序时发现UARTIntHandler(void)中断服务函数没响应(STARTUP里面已经注册好串口的中断处理了,UART0的IO也定义和配置好了),
以下是中断处理函数:
void
UARTIntHandler(void)
{
unsigned long ulStatus;
//
// 获取中断状态
//
ulStatus = UARTIntStatus(UART0_BASE, true);
//
// 清中断
//
UARTIntClear(UART0_BASE, ulStatus);
//
// 读FIFO到空
//
while(UARTCharsAvail(UART0_BASE))
{
*pbuff++=UARTCharGetNonBlocking(UART0_BASE); //放入RecBuff中
RecNum++; //接收数据个数加1
}
if(ulStatus&UART_INT_RT)//接收超时时,去main里显示接收到内容
RecFlag=TRUE; //置超时标记
}
以下是主函数:
while(1)
{
if(RecFlag) //当把RecFlag改为:(RecFlag==0)时,下面的代码才能运行,在中断设断断了没有停下来,说明中断服务函数未响应。
{
RecFlag=FALSE;
//显示接收到的字符
GrContextForegroundSet(&g_sContext,ClrBlack);
GrRectFill(&g_sContext, &sRect);
GrContextForegroundSet(&g_sContext, ClrWhite);
GrContextFontSet(&g_sContext, &g_sFontCm20);
GrStringDraw(&g_sContext, RecBuff,RecNum, 150, 165, 0);
//发送接收到的字符
UARTSend(RecBuff, RecNum);
//清本次接收到的数据和数据个数,准备下一次接收
RecNum=0;
pbuff=RecBuff;
}
OSTimeDlyHMSM(0,0,0,50);
}
请帮忙分析是什么原因。谢谢!
中断标志是已经加进去了的。不加UCOSII是能进入中断的,通讯都正常。
OSStartHighRdy
LDR R4, =NVIC_SYSPRI2 ; set the PendSV exception
; priority设置PendSV优先级
LDR R5, =NVIC_PENDSV_PRI
STR R5, [R4]
MOV R4, #0 ; set the PSP to 0 for initial
; context switch call 使PSP等于0
MSR PSP, R4
LDR R4, __OS_Running ; OSRunning = TRUE
MOV R5, #1
STRB R5, [R4]
LDR R4, =NVIC_INT_CTRL ; trigger the PendSV exception
; 触发软件中断
LDR R5, =NVIC_PENDSVSET
STR R5, [R4] 单步运行从这一句就跳到FaultISR了。
CPSIE I ; enable interrupts at processor
; level使能所有优先级的中断
OSStartHang
B OSStartHang 如果用step into运行这一段代码的话,就会停留在这一步,此时如果再用step over的话就会进入FaultISR程序去了。
按照你的说法,可以排除UART本身代码的问题。
那你UCOSII启动了几个任务呢?任务优先级又如何分配?
你可以在FaultISR的while(1)之前添加如下代码,帮你定位一下问题:
printf("\r\n Task: %s", OSTCBCur->OSTCBTaskName);
printf("\r\n State: %p", OSTCBCur->OSTCBStat);
printf("\r\n StackBase: %p", OSTCBCur->OSTCBStkPtr);
printf("\r\n HardFault: %0x", *(volatile ULONG *) NVIC_HFAULT_STAT);
printf("\r\n ConfFault: %0x", *(volatile ULONG *) NVIC_FAULT_STAT);
printf("\r\n FaultAddr: %0x", *(volatile ULONG *) NVIC_FAULT_ADDR);
printf("\r\n MemAddr: %0x", *(volatile ULONG *) NVIC_MM_ADDR);
可能你没有定义printf,那就这样吧:
你在faultISR的while(1)处设置断点,等进入faultISR时,你查看一下OSTCBCur任务控制块的信息
可以看到是什么任务导致挂死。
我只定义了两个任务,一个是UART 优先级定为 4,另一个是LCD优先级定为 5 ; 没有所谓的优先级为7的任务啊。
单步调试(step into)运行到OSStartHighRdy里面的 B OSStartHang 这行代码就运行不下去了,
OSStartHighRdy
LDR R4, =NVIC_SYSPRI2 ; set the PendSV exception
; priority设置PendSV优先级
LDR R5, =NVIC_PENDSV_PRI
STR R5, [R4]
MOV R4, #0 ; set the PSP to 0 for initial
; context switch call 使PSP等于0
MSR PSP, R4
LDR R4, __OS_Running ; OSRunning = TRUE
MOV R5, #1
STRB R5, [R4]
LDR R4, =NVIC_INT_CTRL ; trigger the PendSV exception
; 触发软件中断
LDR R5, =NVIC_PENDSVSET
STR R5, [R4]
CPSIE I ; enable interrupts at processor
; level使能所有优先级的中断
OSStartHang
B OSStartHang
看了相关uCOS II的书籍,说问题是出在OSTaskStkInit()函数 ,没有将正确的任务启地址放在启任务堆栈中
OS_STK *OSTaskStkInit (void (*task)(void *parg), void *parg, OS_STK *ptos, INT16U opt)
{
OS_STK *stk;
(void)opt; /* 'opt' is not used, prevent */
/* warning 没有用'opt', */
/* 防止编译警告 */
stk = ptos; /* Load stack pointer */
/* 装载堆栈指针 */
/* Registers stacked as if */
/* auto-saved on exception */
/* 模拟成异常,自动把寄存器压栈*/
*(stk) = (INT32U)0x01000000L; /* xPSR */
*(--stk) = (INT32U)task; /* Entry Point of the task */
/* 任务入口地址 */
*(--stk) = (INT32U)0xFFFFFFFEL; /* R14 (LR) (init value will */
/* cause fault if ever used) */
*(--stk) = (INT32U)0x12121212L; /* R12 */
*(--stk) = (INT32U)0x03030303L; /* R3 */
*(--stk) = (INT32U)0x02020202L; /* R2 */
*(--stk) = (INT32U)0x01010101L; /* R1 */
*(--stk) = (INT32U)parg; /* R0 : argument 输入参数 */
/* Remaining registers saved on*/
/* process stack */
/* 剩下的寄存器保存到堆栈 */
*(--stk) = (INT32U)0x11111111L; /* R11 */
*(--stk) = (INT32U)0x10101010L; /* R10 */
*(--stk) = (INT32U)0x09090909L; /* R9 */
*(--stk) = (INT32U)0x08080808L; /* R8 */
*(--stk) = (INT32U)0x07070707L; /* R7 */
*(--stk) = (INT32U)0x06060606L; /* R6 */
*(--stk) = (INT32U)0x05050505L; /* R5 */
*(--stk) = (INT32U)0x04040404L; /* R4 */
return(stk);
}
不知道应该改哪一块
INT8U OSTaskCreate (void (*task)(void *p_arg),
void *p_arg,
OS_STK *ptos,
INT8U prio)
你检查传进该函数的参数是否有问题。
这段代码是在OS_TASK.C里面的条件编译语句里面,没法查看其数据呢,
#if OS_TASK_CREATE_EN > 0
INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
OS_STK *psp;
INT8U err;
aiqin he 说:这段代码是在OS_TASK.C里面的条件编译语句里面,没法查看其数据呢,
#if OS_TASK_CREATE_EN > 0
INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
OS_STK *psp;
INT8U err;
那你怎么创建任务的呢?
创建任务的时候,要么用OSTaskCreat,要么用OSTaskCreateExt。
aiqin he 说:main.c main.h, target.c target.h文件
不好意思,没有看明白你的代码
你建立的uart task要做什么呢?就是延时等待?
你可以找一个CM3的移植例程参考一下任务的设计和创建。