不为 ATmel 处理器调用 LLVM 全局构造函数

问题描述

我已经编译了一个 cpp 代码并将其下载到 Arduino Uno 以闪烁 LED。该代码工作正常。 但是,当我将其转换为 .ll 并从 .ll 转换为目标文件,然后进行十六进制并上传时,代码停止工作。 Arduino 没有 LED 闪烁。

如果我直接寻址端口:

typedef unsigned char uint8_t;
typedef uint8_t * volatile port_type;

const port_type portB = (port_type) 0x25;
const port_type ddrB = (port_type) 0x24;

它可以正常工作,但如果我通过全局构造函数初始化端口,它就不起作用:

int getPortB() {return 0x25;}
int getDdrB() {return 0x24;}

const port_type portB = (port_type) getPortB();
const port_type ddrB = (port_type) getDdrB();

这是因为根本没有调用全局构造函数。如果我通过

从主函数调用
call addrspace(1) void @global_var_init()

它会起作用。

我使用以下命令编译 ll 文件并将其下载到 Arduino uno:

llvm-as-9 blink1.ll -o blink1.bc 
llc-9 -filetype=obj blink1.bc 
avr-g++ -mmcu=atmega328p blink1.o -o blink1 
avr-objcopy -O ihex -R .eeprom blink1 blink1.hex 
avrdude -F -V -c arduino -p ATMEGA328P -P /dev/ttyUSB0 -b 115200 -U flash:w:blink1.hex

blink1.ll

; ModuleID = 'blink1.cpp'
source_filename = "blink1.cpp"
target datalayout = "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8"
target triple = "avr"

@portB = dso_local global i8* null,align 1
@ddrB = dso_local global i8* null,align 1
@llvm.global_ctors = appending global [1 x { i32,void () addrspace(1)*,i8* }] [{ i32,i8* } { i32 65535,void () addrspace(1)* @global_var_init,i8* null }]


; Function Attrs: noinline
define internal void @global_var_init() addrspace(1) {
  %1 = inttoptr i16 37 to i8*
  store volatile i8* %1,i8** @portB,align 1
  %2 = inttoptr i16 36 to i8*
  store volatile i8* %2,i8** @ddrB,align 1
  ret void
}

; Function Attrs: noinline nounwind optnone
define dso_local void @delay_500ms() addrspace(1) {
  call addrspace(0) void asm sideeffect "ldi  r19,150 \0A\09ldi  r20,128 \0A\09ldi  r23,41 \0A\09L1: \0A\09dec  r20 \0A\09brne L1 \0A\09dec  r19 \0A\09brne L1 \0A\09dec  r23 \0A\09brne L1 \0A\09",""() #3,!srcloc !2
  ret void
}

; Function Attrs: noinline norecurse nounwind optnone
define dso_local i16 @main() addrspace(1) {
  ; call addrspace(1) void @global_var_init()

  %1 = alloca i16,align 1
  store i16 0,i16* %1,align 1
  %2 = load volatile i8*,align 1
  store i8 32,i8* %2,align 1
  br label %3

3:                                                ; preds = %0,%3
  %4 = load volatile i8*,i8* %4,align 1
  call addrspace(1) void @delay_500ms()
  %5 = load volatile i8*,align 1
  store i8 0,i8* %5,align 1
  call addrspace(1) void @delay_500ms()
  br label %3
}

!0 = !{i32 1,!"wchar_size",i32 2}
!1 = !{!"clang version 9.0.1-+20210314105943+c1a0a213378a-1~exp1~20210314220516.107 "}
!2 = !{i32 1296,i32 1313,i32 1338,i32 1362,i32 1377,i32 1397,i32 1416,i32 1436,i32 1455,i32 1475,i32 1494}

这是一个 LLVM 错误还是我做错了?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)