完全没有问题...
首先,让串口运行起来。我有一块旧版的BeagleBoard,记得串口和I/O方面的一切都很麻烦,但是还是要在上面安装一个串口,这样你就可以看到它的启动过程。
它会启动uboot,你可以按下一个键或esc键之类的东西来中断正常的启动(进入Linux)。从uboot提示符开始,很容易加载你的第一个简单程序。
我手头上有一些BeagleBoard代码,但是没有我的BeagleBoard本身,所以请访问http://sam7stuff.blogspot.com/,了解如何混合一些启动汇编和C代码,用于无操作系统的嵌入式程序(针对arm,我还有其他thumb/cortex-m3平台的许多示例,但是它们的启动方式略有不同)。
Sam7端口和内存地址空间与BeagleBoard/OMAP完全不同。以上是一个框架,您可以更改或重新发明它。
您需要从ti.com获取OMAP 35x技术参考手册。在他们的网站上搜索omap部件OMAP3530。
还需要BeagleBoard文档。例如,此语句:
BeagleBoard提供单个RS232端口,可访问UART3的TX和RX线路。
因此,在omap的trm中搜索UART3会显示它位于0x49020000的基址处。(通常很难找出某些东西的完整地址,因为手册通常在这里有一部分内存映射,在那里有另一部分,并且在寄存器描述附近,只有地址的较低几位被指出。)
查看UART寄存器,THR_REG是你要写入的将要通过串口发送的字节,注意它是一个16位寄存器。
知道了这些,我们就可以编写第一个程序:
.globl _start
_start:
ldr r0,=0x49020000
mov r1,#0x55
strh r1,[r0]
strh r1,[r0]
strh r1,[r0]
strh r1,[r0]
strh r1,[r0]
hang: b hang
这是一个针对它的makefile:
```makefile
```
ARMGNU = arm-none-linux-gnueabi
AOPS = --warn --fatal-warnings
COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding
uarttest.bin : uarttest.s
$(ARMGNU)-as $(AOPS) uarttest.s -o uarttest.o
$(ARMGNU)-ld -T rammap uarttest.o -o uarttest.elf
$(ARMGNU)-objdump -D uarttest.elf > uarttest.list
$(ARMGNU)-objcopy uarttest.elf -O srec uarttest.srec
$(ARMGNU)-objcopy uarttest.elf -O binary uarttest.bin
使用的链接脚本:
/* rammap */
MEMORY
{
ram : ORIGIN = 0x80300000, LENGTH = 0x10000
}
SECTIONS
{
.text : { *(.text*) } > ram
}
请注意,codesourcery的Linux版本被称为交叉编译器,但实际上,这段代码只需要汇编器和链接器(binutils工具)。arm-none-eabi-...类型的交叉编译器同样可以使用(假设您从codesourcery获取了精简版工具)。
一旦你有了一个.bin文件,请查看uboot的帮助文档,我不记得确切的命令,但它可能是“l 0x80300000”或“load_xmodem”之类的东西。基本上,你想通过串口将.bin文件传输到处理器的内存空间中,然后使用go或其他命令告诉uboot跳转到你的程序。
运行时,你应该会看到一些U字符(0x55是“U”)从串口输出。
你的主要目标是先建立一个简单的串口例程,以便你可以打印一些调试信息并查看程序正在执行什么操作。稍后你可以涉及到图形等内容,但首先要使用串口。
有些作弊行为。由于uboot启动并初始化了串口,我们不必自己再去初始化。只需将字节推入thr即可。但很快你就会溢出thr的存储并且丢失字节,所以你需要读取omap的trm,并找到一些指示发送器为空的位,它已经传输完毕,然后创建一个uart_send类型的函数,它轮询发送器是否为空,然后发送一个字节出去。
另外,请忘记printf(),你需要创建自己的打印数字(八进制或十六进制最容易),以及可能的打印字符串。我一整天都在做这样的工作,99% 的时间,我只使用一个小例程将32位十六进制数输出到串口。从这些数字中,我可以调试并查看程序的状态。
因此,采用sam7模型或类似模型(请注意编译器和链接器命令行选项的重要性,以及链接命令行上文件的顺序,第一个文件必须是入口点,如果您想让.bin文件的第一个指令/字成为入口点,那通常是个好主意,因为日后您需要知道如何控制这个过程以从ROM启动)。
你可以在不删除或替换uboot的情况下做很多事情,如果你开始查看基于Linux的uboot引导命令,你会发现它几乎是从闪存或其他地方复制了一个.bin文件到内存中的一个位置,然后跳转到它。现在跳转到Linux,特别是ARM Linux,涉及到一些ARM表和可能设置一些寄存器,而您的程序不需要这些。基本上,无论你想使用哪个命令,在将程序复制到RAM后,你都需要在uboot的启动脚本中编写它,如果你选择让板子像使用Linux一样启动和运行。
说可以使用jtag而不依赖于uboot工作,但是当你选择这条路时,需要在引导时完成一定数量的工作以使芯片运行起来,特别是配置uart可能需要一些时钟分频器、时钟使能、I/O使能等等。这就是为什么sam7示例从闪烁led开始而不是uart的原因。amotek jtag-tiny是一个很好的jtag wiggler,我一直很满意,在工作中每天都会用到它们。beagleboard可能使用TI引脚布局而不是标准的ARM引脚布局,因此您可能需要更改接线。我不知道OMAP是否会直接给您访问arm tap控制器的权限,还是需要进行一些ti特定的操作。暂时最好选择uboot路线。
一旦你有了一个框架,其中只有少量的汇编代码来设置堆栈并跳转到入口点C代码,你就可以开始将该C代码转换为操作系统或进行任何你想做的事情。如果您查看chibios、prex或其他类似的rtos,您会发现它们有小的asm引导代码,将它们带入系统。同样,其中包括调试和非调试的uart例程。许多rtos都要使用中断而不是轮询thr是否为空。
如果这篇文章不能让你成功运行hello world(让你做一些工作),请告诉我,我会找出我的beagleboard并创建一个完整的示例。虽然我的板子不完全符合你的需求,但对于hello world来说应该足够接近了。