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.

[FAQ] 如何在 SYS/BIOS 工程中使用 C2000Ware 文件?

Other Parts Discussed in Thread: C2000WARE, SYSBIOS

问:如何在同一个工程中使用 C2000Ware 头文件和库以及 SYS/BIOS?

  • 答:

    工程配置

    要创建使用 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”和各种链接器选项。

    需要注意的几个方面:

    • 在上面的示例中,我使用了 C2000Ware 示例中的闪存连接器命令文件,并删除了原始的 cmd 文件。您可以选择其中一个,但如果同时选择这两个选项,它们将会发生冲突。
    • 我没有复制asm 文件 - 引导模块“Enable boot from FLASH”选项将具有相同的用途。同样,如果您尝试同时保留这两者,则可能会收到链接器错误。
    • 默认情况下,C28x SYS/BIOS 示例使用 COFF。如果需要,您可以将 ABI 设置更改为 EABI。

    复制完所有适当的文件和编译选项后,请尝试编译。如果段缺失(如 .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 各项的更多详细信息,请参阅此常见问题解答主题

    组合的 SYS/BIOS“极简”和 C2000Ware led_ex1_blinky 示例源代码:

     

     

    /*

     *  ======== 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);

    }