【Qzone】这个比较有趣 总结一下笔记

本文介绍如何在U-Boot中添加控制LED灯的命令,包括无参数的led命令和带参数的ledon及ledoff命令。通过修改源代码、配置文件并解决编译错误,实现从Ubuntu终端控制mini2440开发板上的LED灯。
2014-10-26 02:24


这个比较有趣 总结一下笔记


搞到这个点,我也是醉了。


内容:
在uboot中添加不带参数的led命令
和带参数的led on 及led off命令
通过ubuntu的kermit终端 控制mini2440上的灯


首先
在目录u-boot-1.1.6/common/下新建一个cmd_led.c文件或复制一个cmd_bdinfo.c改名为cmd_led.c文件
建议复制再修改


然后
修改cmd_led.c文件
找到命令框架
U_BOOT_CMD(
name,maxargs,rep,cmd,usage,help
)//6个参数


更改为如下:
修改前
U_BOOT_CMD(
bdinfo, 1, 1, do_bdinfo,
"bdinfo - print Board Info structure\n",
NULL
);
修改后
U_BOOT_CMD(
led, 1, 1, do_led,
"led - control the led on the mini2440\n",
NULL
);
修改do_dbinfo()函数:
注意,我们用的是ARM板子
#else /* ARM */所以修改下面的代码
修改后如下:
int do_led ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
rGPBCON=0x15400;//开启4个LED灯
rGPBDAT=0x00;//4个LED灯 亮
return 0;
}


还有注意make时 
要在此路径command/MakeFile下的
MakeFile文件中cmd_bdinfo.o旁边或后面添加cmd_led.o


此时在ubuntu终端中执行make 会报错
如下:
cmd_led.c: In function 'do_led':
cmd_led.c:244: error: 'rGPBCON' undeclared (first use in this function)
cmd_led.c:245: error: 'rGPBDAT' undeclared (first use in this function)


解决方法1:
像裸机程序一样加入头文件 在2440addr.h中找到如下代码 并且复制添加到cmd_led.c文件中
如下:
#define rGPBCON (*(volatile unsigned *)0x56000010) //Port B control
#define rGPBDAT (*(volatile unsigned *)0x56000014) //Port B data


此时再make一下 没出错
arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin
成功生成u-boot.bin文件 下载 测试


烧写生成的u-boot.bin文件到mini2440
上电后
ubuntu端的kermit显示如下:
U-Boot 1.1.6 (Oct 26 2014 - 00:31:39)


DRAM: 64 MB
Atmel: AM29LV160DB (16Mbit)
Flash: 2 MB
In: serial
Out: serial
Err: serial
SMDK2410 # 




默认此时mini2440开发板上亮两个灯 正常


此时 在终端输入命令led
后按回车键
mini2440开发板上4个LED灯亮 成功完成led命令的添加


下面用第二种
添加头文件的方法(也建议在以后的开发中用这种方法)


将第一种方法中的
#define rGPBCON (*(volatile unsigned *)0x56000010) //Port B control
#define rGPBDAT (*(volatile unsigned *)0x56000014) //Port B data
用代替
#include<s3c24x0.h>
代替


在目录include/s3c24x0 下的s3c24x0.h文件中
修改如下:
#if 0
改为
#if 0


代码会由灰色变为彩色 有效


因为其中屏蔽了以下代码 修改使其有效
#define rGPBCON (*(volatile unsigned *)0x56000010)
#define rGPBDAT (*(volatile unsigned *)0x56000014)


保存后 再次make


此时会报错如下:
In file included from cmd_led.c:36:
/home/devwang/u-boot-1.1.6/include/s3c24x0.h:563: error: 'S3C24X0_SPI_CHANNELS' undeclared here (not in a function)


解决方法
在s3c24x0.h文件中
Ctrl+F找到该S3C24X0_SPI_CHANNELS结构体 
用/**/将其屏蔽掉即可


修改如下:
修改前
typedef struct {
S3C24X0_SPI_CHANNEL ch[S3C24X0_SPI_CHANNELS];
} /*__attribute__((__packed__))*/ S3C24X0_SPI;
修改后
typedef struct {
/* S3C24X0_SPI_CHANNEL ch[S3C24X0_SPI_CHANNELS];*/
} /*__attribute__((__packed__))*/ S3C24X0_SPI;


再次make OK
下载 烧写 输入led命令 四个灯亮 OK


其他方法:

#if 1
改回原来的
#if 0


补充:
寄存器名不加r 
但裸机中使用时一般加r
现在改rGPBDAT 为GPBDAT


if(strcmp(argv[1],"on")==0)
{
GPBDAT=0x0;
}
if(strcmp(argv[1],"off")==0)
{
GPBDAT=0x7ff;
}


带参数的命令:
如led命令后面增加参数
led on
led off


修改代码如下:
if(strcmp(argv[1],"on")==0)
{
GPBDAT=0x0;
}
if(strcmp(argv[1],"off")==0)
{
GPBDAT=0x7ff;
}


再改:
S3C24X0_GPIO 结构体


S3C24X0_GPIO gpio;//定义结构体变量
gpio.GPBCON=0x15400;
if(strcmp(argv[1],"on")==0)
{
gpio.GPBDAT=0x0;
}
if(strcmp(argv[1],"off")==0)
{
gpio.GPBDAT=0x7ff;
}


补充:
char *argv[]
位置参数 argv


保存,make,烧写,上电
依然才亮两个灯(默认)
说名上面代码无效 但确实执行了那段代码 
可用print查看是否执行
代码如下:
cmd_led.c


gpio.GPBCON=0x15400;
printf("**********start\n");
if(strcmp(argv[1],"on")==0)
{
gpio.GPBDAT=0x0;
printf("**********on\n");
}
if(strcmp(argv[1],"off")==0)
{
gpio.GPBDAT=0x7ff;
printf("**********off\n");
}




输出结果如下
U-Boot 1.1.6 (Oct 26 2014 - 01:27:40)


DRAM: 64 MB
Atmel: AM29LV160DB (16Mbit)
Flash: 2 MB
In: serial
Out: serial
Err: serial
SMDK2410 # 
SMDK2410 # led 
**********start
SMDK2410 # led on
**********start
**********on
SMDK2410 # led off
**********start
**********off
SMDK2410 # 


但还是只亮两个灯
为什么不亮4个灯呢?


注意:
led
led on
led off
给指令加一个参数后要修改如下代码:


修改前
U_BOOT_CMD(
led, 1, 1, do_led,
"led - control the led on the mini2440\n",
NULL
);
修改后
U_BOOT_CMD(
led, 2, 1, do_led,
"led - control the led on the mini2440\n",
NULL
);


六个参数解释:
#name,maxargs,rep,cmd,usage,help
#name:命令的名称
#maxargs:最多的参数个数
#rep:是否允许重复执行 重复 SMDK2410# 没命令 回车
#cmd:执行的命令函数
#usage:简要的说明
#help:帮助


回答上个为什么。
因为在 定义gpio时没有指定物理地址
地址 GPBCON GPBDAT 的地址没写 结构体中
gpio要指向一个物理地址 而非随机分配 即指向寄存器所在的地址


那么如何让让gpio指向0x56000000(不同板子地址不一样 查数据手册)


使用S3C24X0_GetBase_GPIO() 函数
其返回值为return S3C24X0_GPIO_BASE
0x5600000


故修改如下:
S3C24X0_GPIO *gpio=S3C24X0_GetBase_GPIO();//指向0x56000000
gpio->GPBCON=0x15400;
if(strcmp(argv[1],"on")==0)
{
gpio->GPBDAT=0x0;
}
if(strcmp(argv[1],"on")==0)
{
gpio->GPBDAT=0x7ff;
}


补充:
此处*gpio为指针类型
而非原来的gpio结构体变量
故点“.”号
改为径箭头“->”号


make一下
出错:
/home/devwang/u-boot-1.1.6/common/cmd_led.c:255: undefined reference to `S3C24X0_GetBase_GPIO'


在cmd_led.文件中
加入头文件
#include<s3c2410.h>


因为
u-boot1.1.6/include/s3c2410.h
里面有函数
static inline S3C24X0_GPIO * const S3C24X0_GetBase_GPIO(void)
{
return (S3C24X0_GPIO * const)S3C24X0_GPIO_BASE;
}


再次make OK
arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin


把生成的u-boot.bin烧写到2440上
终端显示如下:


U-Boot 1.1.6 (Oct 26 2014 - 01:58:06)


DRAM: 64 MB
Atmel: AM29LV160DB (16Mbit)
Flash: 2 MB
In: serial
Out: serial
Err: serial
SMDK2410 # led on
SMDK2410 # led off
SMDK2410 # led on
SMDK2410 # led off
SMDK2410 # 


结果:
输入led on 命令后
回车
2440上4个灯亮
输入led off 命令后
回车
2440上4个灯灭
输入led on 命令后
回车
2440上4个灯亮
输入led off 命令后
回车
2440上4个灯灭


亲测可行 OK !!!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值