> 文档中心 > 烧写Armbian image的NanoPi NEO Core和WiringNP库 【日积月累计划】

烧写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
解决方案出处