器件型号: EK-TM4C129EXL
尊敬的团队:
代表我们的客户发帖。
我要为微控制器创建自己的 RTOS。 为了确保正确性、我混合了汇编语言和 C 语言。 我已经在线查看并发现可以在设置中设置一些标志。 我只是不确定我所做的是不是正确的。 我能否请有人检查它以确保 C 和组装的正确实现?
此致、
Danilo
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
器件型号: EK-TM4C129EXL
尊敬的团队:
代表我们的客户发帖。
我要为微控制器创建自己的 RTOS。 为了确保正确性、我混合了汇编语言和 C 语言。 我已经在线查看并发现可以在设置中设置一些标志。 我只是不确定我所做的是不是正确的。 我能否请有人检查它以确保 C 和组装的正确实现?
此致、
Danilo
尊敬的 Danilo:
您调用汇编函数的方式显示正确。 我唯一担心的是您所引用的 RunPt 变量。 请确保遵循此处介绍的用于连接汇编语言和 C 代码的指南: https://software-dl.ti.com/codegen/docs/tiarmclang/compiler_tools_user_guide/compiler_manual/runtime_environment/interfacing-c-and-c-with-assembly-language-stdz0544217.html
谢谢、
-Eric Rentschler
您好、Eric、
不幸的是、我对此不能给出很好的答案。 当我到达第 137 行时、我尝试进入该行、但 CCS 不会跳转到.asm 文件。 Ergo、我不能说汇编文件中的哪一行导致了问题。 我只能肯定的是、汇编函数是我可以在程序似乎崩溃之前跳到的最后一步、我只能暂停它以查看我遇到的是 ISR 故障。 在 startOS 函数上时、是否有办法从 C 文件跳转到汇编文件?
谢谢你
我在汇编语言中使用了断点、可以看到汇编文件完成、然后返回到 C 文件。 FaultISR 似乎发生在 C 程序完成后? 或者(如过去所发生的情况)当 I step 时、它将修复任何时序问题、然后代码即可正常工作。
没有、我以前没有看到过这份文件、但遵循了说明。 显示错误位于 0xE000EDF8。 从我可以找到的内容来看、这不是 SYSCTL 寄存器的实际偏移量。
当查看硬故障时、SP 会显示:

我在调试窗口中确实存在 0xFFFFFFF8(未定义符号)问题。 我不知道我的代码是否不完整(似乎只有我的一个线程正在运行)、或者我的代码是否有其他问题。 我希望这有助于更全面地了解我所面临的问题。 谢谢你。
我 在 SPMA043 中看不到 0xE000EDF8 的引用。 架构参考手册 (DDI0403E) 表 C1-10 指出这是 DCRDR、此处可能不是很有用。
确实建议查看 0xE000ED28、即 SCB->CFSR [Ref A-R-M Sec B3.2.15];这可能会有一些有用的内容。
我的第一个猜测是、这最初是一个使用故障。 保存的寄存器似乎表明 PC=0、即您以某种方式分支到位置 0(无效指令)、可能 是由于栈中的某些问题所致。
什么是*lr (=0x2450)? 这将告诉您最近一次通话的位置、这将缩小事情的范围。
更普遍地说、您是否曾经到达 task0()?
但是、对于 TM4C、0xE000E000 是 SYSCTL 寄存器、没有 0xDF8 偏移、因此表示不确定。 也许这意味着 DCRDR、但我无法确定。
根据地址、我有一个使用错误 0x00020000、即“使用无效 EPSR.T 或 EPSR.IT 字段执行指令“。 因此、我在如何为系统启用和禁用中断时似乎存在问题。 我可能错了。 如果 CCS 更具描述性、那就好了。
这似乎是一个使用错误。 也许我的代码在设计时不完整。
连接寄存器位于 0xFFFFFFF8、远远超出了存储器区域。 它分开的地方。 因为它在调用 task2() 后似乎中断、所以我的线程化可能出错。
是的,我的 task0_init () 会被调用。 调用 OS_Launch 后出现问题。 它应该循环遍历我所做的所有线程。 我不确定是我的中断、还是其他内容。
感谢您的帮助、这是我的第一个 RTOS、这是一个有趣的学习曲线。
堆叠的 xPSR =0、因此 T 位为 0、这也会生成使用故障。 这可能 是 从 Bx 到低电平位=0 的寄存器所导致的。
我问 task0()、它是从 OS_Launch () 中执行的第一个任务。 我建议在这里使用断点。
0xFFFFFFF8 看起来像一个 EXC_RETURN(尽管我记得的那些寄存器设置了低位位);使用这些 LR 值之一的返回会执行(实际上)RTI。 [参考 A-R-M 第 B1.5.8]
【编辑:添加参考】
我使用的唯一 BX 是链接寄存器。 在 startOS 中如何调用它会出现问题吗? 我在其他汇编函数中使用它、但它似乎没有问题。 可能我在上面一行中尝试启用中断而没有将其禁用、这种情况是不是这样?
哦、我的错。 不、task0() 永远不会被执行。 操作系统启动后、它直接进入 task2()。
CCS 显示为 0xFFFFFFF8(未定义符号)。 每次我遇到这个错误时、我的代码中的某些内容都不完整。 我不确定此代码中包含什么内容。 似乎 C +程序集可以正常工作、但肯定有些奇怪的地方。
似乎我设置的第一个线程将运行两次、然后代码将失败。
似乎线程无法将指针移动到下一个线程。 如果我用 task0 切换了 task2、则 task0 会运行两次然后中断。 那么我会说是的、每个故障看起来都是一样的。
我逐步浏览代码,然后问题来了,似乎是从线程不切换. 但我无法确定这就是问题所在。
在 0x2450 处、我位于 0x46C0BD08(无处)。 TM4C 的数据表没有 0x46XXXXXX 寄存器。 这是一个空的存储器空间。 你在我的代码中看到一些强制随机跳转的转义序列吗?
顺序

但这是栈所指的意思吗? 然后、它在故障前变为 0x00000000。 因此它运行到 task2()、然后重复出现故障:

我预计当一个任务完成时、下一个任务将开始。 这应该是一个循环线程方案。 类似 task2()-> task3()-> task4()-> task5()-> task2()... 你是对的,我永远不会再期待它回来。 我想知道我的日程安排是否错误,因为我循环 task2()。
从你的描述(连续调用 taskN ()) 听起来好像你确实期望每个函数返回(“运行到完成“模型),这就是他们正在做的。
这是可以的,除了 StartOS 使用“BX LR“得到(例如)task2(),这给了目标函数什么都不能返回。 (更重要的是,它在 lr 中提供了一个返回点,它是 task2() 函数的顶部,因此它不会被发现。
我建议您尝试在 0x2450 处使用断点、并逐步执行返回过程以查看它正在执行的操作。
假设我猜对你的想法是正确的,你可以得到一个地方,通过 (1) 调用 taskN() 使用“Blex LR“(因此它返回那里)(2) 调用“scheduler",“,然后 (3) 分支回 StartOS() 的顶部从更新的 TCB 加载内容。
[我在这里没有我的材料,所以我在内存工作,但我认为这是正确的。]
是的,每个线程都应该返回,但循环永远不会结束
我期望 SysTick 处理汇编函数来完成线程之间的转换。
我两次按 0x2450。 这是 task2() 函数的结尾。 在第二个之后、它就会中断。 从这张图片中可以看出、它看到该地址两次。

我就像你说的那样走过去、按两次 0x2450。 我的 SysTick 中断处理程序似乎无法正常工作。 我想知道是否连接不正确。 我运行 0x2440 至 0x2450 两次、然后中断。
我更改为 blx lr、这样 task2() 就不会运行两次、但在它完成后立即中断。 我在装配体文件中的该行有一个故障:

您指的是呼叫调度程序? 在 task2()? 直接插入吗? 返回到操作系统的开头? 您认为它会更改指针地址吗?
这是整个项目,以防它会帮助你看看,如果我不是在称什么对。 谢谢、感谢您的帮助。
被编码后、taskN() 函数全部返回。 如果它们在 120K 个时钟内运行(很可能)、SysTick 就不重要。
如果您打算让他们不返回、您需要确保他们不会返回、例如使用“永久“(“while (1)“)循环。
另一方面、“run to completion“(运行到完成)没有任何问题。 看起来您执行了上述步骤 (1)、但没有执行 (2) 或 (3)。
[编辑:您发布的.zip 似乎缺少 pll.h 和 bsp.h。]
我想我能明白。 我尝试切换我的线程、并注意到它的行为有所不同。 我确实在每个线程中都需要一个 while 循环、这是 SysTick 处理程序正确执行的方式。 我之前有几个时序违例、因此是 faultISR。 这是现在可以正常运行的完整代码。 我还扩展了我的堆栈只是为了安全起见。 只是玩魔鬼鼓吹,我不想玩一个假的正面。 这看起来像是一个红鲱鱼吗? 它可以工作、但不正确?