工具与软件:
您好!
我们使用的是 MCU PLUS SDK 09.01 tiarmclang LTS 3.2.0。 我们通过自己的通信协议的附加层使用 IPC。 目前、我们在一个集群中使用两个内核、但也可以使用全部4个内核。 另外请注意、对于以下内容、我们不使用 SYSCFG、但我们修改了 SDK-API、这样、驱动程序将不会获取数组的索引、但可以直接将 Config 用作指针参数。 因此,变化很小,只与 open()函数相关。
一般来说、我们有很多方法可以修改驱动程序设置。 例如、在 SpiDriver 等的书面构造函数设置后、模块的时钟立即激活、并设置正确的中断等。 一般来说、这种方法已经效果很好。
我们现在可以将我们的软件组件从一个内核切换到另一个内核、但由于我们(目前)未实现任何用于外设访问的特殊处理程序、因此我们需要从两个内核访问外设。
因此、在我们的示例中、假设设置如下:
一个集群中的2个内核(mcu0_0和 mcu0_1)都在相同 MCSPI 模块但不同的通道上访问 SpiDriver。
我们对阻止并发访问的想法是使用自旋锁。 所以每个驱动程序都有自己的硬编码 spinlock-id。 有一些限制、但我稍后会在 PS 中处理这些限制。
通常、一旦一个驱动程序访问 SPI 驱动程序、我们就锁定自旋锁。 无论它是任何打开、关闭、收发或任何其他-旋钮锁被锁定。 我们当前的用例是在一个 SPI 通道上的移位寄存器处安装一些 LED、并在另一个 SPI 通道上安装一个 EEPROM (我们使用我们自己的驱动器、而不是 SDK 的驱动器)。
有意思的是、这似乎通过 CCS 的加载实现了完美的工作。 可以从这两个内核访问 SPI。
但如果从闪存引导、它将无法正常工作。 当我们尝试从 SciClient 写入寄存器时、出现数据中止(sciclientobj.c 中的 CSL_REG32_WR_RAW)。很遗憾、中止处理程序不提供任何有用的信息。 但 CP15寄存器显示:0x1808、所以在写入时包含一个外部中止。 数据故障地址为0x4D001004。 因此、根据 TRM、它是 DMASS0_SEC_PROVISION_SRC_TARGET_DATA 的一部分。
我们无法真正调试这种情况、因此在这里可能需要您的帮助。 这似乎是某种种族条件,行为真的很奇怪. 我们在一个内核上实现了超过10秒的睡眠、以排除同时激活某些东西的可能性、但这并没有阻止它。 有趣的是、当我们在开始时添加一个 loop_forever (例如在引导加载程序调试中)、然后让其随后运行时、它会起作用。
为了更详细地解释启动(每个内核),因为我们不使用 SYSCFG,请参阅从 main()运行:
1. Hwip_init()
2、设置时钟(内核0_0的 HWTimer 8和内核0_1的 HWTimer 9,设置中断正确,调用 ClockP_init ()))
3. Hwip_open()
4. Sciclient_init (CoreID)
5.设置 IPC、等待同步
6.设置 SpiDrivers:
6.1设置 SPI 模块的中断、自旋锁 ID 和使能时钟(根据使用的 SPI 模块)
6.2打开 SpiDriver
6.3调用 MCSPI_chConfig (当前针对每个内核上的每个通道)
所以,由于错误发生在防火墙范围内的某个地方,我不知道该怎么做。 这与 boardcfg 相关吗? 但是、为什么在通过 CCS 加载或开始使用 while 循环的引导加载程序-调试-方法时、它能够起作用呢?
PS:
是的、我们知道自旋锁可能不是一个好主意。 TRM 指出执行锁定的时间不应超过200ns、操作应短等 理论上存在的问题是:一个内核的任务优先级低、用于访问 SPI、将其锁定、而另一个内核的任务具有更高的优先级、当尝试访问同一外设以及尝试在 while 循环中获取自旋锁时、可能会被阻止、从而相当长地阻止一个内核。 此外、如果在同一个内核上有多个实体想要访问同一个 SPI 模块、如果一个较低优先级任务取代了自旋锁、而一个较高优先级任务-也使用了 SPI 模块-取代了这个任务、那么他们自身就会死锁。 但不应发生最后一种情况、因为我们还使用信标确实会阻止从一个内核进行并发访问。 自旋锁随后直接锁定(当然也会释放)。
为了至少减小影响、我们为每次自旋锁检查设置了超时和睡眠(1)、以便确保较低的优先任务可以继续运行。 我们稍后可能会细化此行为。
我们现在可以顺利完成调试、因为至少我们可以保证不会同时访问 SPI 模块。
您是否知道我们可以在这里做些什么来运行这个程序?
此致
Felix