烧写Armbian image的NanoPi NEO Core和WiringNP库 【日积月累计划】
背景介绍
基本不用官方镜像,通常给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 : Sun8iw7p1sunxi_secure : normalsunxi_chipid : 2c21020e786746240000540000000000sunxi_chiptype : 00000042sunxi_batchno : 1sunxi_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布局。
参考
boardtype_friendlyelec.c
boardtype_friendlyelec.h
解决方案出处