gpt4 book ai didi

c - IAR 的新 EWAVR32 (4.20)。编译器对内联汇编更严格

转载 作者:太空宇宙 更新时间:2023-11-03 23:29:47 25 4
gpt4 key购买 nike

我正在使用 AVR32 AT32UC3C0512C 微 Controller 和 ASF 3.11 框架。将 IAR Workbench 从 4.10 更新到 4.20 新版本后,我遇到了一些 IAR 编译器问题。我在 IAR 的技术支持说明中发现了一些与内联汇编相关的更改。 (实际上不是 EWAVR32,而是 EWAVR):

使用内联汇编程序时出现错误 [Og005] + [Og006]:标签必须在声明时在同一汇编程序语句中引用。该行为在早期版本的编译器平台中是不正确的。新版本使用新的内部编译器平台,该平台更加严格。”

我遇到了同样的问题,但无法编译的代码属于 FreeRTOS 端口。我假设编译器无法识别标签 LABEL_INT_SKIP_RESTORE_CONTEXT_ 因为它没有在同一个 asm 语句中定义。这是代码:

#define portRESTORE_CONTEXT_OS_INT() { extern volatile unsigned portLONG ulCriticalNesting; 
extern volatile void *volatile pxCurrentTCB;
/* Check if AVR32_INTC_INT0 or higher were being handled (case where the OS tick interrupted another */
/* interrupt handler (which was of a higher priority level but decided to lower its priority */
/* level and allow other lower interrupt level to occur). */
/* In this case we don't want to do a task switch because we don't know what the stack */
/* currently looks like (we don't know what the interrupted interrupt handler was doing). */
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */
/* will just be restoring the interrupt handler, no way!!! */

__asm__ __volatile__ (
"ld.w r0, sp[9*4]\n\t" /* Read SR in stack */
"bfextu r0, r0, 22, 3\n\t" /* Extract the mode bits to R0. */
"cp.w r0, 1\n\t" /* Compare the mode bits with supervisor mode(b'001) */
"brhi LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__) );

/* Else */
/* because it is here safe, always call vTaskSwitchContext() since an OS tick occurred. */
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */
portENTER_CRITICAL();
vTaskSwitchContext();
portEXIT_CRITICAL();

/* Restore all registers */
__asm__ __volatile__ (
/* Set SP to point to new stack */
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)")\n\t"
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)")\n\t"
"ld.w r0, r8[0]\n\t"
"ld.w sp, r0[0]\n"

"LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)":\n\t"

/* Restore ulCriticalNesting variable */
"ld.w r0, sp++\n\t"
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)")\n\t"
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)")\n\t"
"st.w r8[0], r0\n\t"

/* Restore R0..R7 */
"ldm sp++, r0-r7\n\t"

/* Now, the stack should be R8..R12, LR, PC and SR */
"rete"
);

/* Force import of global symbols from assembly */
ulCriticalNesting;
pxCurrentTCB; }

#endif

我一直在考虑尝试在 asm 语句(Call c function using inline assembly)中切换上下文,但我不确定这是否是最佳选择以及它是否真的可行。所以,如果能在这里得到一些建议,如何以另一种方式恢复上下文并避免编译错误,那就太好了。谢谢!

如果您需要它,您可以在 ASF 中轻松找到此代码作为 FreeRTOS 示例 (...asf-3.11.0\common\services\usb\class\msc\device\example_freertos\at32uc3c0512c_uc3c_ek\iar\example_freertos.eww)

最佳答案

好吧,正如我在问题中所说的那样,我只是尝试在 asm 语句中切换上下文(使用内联汇编程序指令调用 c 函数)。因此,使用“RCALL”(相对调用子程序):

"RCALL vPortEnterCritical\n\t"
"RCALL vTaskSwitchContext\n\t"
"RCALL vPortExitCritical\n\t"

孔代码如下所示:

#define portRESTORE_CONTEXT_OS_INT() 
{
extern volatile unsigned portLONG ulCriticalNesting;
extern volatile void *volatile pxCurrentTCB;

/* Check if AVR32_INTC_INT0 or higher were being handled (case where the OS tick interrupted another */
/* interrupt handler (which was of a higher priority level but decided to lower its priority */
/* level and allow other lower interrupt level to occur). */
/* In this case we don't want to do a task switch because we don't know what the stack */
/* currently looks like (we don't know what the interrupted interrupt handler was doing). */
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */
/* will just be restoring the interrupt handler, no way!!! */

__asm__ __volatile__ (
"ld.w r0, sp[9*4]\n\t" /* Read SR in stack */
"bfextu r0, r0, 22, 3\n\t" /* Extract the mode bits to R0. */
"cp.w r0, 1\n\t" /* Compare the mode bits with supervisor mode(b'001) */
"brhi LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)"\n\t"

/* Else */
/* because it is here safe, always call vTaskSwitchContext() since an OS tick occurred. */
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */
"RCALL vPortEnterCritical\n\t"
"RCALL vTaskSwitchContext\n\t"
"RCALL vPortExitCritical\n\t"

/* Restore all registers */
/* Set SP to point to new stack */
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)")\n\t"
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)")\n\t"
"ld.w r0, r8[0]\n\t"
"ld.w sp, r0[0]\n"

"LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)":\n\t"

/* Restore ulCriticalNesting variable */
"ld.w r0, sp++\n\t"
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)")\n\t"
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)")\n\t"
"st.w r8[0], r0\n\t"

/* Restore R0..R7 */
"ldm sp++, r0-r7\n\t"

/* Now, the stack should be R8..R12, LR, PC and SR */
"rete"
);

/* Force import of global symbols from assembly */
ulCriticalNesting;
pxCurrentTCB;
}

这对我有用,到目前为止我没有发现我们系统的行为有任何差异。我希望这可以帮助那些必须从 IAR Workbench 4.10 迁移到 4.20 的人。

关于c - IAR 的新 EWAVR32 (4.20)。编译器对内联汇编更严格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18653055/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com