|
大家能帮我看一下V2到底错在哪里了吗 一旦使用V2PendSVHandler就直接进入HardDefault了 自己不知道错在哪里了
// 这是正常版本的
// 动态创建任务
void tTaskCreated(tTask * task,void (*entry)(void *), void *param,
uint32_t prio, uint32_t stack_size)
{
taskENTER_CRITICAL();
tTaskStack * stackTop = NULL;
tTaskStack * StackStart = NULL;
StackStart = (tTaskStack *)pvPortMalloc(stack_size);
configASSERT((uint32_t)StackStart%8==0);
if(StackStart == NULL)
{
return;
}
task->stackBase = StackStart;
task->stackSize = stack_size;
memset(StackStart, 0, stack_size);
stackTop = StackStart + stack_size / sizeof(tTaskStack);
*(--stackTop) = (uint32_t)(1<<24); // XPSR, 设置了Thumb模式,恢复到Thumb状态而非ARM状态运行
*(--stackTop) = (uint32_t)entry; // 程序的入口地址
*(--stackTop) = (uint32_t)portINITIAL_EXC_RETURN; // R14(LR), 任务不会通过return xxx结束自己,所以未用
*(--stackTop) = (uint32_t)0x12; // R12, 未用
*(--stackTop) = (uint32_t)0x3; // R3, 未用
*(--stackTop) = (uint32_t)0x2; // R2, 未用
*(--stackTop) = (uint32_t)0x1; // R1, 未用
*(--stackTop) = (uint32_t)param; // R0 = param, 传给任务的入口函数
for (int i = 31; i >= 16; i--) {
*(--stackTop) = (uint32_t)(0x00000000); // S16–S31: 初始化为特殊值方便调试
}
*(--stackTop) = (uint32_t)portINITIAL_EXC_RETURN; // R14(LR)
*(--stackTop) = (uint32_t)0x11; // R11, 未用
*(--stackTop) = (uint32_t)0x10; // R10, 未用
*(--stackTop) = (uint32_t)0x9; // R9, 未用
*(--stackTop) = (uint32_t)0x8; // R8, 未用
*(--stackTop) = (uint32_t)0x7; // R7, 未用
*(--stackTop) = (uint32_t)0x6; // R6, 未用
*(--stackTop) = (uint32_t)0x5; // R5, 未用
*(--stackTop) = (uint32_t)0x4; // R4, 未用
task->slice = TINYOS_SLICE_MAX; // 初始化任务的时间片计数
task->stack = stackTop; // 保存最终的值
task->prio = prio; // 设置任务的优先级
task->state = TINYOS_TASK_STATE_RDY; // 设置任务为就绪状态
task->suspendCount = 0; // 初始挂起次数为0
task->clean = (void(*)(void *))0; // 设置清理函数
task->cleanParam = (void *)0; // 设置传递给清理函数的参数
task->requestDeleteFlag = 0; // 请求删除标记
task->waitEvent = (tEvent *)0; // 没有等待事件
task->eventMsg = (void *)0; // 没有等待事件
task->waitEventResult = tErrorNoError; // 没有等待事件错误
tNodeInit(&(task->delayNode)); // 初始化延时结点
tNodeInit(&(task->linkNode)); // 初始化链接结点
tTaskSchedRdy(task); // 将任务插入就绪队列
taskEXIT_CRITICAL();
return;
}
// 这是V2 tTask也动态分配
tTask * tTaskCreatedV2(void (*entry)(void *), void *param,
uint32_t prio, uint32_t stack_size)
{
taskENTER_CRITICAL();
tTask * task = NULL;
tTaskStack * stackTop = NULL;
tTaskStack * StackStart = NULL;
task = (tTask *)pvPortMalloc(sizeof(tTask));
memset(task, 0x00, sizeof(tTask));
StackStart = (tTaskStack *)pvPortMalloc(stack_size);
configASSERT((uint32_t)StackStart%8==0);
if(StackStart == NULL)
{
vPortFree(task);
task = NULL;
return task;
}
task->stackBase = StackStart;
task->stackSize = stack_size;
memset(StackStart, 0, stack_size);
stackTop = StackStart + stack_size / sizeof(tTaskStack);
*(--stackTop) = (uint32_t)(1<<24); // XPSR, 设置了Thumb模式,恢复到Thumb状态而非ARM状态运行
*(--stackTop) = (uint32_t)entry; // 程序的入口地址
*(--stackTop) = (uint32_t)portINITIAL_EXC_RETURN; // R14(LR), 任务不会通过return xxx结束自己,所以未用
*(--stackTop) = (uint32_t)0x12; // R12, 未用
*(--stackTop) = (uint32_t)0x3; // R3, 未用
*(--stackTop) = (uint32_t)0x2; // R2, 未用
*(--stackTop) = (uint32_t)0x1; // R1, 未用
*(--stackTop) = (uint32_t)param; // R0 = param, 传给任务的入口函数
for (int i = 31; i >= 16; i--) {
*(--stackTop) = (uint32_t)(0x00000000); // S16–S31: 初始化为特殊值方便调试
}
*(--stackTop) = (uint32_t)portINITIAL_EXC_RETURN; // R14(LR)
*(--stackTop) = (uint32_t)0x11; // R11, 未用
*(--stackTop) = (uint32_t)0x10; // R10, 未用
*(--stackTop) = (uint32_t)0x9; // R9, 未用
*(--stackTop) = (uint32_t)0x8; // R8, 未用
*(--stackTop) = (uint32_t)0x7; // R7, 未用
*(--stackTop) = (uint32_t)0x6; // R6, 未用
*(--stackTop) = (uint32_t)0x5; // R5, 未用
*(--stackTop) = (uint32_t)0x4; // R4, 未用
task->slice = TINYOS_SLICE_MAX; // 初始化任务的时间片计数
task->stack = stackTop; // 保存最终的值
task->prio = prio; // 设置任务的优先级
task->state = TINYOS_TASK_STATE_RDY; // 设置任务为就绪状态
task->suspendCount = 0; // 初始挂起次数为0
task->clean = (void(*)(void *))0; // 设置清理函数
task->cleanParam = (void *)0; // 设置传递给清理函数的参数
task->requestDeleteFlag = 0; // 请求删除标记
task->waitEvent = (tEvent *)0; // 没有等待事件
task->eventMsg = (void *)0; // 没有等待事件
task->waitEventResult = tErrorNoError; // 没有等待事件错误
tNodeInit(&(task->delayNode)); // 初始化延时结点
tNodeInit(&(task->linkNode)); // 初始化链接结点
tTaskSchedRdy(task); // 将任务插入就绪队列
taskEXIT_CRITICAL();
return task;
}
其中动态分配内存来自一个uHeap大数组和FreeRTOS一样 通过调试可以发现是卡在了
LDR R0, =currentTask // 好了,准备切换了
LDR R1, =nextTask
LDR R2, [R1]
STR R2, [R0] // 先将currentTask设置为nextTask,也就是下一任务变成了当前任务
LDR R0, [R2] // 这里V2获得的R0莫名奇妙
LDMIA R0!, {R4-R11,LR} // 导致这里直接错误了
|
|