cubieboard上通过U-boot点亮板载LED
原文http://blog.csdn.net/andy_wsj/article/details/8973818软件环境: 笔记本一台,安装WindowsXP sp3 XP下软件:Source Insight 3.5;SecureCRT;VMware Workstation7.0 虚拟机中安装ubuntu10.04 ubuntu中软件:Vim;编译工具链 arm-none-eabi- 版本4.7.2硬件环境:cubieboard,淘宝自带的串口线和电源线 microSD卡一只,读卡器一个准备工作:U-boot实现SD卡启动,请参考另一篇文章 http://blog.csdn.net/andy_wsj/article/details/8515197 CB的原理图 A10用户手册
在XP下用Source Insight 3.5建立u-boot代码查阅工程。 SecureCRT就是超级终端,XP还需要USB转串口的驱动,网上很多例子。
直接就在u-boot代码查阅工程中搜索"LED",出来一大片结果,最后可以定位通用的LED控制代码在文件: /u-boot-sunxi-sunxi/drivers/misc/status_led.c
调用的函数有__led_init,__led_toggle,__led_set,搜索这几个函数,定位在文件:
/u-boot-sunxi-sunxi/drivers/misc/gpio_led.c
如果需要实现LED控制,则将这两个文件修改成适合cubieboard即可。
1、编译细节处理
以上两个文件需要编译到u-boot里面去,看一下目录/u-boot-sunxi-sunxi/drivers/misc/的Makefile文件内容:.......
COBJS-$(CONFIG_GPIO_LED) += gpio_led.o
COBJS-$(CONFIG_FSL_MC9SDZ60) += mc9sdz60.o
COBJS-$(CONFIG_NS87308) += ns87308.o
COBJS-$(CONFIG_PDSP188x) += pdsp188x.o
COBJS-$(CONFIG_STATUS_LED) += status_led.o
.......可以看出,编译这两个文件需要定义两个宏CONFIG_GPIO_LEDCONFIG_STATUS_LED
2、函数调用细节阅读gpio_led.c代码,调用了gpio_direction_output,gpio_set_value,gpio_get_value三个函数,在工程内搜索一下,找到相关文件就是/u-boot-sunxi-sunxi/arch/arm/cpu/armv7/sunxi/gpio.c再来看看status_led.c内函数的调用情况,要实现LED闪烁,只要调用status_led_tick函数搜索status_led_tick函数,可以看见其他平台的实现,都是在定时器中断中调用。如果不使用中断,最好的莫过于使用命令来控制了。到目录/u-boot-sunxi-sunxi/common看一下,发现已经存在一个文件cmd_led.c,打开看看头文件和宏定义,如果想直接使用这个文件,再看看目录下的Makefile,那么需要定义CONFIG_CMD_LEDCONFIG_BOARD_SPECIFIC_LED如此一来,在/u-boot-sunxi-sunxi/include/configs/sunxi-common.h最后加上下面这几行:/*LED*/#define CONFIG_CMD_LED //使用LED命令,即编译cmd_led.c
#define CONFIG_BOARD_SPECIFIC_LED //板载特别LED
#define CONFIG_GPIO_LED //LED的IO操作,即编译../driver/misc/gpio_led.c
#define CONFIG_STATUS_LED //LED的状态控制操作,即编译../driver/misc/status_led.c, 实际上./driver/misc/status_led.c这个文件没有使用到。
这样编译会报错,因为还有一些LED相关的宏没有定义,定义在何处呢?经过观察,我发现其他开发板都定义在status_led.h内,因此我也打算这样做进入status_led.h,发现正好使用了CONFIG_BOARD_SPECIFIC_LED这个宏做条件编译偷一下懒,status_led.h文件内如下定义之:#elif defined(CONFIG_BOARD_SPECIFIC_LED)#define STATUS_LED_BIT ((7 << 5) + 20) /*PH20, gpio group 7*/#define STATUS_LED_PERIOD (CONFIG_SYS_HZ / 10)#define STATUS_LED_STATE STATUS_LED_BLINKING
#define STATUS_LED_BIT1 ((7 << 5) + 21) /*PH21*/#define STATUS_LED_PERIOD1 (CONFIG_SYS_HZ / 10)#define STATUS_LED_STATE1 STATUS_LED_BLINKING
解释一下这个宏:#define STATUS_LED_BIT ((7 << 5) + 20) /*PH20, gpio group 7*/ 7左移5表示:7乘以32看看原理图,LED画在PH20和PH21上,同过IO控制三极管导通,进而控制LED状态这时候需要看看A10的用户手册,“Port Controller”那一节,若要获得PH的控制寄存器首地址,需要 n*0x24 + 0x00而PH是第7组IO,0x24就是十进制32,因此需要 7 << 5加20表示是第PH20,如果是PH21就加21,当使用这个宏的时候,代码是反过来解析使用的,阅读/u-boot-sunxi-sunxi/arch/arm/cpu/armv7/sunxi/gpio.c,就可以看到这个数据使用的方法了。最后发现是初始化没有调用,在文件cmd_led.c里面还需要调用一下初始化,在函数 do_led 中加入
static int led_init_flag = 0;
if( led_init_flag == 0)
{
for(i=0; led_commands.mask; i++){
__led_init(led_commands.mask, 0);
}
led_init_flag = 1;
}
3、测试
编译,按SD卡启动方式写入SD卡,上电之后输入命令led0onled0off
led1onled1offled all toggle 就可以控制两个LED了
好贴!学习了 有没有不用打指令的方法,比如闪灯,把bin烧入sd,插卡后就可以看到灯闪 寒寒 发表于 2013-7-10 09:05 static/image/common/back.gif
有没有不用打指令的方法,比如闪灯,把bin烧入sd,插卡后就可以看到灯闪
读贴不精,再读一次就知道问题怎么解决了 本帖最后由 tll 于 2013-10-6 22:00 编辑
这个用gpio的命令去控制led就好了,实在没必要上传程序…… 不错哦。。 LZ你好,我在A20的uboot.lds文件中发现是这样写的:OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
arch/arm/cpu/armv7/start.o (.text)
*(.text)
}
. = ALIGN(4);
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
. = ALIGN(4);
.data : {
*(.data)
}
. = ALIGN(4);
. = .;
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
. = ALIGN(4);
__image_copy_end = .;
.rel.dyn : {
__rel_dyn_start = .;
*(.rel*)
__rel_dyn_end = .;
}
.dynsym : {
__dynsym_start = .;
*(.dynsym)
}
_end = .;
.bss __rel_dyn_start (OVERLAY) : {
__bss_start = .;
*(.bss)
. = ALIGN(4);
__bss_end__ = .;
}
/DISCARD/ : { *(.dynstr*) }
/DISCARD/ : { *(.dynamic*) }
/DISCARD/ : { *(.plt*) }
/DISCARD/ : { *(.interp*) }
/DISCARD/ : { *(.gnu*) }
}
也就是在它的前4kB中,就只有一个start.S文件,而没有从nand flsh拷贝到ram 的函数,请问这个是怎么回事...?莫非拷贝功能已经在 start.S中已经实现了?还是...?
页:
[1]