AVR128DB28 USART 引导加载程序页面

问题描述 投票:0回答:1

我在将数据写入闪存时遇到问题。如果我使用

int main
,编程可以正常运行,但是如果我使用
__attribute__((naked)) __attribute__((section(".ctors"))) void boot(void)
,编程就无法写入我想要分页的地址内存。

#include "libcomp.h"

const flash_adr_t address = 0x1fc00;

#ifndef MAIN_TEST
/*
 * Main boot function
 * It represents the enter point for the device to start execution
 * It represents the enter point for the device to start execution
 * Naked attribute instructs the compiler to omit the function prologue and epilogue
 */
  __attribute__((naked)) __attribute__((section(".ctors"))) void boot(void)
#else
int main(void)
#endif
{
    int value;
    /* Initialize system for AVR GCC support, expects r1 = 0 */
    asm volatile("clr r1");
    SYSTEM_Initialize();
    
    uint8_t buffer[PROGMEM_PAGE_SIZE];
    uint8_t data_flash[PROGMEM_PAGE_SIZE] = "Main boot function. It represents the enter point for the device to start execution.";
    
    value = strlen((char)data_flash);
    FLASH_WriteFlashPage(address, data_flash);
    
    _delay_ms(500); 
    BLD_Init();
    uint16_t i = 0;
    
    while (1)
    {
        if (USART0_IsTxReady()) {
            for (int k = 0; k < value; k++) {
                USART0_Write(FLASH_ReadFlashByte(address + k));
            }
            USART0_Write('\n');
        }
    
        ClrWdt();
        BLD_Tasks();
        
        if (++i == 0)
            LED3_Toggle();
    }

#ifdef MAIN_TEST
return 0;
#endif
}
avr
1个回答
0
投票

我用

__attribute__((naked)) __attribute__((section(".ctors"))) void boot(void)

这些属性没有任何意义。

.ctors
节包含静态构造函数的地址;它不包含可执行代码。

asm volatile("clr r1");

这是黑客行为,可能无法按您的预期工作。避免它或将其移至启动代码的汇编部分。


如果需要自定义启动代码,可以使用

静态构造函数

此功能是 GCC 特有的。语法就像

__attribute__((__constructor__))
static void init (void)
{
    // C/C++ code
}

注意,代码中的

static
限制了构造函数的可见性,它与构造函数是静态的无关。生成的代码将类似于:

.global __do_global_ctors
.section .ctors,"a",@progbits
.p2align    1
.word   gs(init)

__do_global_ctors
将遍历
.ctors
并调用静态构造函数。它位于 libgcc 中,并且 avr-gcc 引用它,因此它是从 libgcc 中拖出的。

.init
部分中的裸代码

此功能特定于 avr-gcc。语法就像

__attribute__((__used__,__unused__,__naked__,__section__(".init8")))
static void init8 (void)
{
  __asm volatile ("; code");
}
  • 裸函数仅支持(内联)汇编。
  • 如果某个
    .initN
    部分包含多个函数,则执行顺序未指定。

以下部分有库对应。启动代码位于/附加到它们:

  • .init0
    :实现向量0:设置
    __zero_reg__
    SP
    EIND
    RAMP*
    寄存器(来自AVR-LibC)。
  • .init4
    :根据需要运行
    __do_copy_data
    __do_clear_bss
    (来自 libgcc)。
  • .init6
    :根据需要运行
    __do_global_ctors
    (来自 libgcc)。
  • .init9
    :调用
    main
    exit
    (来自 AVR-LibC)。

自己的启动代码

如果您完全喜欢自己的启动代码,那么

  • 将该代码编写为(内联)汇编。
  • -nostartfiles
    链接。
  • 将以下符号定义为空:
    __do_copy_data
    __do_clear_bss
    __do_global_ctors
  • 向量表是AVR-LibC启动代码的一部分,因此使用
    -nostartfiles
    你必须提供自己的vectab。
© www.soinside.com 2019 - 2024. All rights reserved.