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] [参考译文] 【常见问题解答】PROCESSOR-SDK-AM64X:如何使用 GCC 为 A53 内核启用构造函数/析构函数属性

Guru**** 2419530 points
Other Parts Discussed in Thread: SYSCONFIG

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1536691/faq-processor-sdk-am64x-how-to-enable-constructor-destructor-attribute-for-a53-core-using-gcc

器件型号:PROCESSOR-SDK-AM64X
主题:SysConfig 中讨论的其他器件

工具/软件:

我在 C 代码中使用__attribute__((constructor (x)/析构函数 (y)) 属性作为 A53 内核和 GCC 编译器。

GCC 属性是__attribute__(析构函数 (x))、其中 x 表示 API 优先级编号。

我无法看到在 main 函数之前调用构造函数、并且在 main 退出后也不调用析构函数。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    请按照以下步骤操作。

    1.在中定义 init 和 deinit 函数  BOOT_ARMv8.c  文件位于  ${MCU+SDK} \ source\kernel\nortos\DPL\A53。

    typedef void (*func_ptr)(void);
    extern func_ptr __preinit_array_start[0], __preinit_array_end[0];
    extern func_ptr __init_array_start[0], __init_array_end[0];
    extern func_ptr __fini_array_start[0], __fini_array_end[0];
    
    void __init()
    {
        for ( func_ptr* func = __preinit_array_start; func != __preinit_array_end; func++ )
                (*func)();
        for ( func_ptr* func = __init_array_start; func != __init_array_end; func++ )
               (*func)();
    }
    
    void __deinit()
    {
        for ( func_ptr* func = __fini_array_start; func != __fini_array_end; func++ )
                (*func)();
    }
    
    
    

    2.修改  __SYSTEM_START  传递函数。

    int __system_start(void)
    {
        volatile unsigned int * bs;
        volatile unsigned int * be;
        unsigned int * dl;
        unsigned int * ds;
        unsigned int * de;
    
    #if defined (SMP_FREERTOS)
    
        /* Initialization of bss section is done only once (From Core0) */
        if (0 == Armv8_getCoreId())
        {
            /* initialize .bss to zero */
            bs = & __bss_start__;
            be = & __bss_end__;
            while (bs < be)
            {
                *bs = 0;
                bs++;
            }
    
            /* relocate the .data section */
            dl = & __data_load__;
            ds = & __data_start__;
            de = & __data_end__;
            if (dl != ds)
            {
                while (ds < de)
                {
                    *ds = *dl;
                    dl++;
                    ds++;
                }
            }
    
            /* Set flag to indicate bss initialization is done by Core0 */
            bssInitDone = 1;
        }
        else
        {
            /* Core1 should wait until bss initialization is done by Core0 */
            while(bssInitDone != 1)
            {
                ;
            }
        }
    
    #else
        /* initialize .bss to zero */
        bs = & __bss_start__;
        be = & __bss_end__;
        while (bs < be)
        {
            *bs = 0;
            bs++;
        }
    
        /* relocate the .data section */
        dl = & __data_load__;
        ds = & __data_start__;
        de = & __data_end__;
        if (dl != ds)
        {
            while (ds < de)
            {
                *ds = *dl;
                dl++;
                ds++;
            }
        }
    #endif
    
    #if defined (SMP_FREERTOS)
    
        /* Wait for MMU init to be done by Core0 when running SMP FreeRTOS */
        /* This is done to synchronise between Core0 and Core1 so that MMU initialization is done by Core 0 */
        if (1 == Armv8_getCoreId())
        {
            while(mmuInitDone != 1)
            {
                ;
            }
        }
    
    #endif
        CacheP_enableSMP();
        /* initialize mmu and cache */
        __mmu_init();
    
    #if defined (SMP_FREERTOS)
    
        /* Set flag to indicate the MMU initialization completion by Core0 */
        if (0 == Armv8_getCoreId())
        {
            mmuInitDone = 1;
            CacheP_wb((void *)&mmuInitDone, sizeof(mmuInitDone), CacheP_TYPE_ALL);
        }
    
    #endif
    
        __init();
        main();
        __deinit();
    
        Armv8_exit();
    
        return(0);
    }

    3.构建内核的库。

    cd ${MCU+SDK}/source/kernel/nortos
    gmake -s -f makefile.am64x.a53.gcc-aarch64 PROFILE=debug
    gmake -s -f makefile.am64x.a53.gcc-aarch64 

    4.在示例的 SysConfig 文件中、添加以下部分。

    .ARM.exidx : {} > DDR
        .preinit_array     :
    	 {
    	    PROVIDE_HIDDEN (__preinit_array_start = .);
    	    KEEP (*(.preinit_array*))
    	    PROVIDE_HIDDEN (__preinit_array_end = .);
    	 } > DDR
    
    	 .init_array :
    	 {
    	    PROVIDE_HIDDEN (__init_array_start = .);
    	    KEEP (*(SORT(.init_array.*)))
    	    KEEP (*(.init_array*))
    	    PROVIDE_HIDDEN (__init_array_end = .);
    	 } > DDR
    
    	 .fini_array :
    	 {
    	    PROVIDE_HIDDEN (__fini_array_start = .);
    	    KEEP (*(SORT(.fini_array.*)))
    	    KEEP (*(.fini_array*))
    	    PROVIDE_HIDDEN (__fini_array_end = .);
    	 } > DDR

    5.重建应用程序。

    然后能够执行构造函数和析构函数。

    此致、

    Tushar