问:如何在同一个工程中使用 C2000Ware 头文件和库以及 SYS/BIOS?
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.
答:
工程配置
要创建使用 C2000Ware 器件支持文件的 SYS/BIOS 工程,通常建议先了解 SYS/BIOS 示例或模板工程,然后向工程添加 C2000Ware 支持文件。在 C2000Ware 中器件的 device_support/<device>/docs/ 目录下,有一个固件开发用户指南,介绍了新建非 SYS/BIOS 工程的分步说明。很多相同的说明可帮助您了解需要将哪些文件、路径变量、包含路径目录、预定义符号等添加到您开始的 SYS/BIOS 工程中。
另一个选项是导入现有的 C2000Ware 示例并将其用作源代码,通过源代码将上述各项复制到 SYS/BIOS 工程中。我在下面显示了 SYS/BIOS“极简”模板工程(要查看有关导入 SYS/BIOS 示例和模板的说明,请点击此处),并向其中添加了 F2837xD driverlib 和其他器件支持文件。具体的文件和设置将因您的器件和初始示例而异。
在“Project Explorer”中复制的文件:
“Include Options”和“Predefined Symbols”:
另请查看其他选项,如“Linked Resources”/“Path Variables”、“Processor Options”和各种链接器选项。
需要注意的几个方面:
复制完所有适当的文件和编译选项后,请尝试编译。如果段缺失(如 .binit)或不符合默认范围,您可能需要解决一些链接器错误。如果您不熟悉如何编辑链接器命令文件,请参阅此文档了解入门信息。
如果您在 SYS/BIOS 生成的 linker.cmd 文件中遇到链接器错误,这可能与“Flash Functions”设置相关。打开工程的 .cfg 文件并编辑引导模块设置,以使用在 .cmd 文件中定义的 RAM 和闪存范围名称。在我的示例中,我将加载/运行存储器与 .cmd 文件用于 .TI.ramfunc 的相同存储器相匹配。在 cfg 脚本中,它如下所示:
Boot.loadSegment = "FLASHD PAGE = 0";
Boot.runSegment = "RAMLS0 PAGE = 0";
当您开始将 C2000Ware 函数调用和头文件添加到 SYS/BIOS 工程时,需要记住一些资源注意事项。
默认情况下,SYS/BIOS 引导模块将配置 SYSCLK 速率。如果您的应用程序代码也在调用 Device_init() 或 InitSysCtrl(),您可能会遇到与此冗余重新配置相关的问题。我建议在 .cfg 文件中禁用此选项,并使用 C2000Ware 函数配置时钟,因为 C2000Ware 更新频率更高,并且具有最新的时钟配置规程。请注意,您仍需要告诉 BIOS SYSCLK 频率是多少,以便能够准确配置其时钟周期。在 cfg 脚本中,它如下所示:
Boot.configureClocks = false;
BIOS.cpuFreq.lo = 200000000;
SYS/BIOS 引导模块还能够配置闪存包装器,从而启用闪存、设置等待状态等。与 SYSCLK 配置一样,注意仅使用一种方法来执行此配置,避免引导模块代码和 C2000Ware 代码之间发生可能的冗余或冲突。
应使用 SYS/BIOS 的 Hwi 模块来管理中断。因此,通常不应在应用程序中编写代码来配置 PIE 矢量表、PIE 寄存器或与中断相关的 CPU 寄存器,也不能冒险覆盖 Hwi 模块所需的配置。示例包括 Interrupt_initVectorTable()、Interrupt_register() 或 InitPieVectTable() 等函数。而是为中断创建 Hwis,并在需要进行更新时调用 SYS/BIOS Hwi 模块函数。
请注意,虽然 SYS/BIOS 将配置 PIE 和 CPU 寄存器,但它不知道外设级中断寄存器/位(SPICTL.SPIINTENA、ETSEL.INTEN 等)。您仍需要在代码中执行这些配置。还要记住,与常规非 BIOS ISR 不同,Hwi 函数不需要 __interrupt 关键字。
SYS/BIOS 时钟模块使用器件的某个 CPU 计时器来运行其系统周期。同样,如果您使用的是 Timestamp 模块,它也可能使用另一个 CPU 计时器。如果您需要在应用中使用 CPU 计时器,请确保其中一个模块尚未使用该计时器。
有关 SYS/BIOS 计时器使用和其他 C28x 特定 SYS/BIOS 各项的更多详细信息,请参阅此常见问题解答主题。
/*
* ======== main.c ========
*/
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include "device.h"
/*
* ======== taskFxn ========
*/
Void taskFxn(UArg a0, UArg a1)
{
for(;;)
{
//
// Turn on LED
//
GPIO_writePin(DEVICE_GPIO_PIN_LED1, 0);
//
// Delay for a bit.
//
Task_sleep(500);
//
// Turn off LED
//
GPIO_writePin(DEVICE_GPIO_PIN_LED1, 1);
//
// Delay for a bit.
//
Task_sleep(500);
}
}
/*
* ======== main ========
*/
Int main()
{
/*
* use ROV->SysMin to view the characters in the circular buffer
*/
System_printf("enter main()\n");
//
// Initialize device clock and peripherals
//
Device_init();
//
// Initialize GPIO and configure the GPIO pin as a push-pull output
//
Device_initGPIO();
GPIO_setPadConfig(DEVICE_GPIO_PIN_LED1, GPIO_PIN_TYPE_STD);
GPIO_setDirectionMode(DEVICE_GPIO_PIN_LED1, GPIO_DIR_MODE_OUT);
BIOS_start(); /* does not return */
return(0);
}