背景介绍
基本不用官方镜像,通常给NanoPi 烧写Armbian镜像。本次使用的NanoPi Neo Core也是烧写的此固件。
NanoPi基于WiringPi这个开源库自己做了一个WiringNP库,可用来操作GPIO接口。从https://github.com/friendlyarm/WiringNP/blob/master上copy,编译安装之后。运行bash gpio readall
之后。提示一下错误:
piBoardRev: Unable to determine board revision from /proc/cpuinfo
-> Is not NanoPi based board.
-> You may want to check:
-> http://www.lemaker.org/
open /sys/class/sunxi_info/sys_info failed
分析
其实这个问题已经很清晰了。尝试查找/sys/class/sunxi_info/sys_info文件失败。因此识别不了板子的型号。
最初的想法是将讲官方镜像的/sys/class/sunxi_info/sys_info拷贝过来。但是暂时手边没有安装这个文件的板子。就想着能不能找来替换一下。但是在搜索的过程中却找到了另一种方法。
解决方法
这个解决方法我的思路类似。不过这里的方法是新创建了一个新文件/etc/sys_info(我想是为了防止冲突吧)。将本该填入/sys/class/sunxi_info/sys_info的内容填写到/etc/sys_info中。
1、 添加/etc/sys_info文件
比方说Nanopi Neo应该添入的文件如下:
sunxi_platform : Sun8iw7p1
sunxi_secure : normal
sunxi_chipid : 2c21020e786746240000540000000000
sunxi_chiptype : 00000042
sunxi_batchno : 1
sunxi_board_id : 1(0)
2、修改boardtype_friendlyelec.c文件
然后修改WiringNP目录下的wiringPi/boardtype_friendlyelec.c文件。
搜索/sys/class/sunxi_info/sys_info会发现如下命令
if (!(f = fopen("/sys/class/sunxi_info/sys_info", "r"))) {
LOGE("open /sys/class/sunxi_info/sys_info failed.");
return -1;
}
这行命令就是导致出错的原因。
现在的做法就是如果读不到/sys/class/sunxi_info/sys_info在让其尝试读取我们新添加的文件/etc/sys_info。
命令如下:
if (!(f = fopen("/sys/class/sunxi_info/sys_info", "r"))) {
if (!(f = fopen("/etc/sys_info", "r"))) {
LOGE("open /sys/class/sunxi_info/sys_info failed.");
return -1;
}
}
3、针对性修改
而不同板子的添加/etc/sys_info文件的信息是不同的。上面的信息会被读取到一个结构体中:
typedef struct {
char kernelHardware[255];
int kernelRevision;
int boardTypeId;
char boardDisplayName[255];
char allwinnerBoardID[255];
} BoardHardwareInfo;
其中boardTypeId和allwinnerBoardID很重要。不同板子是不同的。
可以通过查看wiringPi/boardtype_friendlyelec.c找到。
BoardHardwareInfo gAllBoardHardwareInfo[] = {
{"MINI6410", -1, S3C6410_COMMON, "S3C6410_Board", ""},
{"MINI210", -1, S5PV210_COMMON, "S5PV210_Board", ""},
{"TINY4412", -1, S5P4412_COMMON, "S5P4412_Board", ""},
{"mini2451", 0, S3C2451_COMMON, "S3C2451_Board", ""},
//s5p4418
{"nanopi2", 0, NanoPi2, "NanoPi2", ""},
{"nanopi2", 1, NanoPC_T2, "NanoPC-T2", ""},
{"nanopi2", 2, NanoPi_S2, "NanoPi-S2", ""},
{"nanopi2", 3, Smart4418, "Smart4418", ""},
{"nanopi2", 4, NanoPi2_Fire, "NanoPi2-Fire", ""},
{"nanopi2", 5, NanoPi_M2, "NanoPi-M2", ""},
{"nanopi2", 7, NanoPi_M2A, "NanoPi-M2A", ""},
{"nanopi2", 0x103, Smart4418SDK, "Smart4418SDK", ""},
//s5p6818
{"nanopi3", 1, NanoPC_T3, "NanoPC-T3", ""},
{"nanopi3", 2, NanoPi_M3B, "NanoPi-M3B", ""},
{"nanopi3", 3, Smart6818, "Smart6818", ""},
{"nanopi3", 4, NanoPC_T3T, "NanoPC-T3T", ""},
{"nanopi3", 5, NanoPi_Fire3, "NanoPi-Fire3", ""},
{"nanopi3", 7, NanoPi_M3, "NanoPi-M3", ""},
//allwinner h3
// kernel 3.x
{"sun8i", 0, NanoPi_M1, "NanoPi-M1", "0(0)"},
{"sun8i", 0, NanoPi_NEO, "NanoPi-NEO", "1(0)"},
{"sun8i", 0, NanoPi_NEO_Air, "NanoPi-NEO-Air", "2(0)"},
{"sun8i", 0, NanoPi_M1_Plus, "NanoPi-M1-Plus", "3(0)"},
{"sun8i", 0, NanoPi_Duo, "NanoPi-Duo", "4(0)"},
{"sun8i", 0, NanoPi_NEO_Core, "NanoPi-NEO-Core", "5(0)"},
{"sun8i", 0, NanoPi_K1, "NanoPi-K1", "6(0)"},
{"sun8i", 0, NanoPi_Hero, "NanoPi-Hero", "7(0)"},
{"sun8i", 0, NanoPi_Duo2, "NanoPi-Duo2", "8(0)"},
{"sun8i", 0, NanoPi_R1, "NanoPi-R1", "9(0)"},
// kernel 4.x
{"Allwinnersun8iFamily", 0, NanoPi_M1, "NanoPi-M1", "0(0)"},
{"Allwinnersun8iFamily", 0, NanoPi_NEO, "NanoPi-NEO", "1(0)"},
{"Allwinnersun8iFamily", 0, NanoPi_NEO_Air, "NanoPi-NEO-Air", "2(0)"},
{"Allwinnersun8iFamily", 0, NanoPi_M1_Plus, "NanoPi-M1-Plus", "3(0)"},
{"Allwinnersun8iFamily", 0, NanoPi_Duo, "NanoPi-Duo", "4(0)"},
{"Allwinnersun8iFamily", 0, NanoPi_NEO_Core, "NanoPi-NEO-Core", "5(0)"},
{"Allwinnersun8iFamily", 0, NanoPi_K1, "NanoPi-K1", "6(0)"},
{"Allwinnersun8iFamily", 0, NanoPi_Hero, "NanoPi-Hero", "7(0)"},
{"Allwinnersun8iFamily", 0, NanoPi_Duo2, "NanoPi-Duo2", "8(0)"},
{"Allwinnersun8iFamily", 0, NanoPi_R1, "NanoPi-R1", "9(0)"},
// a64
// {"sun50iw1p1", 0, NanoPi_A64, "NanoPi-A64", "0"},
// armbian+Neo2
{"sun50iw1p1", 4, NanoPi_NEO2, "NanoPi-NEO2", "1(0)"},
//allwinner h5
// kernel 3.x
{"sun50iw2", 4, NanoPi_NEO2, "NanoPi-NEO2", "1(0)"},
{"sun50iw2", 4, NanoPi_M1_Plus2, "NanoPi-M1-Plus2", "3(0)"},
{"sun50iw2", 4, NanoPi_NEO_Plus2, "NanoPi-NEO-Plus2", "2(0)"},
{"sun50iw2", 4, NanoPi_NEO_Core2, "NanoPi-NEO-Core2", "0(0)"},
{"sun50iw2", 4, NanoPi_K1_Plus, "NanoPi-K1-Plus", "4(0)"},
// kernel 4.x
{"Allwinnersun50iw2Family", 4, NanoPi_NEO2, "NanoPi-NEO2", "1(0)"},
{"Allwinnersun50iw2Family", 4, NanoPi_M1_Plus2, "NanoPi-M1-Plus2", "3(0)"},
{"Allwinnersun50iw2Family", 4, NanoPi_NEO_Plus2, "NanoPi-NEO-Plus2", "2(0)"},
{"Allwinnersun50iw2Family", 4, NanoPi_NEO_Core2, "NanoPi-NEO-Core2", "0(0)"},
{"Allwinnersun50iw2Family", 4, NanoPi_K1_Plus, "NanoPi-K1-Plus", "4(0)"},
//k2
{"Amlogic", 0, NanoPi_K2, "NanoPi-K2", ""},
//t4
{"nanopi4", 0, NanoPC_T4, "NanoPC-T4", ""},
{"nanopi4", 1, NanoPi_M4, "NanoPi-M4", ""},
{"nanopi4", 2, NanoPC_T4, "NanoPC-T4", ""},
{"nanopi4", 4, NanoPi_NEO4, "NanoPi-NEO4", ""},
};
这里面定义了不同的板子,比方Neo Core的BoardID是“5(0)”。
在main函数中可看到如下信息:
int main() {
BoardHardwareInfo* retBoardInfo;
int boardId;
boardId = getBoardType(&retBoardInfo);
if (boardId >= 0) {
printf("boardName:%s,boardId:%d\n", retBoardInfo->boardDisplayName, boardId);
} else {
printf("%s, ret:%d\n", "failed", boardId);
}
return 0;
}
所以boardId其实是通过getBoardType来实现的,在getBoardType中对于H3和H5的cpu是通过getAllwinnerBoardID来获取的。而我们刚刚修改的c语言部分就是这个getAllwinnerBoardID的一部分。
所以其实改了boardID就更改了板子的型号。
结论
此方法暂时解决了上面的问题。通过gpio readall可以获取板子的io布局。