我已经编译了一个 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
眨眼1.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, void () addrspace(1)*, 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*, i8** @ddrB, align 1
store i8 32, i8* %2, align 1
br label %3
3: ; preds = %0, %3
%4 = load volatile i8*, i8** @portB, align 1
store i8 32, i8* %4, align 1
call addrspace(1) void @delay_500ms()
%5 = load volatile i8*, i8** @portB, 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 错误还是我做错了?