我希望在uboot中读取i2c的值, 并根据值,执行命令。我需要它在脚本中
命令本身并不重要,但是,它的激活必须基于i2c芯片的值。
到目前为止,我只能打印i2c中的值,但我无法使用它们。
=> i2c md 20.1 0 8
0000: ff ff ff ff ff ff ff ff ........
我也有条件:
=> setenv myvalue 0
=> if test $myvalue -eq 1; then echo 'hello'; fi
=> setenv myvalue 1
=> if test $myvalue -eq 1; then echo 'hello'; fi
hello
=>
我可以针对i2c做一些特定的事情:
=> if i2c probe; then echo "true"; else echo "false"; fi
Valid chip addresses: 20 21 22 23
true
但我无法将i2c中的值用于条件。我该如何解决这个问题?
答案 0 :(得分:1)
我没有看到任何直截了当的方法,但以下情况应该有效:
i2c read
mw
将比较值写入内存中。cmp
比较两个内存区域 - 这应该以{{1}}的形式工作,以根据结果有条件地执行某些操作。您将不知何故必须知道特定系统上的RAM块的地址,这些RAM可以在引导过程的这个阶段安全地写入。
答案 1 :(得分:0)
u-boot中没有提供解决方案来实现您的目标(轻松)。我编写了一个u-boot命令,它允许您从RAM读取并将值存储到一个环境变量中,以便您进行比较。
#include <common.h>
#include <config.h>
#include <command.h>
int do_setenvram(
cmd_tbl_t *cmdtp,
int flag,
int argc,
char *argv[]
) {
unsigned int *addr;
unsigned long len;
uint32_t val;
char buffer[200];
char type;
char returntype;
if ( argc < 3 || argc > 4 ) {
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
addr = (char *)simple_strtol(argv[2], NULL, 16);
if ( !addr ) {
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
if ( argc == 4 ) {
len = simple_strtol(argv[3], NULL, 16);
if ( !len || len >= buffer ) {
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
}
int option = strlen(argv[0]);
if ( option > 2 && argv[0][option-3] == '.' ) {
type = argv[0][option-2];
returntype = argv[0][option-1];
} else if ( option > 2 && argv[0][option-2] == '.' ) {
type = argv[0][option-1];
} else {
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
switch ( type ) {
case 'b':
val = *((unsigned char *)(addr));
break;
case 'w':
addr = (unsigned short *)simple_strtol(argv[2], NULL, 16);
val = ntohs(*addr);
break;
case 'l':
addr = (unsigned int *)simple_strtol(argv[2], NULL, 16);
val = htonl(*addr);
break;
case 'k':
addr = (unsigned int *)simple_strtol(argv[2], NULL, 16);
val = (*addr);
break;
case 's':
memset(buffer, 0, sizeof(buffer));
memcpy(buffer, addr, len);
break;
default:
return 0;
}
if ( returntype == 'd' ) {
sprintf(buffer, "%d", val);
} else if ( type != 's' ) {
sprintf(buffer, "0x%x", val);
}
setenv(argv[1], buffer);
return 0;
}
/* ------------------------------------------------------------------------- */
U_BOOT_CMD(
setenvram, 4, 0, do_setenvram,
"set environment variable from ram",
"name addr {len}\n"
"[.b, .w, .l, .s, .k] name address {max_length}\n"
" - set environment variable 'name' from addr 'addr'\n"
);
所以在你的情况下:
i2c read <chip> <memory-location>
md <memory-location>
setenvram.x <variable-name> <memory-location> <length>
使用我在上面提供的u-boot命令,其中参数.x
是以下之一:参数[1]选项:
.b - 位(1个字节)。
.w - 字(2个字节)。主机 - 网络字节转换。
.l - 长(4个字节)。主机 - 网络字节转换。
.k - 长(4个字节)。
.s - string(用户指定的字节数)。 //注意:{length}是必需的。
在此处的提交中可以看到更多示例和用法:https://github.com/bwenstar/uboot-imx/commit/5996e854f82ecb9005d2b9546a71fca458784204