当前位置:   article > 正文

OneCloud记录

s805三色灯gpio

配置信息

S805, 1G RAM, 8G ROM, USB2.0 * 2, 1GB LAN, SD Cardreader
S805参数: 32-bit, ARMv7-A, Cortex-A5, 1.5GHz 4核. 这个不是64位的CPU.

原生玩客云刷机的步骤

因为玩客云原生系统uboot无法输入命令,且启动后TTL终端需要用户登录, 所以需要先将带uboot的固件刷入

刷入安卓电视盒

在这个固件刷入后,才能在uboot菜单输入命令让盒子从SD和USB启动。

  • 拆开盒子,取出PCB板,焊上TTL
  • 电脑上安装USB_Burning_Tool_v2.1.6,注意系统不能是Win10英文版,这个版本读取镜像会有问题, 换成Win7就没问题
  • 运行USB Burning Tool,连接USB双公头到靠近HDMI的USB口,短接触点,PCB板上电,此时在USB Burning Tool中能看到出现的新设备
  • 选择inphic_firmware_v1.img或inphic_firmware_v2.img,点击开始刷机
    • V2是沙发桌面,V1是另一种不常见的桌面,都是源自同一固件制作的
    • 固件都未ROOT,需要自行ROOT
  • 如果是第一次安装USB Burning Tool,第一次连接,刷机可能会失败,因为在3%或4%这步PCB重启时驱动反应较慢会超时,再来一次就好了
  • 刷入成功后,拔掉USB双公头线,拔电重启

用SD/TF卡运行Armbian

  • 解开 Armbian_5.74_Aml-s805_Ubuntu_bionic_default_3.10.108_20190205
  • 用USBWriter.exe将镜像写入U盘或SD/TF卡
  • TTL线连接PCB板,电脑上用XShell打开SERIAL连接
    • 在Win10下,P2302需要安装旧版的驱动,否则不能用
  • 加电,出现输出后立即拍空格,出现UBOOT提示符,输入下面的命令

第一组

  1. # set env
  2. setenv bootfromrecovery 0
  3. setenv bootfromnand 0
  4. setenv start_mmc_autoscript 'if fatload mmc 0 11000000 s805_autoscript; then autoscr 11000000; fi;'
  5. setenv start_usb_autoscript "if fatload usb 0 11000000 s805_autoscript; then autoscr 11000000; fi; if fatload usb 1 11000000 s805_autoscript; then autoscr 11000000; fi;"
  6. setenv start_autoscript 'if usb start; then run start_usb_autoscript; fi; if mmcinfo; then run start_mmc_autoscript; fi;'
  7. setenv bootcmd 'run start_autoscript; run storeboot'
  8. # setenv firstboot 1
  9. saveenv

第二组

  1. # set env
  2. setenv bootfromrecovery 0
  3. setenv bootfromnand 0
  4. setenv bootcmd 'run start_autoscript; run storeboot'
  5. setenv start_autoscript 'if mmcinfo; then run start_mmc_autoscript; fi; if usb start; then run start_usb_autoscript; fi; run start_emmc_autoscript;'
  6. setenv start_emmc_autoscript 'if fatload mmc 1 11000000 emmc_autoscript; then autoscr 11000000; fi;'
  7. setenv start_mmc_autoscript 'if fatload mmc 0 11000000 s805_autoscript; then autoscr 11000000; fi;'
  8. setenv start_usb_autoscript 'for usbdev in 0 1 2 3; do if fatload usb ${usbdev} 11000000 s805_autoscript; then autoscr 11000000; fi; done'
  9. saveenv

上面任一组都可以,然后用这个命令检查

  1. # show env
  2. printenv

然后拔电,插上已经写入Armbian镜像的SD卡,或者U盘,U盘必须用靠近网口那个USB口, 然后加电, 就会启动进入Armbian

注意:

  • 如果是用SD卡套的TF卡,注意这个读卡器比较挑,有些卡套不识别。
  • 启动后先出安卓的LOGO,然后黑屏,然后才会有命令行输出, 有些Armbian镜像只有TTL输出,没有HDMI输出
  • 国内制作的部分Armbian镜像, 必须用Windows下的USBWriter写入, 如果用Linux下的Disk Writer, 会导致uboot无法识别U盘的分区而导致读取USB中的启动脚本失败.

更新UBOOT

准备一张格式化为Fat32的分区小于512M的SD卡, 新的u-boot.bin放这个卡上, 在启动时进入uboot界面, 插入SD卡, 输入以下命令

  1. # 启动mmc
  2. mmcinfo
  3. # 将u-boot.bin这个文件从mmc 0读出, 放到内存开始地址为12000000的地方
  4. # 注:u-boot.bin 为 u-boot 的名字,如果名字不一样,需要作相应的更改。
  5. fatload mmc 0 12000000 u-boot.bin
  6. # 将12000000的内容 写入到rom的 0 60000 地址区间
  7. store rom_write 12000000 0 60000
  8. # 断电重启

修改autoscript

有时候镜像中的s805_autoscript设置得不对导致启动失败,需要修改. 直接修改s805_autoscript, 会导致启动时校验失败, 需要用mkimage工具重新生成, 命令历史如下

  1. $ mkimage -l s805_autoscript
  2. GP Header: Size 27051956 LoadAddr 7c441e58
  3. $ mv s805_autoscript s805_autoscript.bak
  4. $ mkimage -A arm -O linux -T script -C none -d s805_autoscript.cmd s805_autoscript
  5. Image Name:
  6. Created: Sun Dec 27 21:28:00 2020
  7. Image Type: ARM Linux Script (uncompressed)
  8. Data Size: 1284 Bytes = 1.25 KiB = 0.00 MiB
  9. Load Address: 00000000
  10. Entry Point: 00000000
  11. Contents:
  12. Image 0: 1276 Bytes = 1.25 KiB = 0.00 MiB
  13. $ mkimage -l s805_autoscript
  14. Image Name:
  15. Created: Sun Dec 27 21:28:00 2020
  16. Image Type: ARM Linux Script (uncompressed)
  17. Data Size: 1284 Bytes = 1.25 KiB = 0.00 MiB
  18. Load Address: 00000000
  19. Entry Point: 00000000
  20. Contents:
  21. Image 0: 1276 Bytes = 1.25 KiB = 0.00 MiB

对于一些只能从USB启动的img, 可以通过修改s805_autoscript的方式让其通过SD卡槽也能启动, 对于玩客云, 修改s805_autoscript.cmd中的这一行, 将 mmc 1 都改为 mmc 0, 因为玩客云只有mmc 0

if fatload mmc 1 ${kernel_addr} uImage; then if fatload mmc 1 ${initrd_addr} uInitrd; then if fatload mmc 1 ${env_addr} uEnv.txt; then env import -t ${env_addr} ${filesize};fi; if fatload mmc 1 ${dtb_addr} ${dtb_name}; then unifykey get mac;setenv bootargs ${bootargs} mac=${mac};run boot_start; else imgread dtb boot ${dtb_addr}; run boot_start;fi;fi;fi;

然后再用前面的命令,将s805_autoscript.cmd转化为s805_autoscript, 代替原文件,就可以从SD卡槽启动了.

其他的Armbian版本

目前能下载的Armbian镜像, 普遍存在两个问题: 网卡不能正常工作, HDMI没有输出. 这两者正常的只有3.10.108这个内核的版本.
内核是5.x的现在还没见到HDMI正常工作的, 因为可以从TTL进行配置, 所以如果仅作为服务器使用, 这样也可以接受.

修复网卡:
对于balbes150提供的内核为5.7.0以后的版本,都可以用替换dtb的方式修复网卡.
用这里提供的meson8b-odroidc1.dtb文件,替换掉镜像里的同名文件,并修改 uEnv.txt 文件设置为这个dtb, 就可以启动为千兆网卡

遇到的问题:

  1. Debian Buster版本中,用iptables命令出现"iptables-legacy tables present, use iptables-legacy to see them"提示
    这是因为Buster已经更换了新的iptables实现,具体看这个链接 https://wiki.debian.org/iptables
    NOTE: Debian Buster uses the nftables framework by default.
    Starting with Debian Buster, nf_tables is the default backend when using iptables, by means of the iptables-nft layer (i.e, using iptables syntax with the nf_tables kernel subsystem). This also affects ip6tables, arptables and ebtables.
    You can switch back and forth between iptables-nft and iptables-legacy by means of update-alternatives (same applies to arptables and ebtables).
    The default starting with Debian Buster:
  1. # update-alternatives --set iptables /usr/sbin/iptables-nft
  2. # update-alternatives --set ip6tables /usr/sbin/ip6tables-nft
  3. # update-alternatives --set arptables /usr/sbin/arptables-nft
  4. # update-alternatives --set ebtables /usr/sbin/ebtables-nft

Switching to the legacy version:

  1. # update-alternatives --set iptables /usr/sbin/iptables-legacy
  2. # update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
  3. # update-alternatives --set arptables /usr/sbin/arptables-legacy
  4. # update-alternatives --set ebtables /usr/sbin/ebtables-legacy

参考以下的链接
Armbian S805相关讨论https://forum.armbian.com/topic/1919-armbian-for-amlogic-s805/
上面这个主题的后续讨论,因为“Now images for S805 and S802\S812 are shared with core 5”https://forum.armbian.com/topic/3023-armbian-for-amlogic-s805-and-s802s812/
在另一个论坛的讨论https://forum.freaktab.com/forum/tv-player-support/amlogic-based-tv-players/606133-linux-images-for-s802-s805-s812-s905-s905x-s912-sd-usb-emmc

  1. s805\s802\s812
  2. Thanks to the work done by Martin and the developers of Libreelec (Chewitt etc). An early alpha version of Libreelec with a 5.6 core is now available.This version is intended for General evaluation of the system's ability to run on s805\s802\s812. This version uses a new DTB configuration mechanism that is common with the latest Armbian versions for all RK+AW+AML platforms. You need to edit the file to configure it (uEnv.txt). If multi-loading is already enabled on your device, the system should start automatically after setting up DTB.

https://yadi.sk/d/2TMsShn0sgvsOA

Armbian S8xx下载 from balbes150, 这些是5.x内核使用新的dtb后整合S805,S812的镜像https://yadi.sk/d/-MwoNitZonsRCg

Armbian S805下载https://yadi.sk/d/QCGU0PIv3G5kEa
Armbian S805下载https://yadi.sk/d/DnCkh3KBvAFES
玩客云的下载 -- 这些国内自行编译的镜像, 必须在windows下用USBWriter写入才行, 如果在Linux下用disk writer,在uboot中会无法识别U盘的分区导致引导失败https://yadi.sk/d/3HM6lyepys95Tg

参考链接

https://zhuanlan.zhihu.com/p/144850658https://1syan.com/read/39.htmlhttps://www.xiaowenweb.com/fl/770/3/https://post.smzdm.com/p/akmg53qr/https://www.mydigit.cn/forum.php?mod=viewthread&tid=174374

https://www.right.com.cn/forum/thread-4023909-1-1.htmlhttps://www.right.com.cn/forum/thread-2803127-1-1.htmlhttps://www.right.com.cn/forum/thread-4031647-1-1.html
英菲克固件带roothttps://www.right.com.cn/forum/thread-4034368-1-1.html

https://www.right.com.cn/forum/thread-4034559-1-3.htmlhttps://www.right.com.cn/forum/thread-837057-1-1.html

相关下载https://pan.baidu.com/s/1RNBZGNbM1ZubrRuSegZ4kQ 提取码:oktshttps://cloud.189.cn/t/Z3a6jmYviYzu 访问码:aib8https://pan.baidu.com/s/12c2tQ3w6ncgnfI9BclSBdA 提取码:7ab0https://pan.baidu.com/s/1G5GWvkG-9oR1Nx1auVJqgQ 提取码:g7mt

通过程序控制三色灯的亮灭

前面的灯虽然只有一个,但是有三种颜色红绿蓝,通过两两组合还可以产生紫黄青白一共七种颜色. 对灯的控制是通过GPIO实现的.
如何查看GPIO信息可以参考 https://docs.khadas.com/zh-cn/vim3/HowToAccessGpio.html

对应这个设备的C代码

  1. #include <ctype.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stdint.h>
  5. #include <fcntl.h>
  6. #include <sys/types.h>
  7. #include <sys/mman.h>
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include <sys/select.h>
  11. #include <pthread.h>
  12. #include <unistd.h>
  13. #include <sched.h>
  14. #include <string.h>
  15. #define PLPM_BASE 0xc8100014
  16. #define __IO volatile
  17. void *var_addr_satr=0;
  18. unsigned int var_addr_size=0;
  19. unsigned int *gpioaddr;
  20. void *gpio_base= 0;
  21. int gpio_init(void) {
  22. int fd;
  23. unsigned int addr_start,addr_offset;
  24. unsigned int PageSize,PageMask;
  25. fd = open("/dev/mem",O_RDWR);
  26. if(fd < 0) {
  27. return -1;
  28. }
  29. PageSize = sysconf(_SC_PAGESIZE);
  30. PageMask = ~(PageSize-1);
  31. //printf("take PageSize=%d\n",PageSize);
  32. addr_start = PLPM_BASE & PageMask ;
  33. addr_offset= PLPM_BASE & ~PageMask;
  34. var_addr_size = PageSize*2;
  35. var_addr_satr = (void*) mmap(0, var_addr_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr_start);
  36. if(var_addr_satr == MAP_FAILED) {
  37. return -1;
  38. }
  39. gpio_base = var_addr_satr;
  40. gpio_base += addr_offset;
  41. //printf("take var addr = 0x%8x\n",(unsigned int)var_addr_satr);
  42. //printf("make gpio_base = 0x%8x\n",(unsigned int)gpio_base);
  43. close(fd);
  44. return 0;
  45. }
  46. int gpio_deinit(void) {
  47. int fd;
  48. fd = open("/dev/mem",O_RDWR);
  49. if(fd < 0) {
  50. return -1;
  51. }
  52. if(munmap(var_addr_satr,var_addr_size) == 0) {
  53. //printf("remove var addr ok\n");
  54. } else {
  55. //printf("remove var addr erro\n");
  56. }
  57. close(fd);
  58. return 0;
  59. }
  60. void red_on(void) {
  61. unsigned int temp;
  62. temp = *(gpioaddr+4)|0x00040000;
  63. *(gpioaddr+4)=temp;
  64. }
  65. void red_off(void) {
  66. *(gpioaddr+4) = *(gpioaddr+4)&(~0x00040000);
  67. }
  68. void red_toggle(void) {
  69. unsigned char c;
  70. c = (*(gpioaddr+4)&0x00040000)>>18;
  71. if (c == 0) {
  72. red_on();
  73. } else {
  74. red_off();
  75. }
  76. }
  77. void green_on(void) {
  78. *(gpioaddr+4) = *(gpioaddr+4)|0x00080000;
  79. }
  80. void green_off(void) {
  81. *(gpioaddr+4) = *(gpioaddr+4)&(~0x00080000);
  82. }
  83. void green_toggle(void) {
  84. unsigned char c;
  85. c = (*(gpioaddr+4)&0x00080000)>>19;
  86. if (c == 0) {
  87. green_on();
  88. } else {
  89. green_off();
  90. }
  91. }
  92. void blue_on(void) {
  93. *(gpioaddr+4) = *(gpioaddr+4)|0x00100000;
  94. }
  95. void blue_off(void) {
  96. *(gpioaddr+4) = *(gpioaddr+4)&(~0x00100000);
  97. }
  98. void blue_toggle(void) {
  99. unsigned char c;
  100. c = (*(gpioaddr+4)&0x00100000)>>20;
  101. if (c == 0) {
  102. blue_on();
  103. } else {
  104. blue_off();
  105. }
  106. }
  107. unsigned char key_scan(void) {
  108. unsigned char key=0;
  109. key=((*(gpioaddr+5)&0x00000020)>>5);
  110. return key;
  111. }
  112. int main(int argc,char * argv[]) {
  113. if (argc < 2 || argc > 4) {
  114. printf("led [red|green|blue] [0|1]\n");
  115. return 1;
  116. }
  117. unsigned int temp;
  118. if (gpio_init() != 0) {
  119. printf("gpio_init failed\n");
  120. return -1;
  121. }
  122. gpioaddr = (unsigned int *)gpio_base;
  123. // Turn off GPIOAO_4,GPIOAO_5 reuse
  124. temp = *gpioaddr&(~0x01800066);
  125. *gpioaddr = temp;
  126. // Enable GPIOAO_2,GPIOAO_3,GPIOAO_4 output,GPIOAO_5 input
  127. temp = *(gpioaddr+4)&(~0x0000001c);
  128. *(gpioaddr+4) = temp;
  129. temp = *(gpioaddr+4)|0x00000020;
  130. *(gpioaddr+4) = temp;
  131. if (argc == 2) {
  132. if (strcmp((const char*)argv[1],"red")==0)
  133. red_toggle();
  134. if (strcmp((const char*)argv[1],"green")==0)
  135. green_toggle();
  136. if (strcmp((const char*)argv[1],"blue")==0)
  137. blue_toggle();
  138. }
  139. if (argc == 3) {
  140. if (strcmp((const char*)argv[1],"red")==0) {
  141. if (strcmp((const char*)argv[2],"0")==0) {
  142. red_off();
  143. } else {
  144. red_on();
  145. }
  146. }
  147. if (strcmp((const char*)argv[1],"green")==0) {
  148. if (strcmp((const char*)argv[2],"0")==0) {
  149. green_off();
  150. } else {
  151. green_on();
  152. }
  153. }
  154. if (strcmp((const char*)argv[1],"blue")==0) {
  155. if (strcmp((const char*)argv[2],"0")==0) {
  156. blue_off();
  157. } else {
  158. blue_on();
  159. }
  160. }
  161. }
  162. gpio_deinit( );
  163. return 0;
  164. }

编译和使用

  1. # 编译
  2. gcc led.c -o led
  3. # 触发红色亮灭
  4. ./led red
  5. # 关闭红色
  6. ./led red 0
  7. # 打开红色
  8. ./led red 1

如果将其放入 /usr/bin, 再将命令添加到 /etc/rc.loacl, 放到 exit 0 之前, 就能实现启动结束后变色的效果

  1. # By default this script does nothing.
  2. # Switch led to green to indicate the systemd has been started
  3. /usr/bin/onecloud_led red 0
  4. /usr/bin/onecloud_led blue 0
  5. /usr/bin/onecloud_led green 1
  6. exit 0
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/332579
推荐阅读
相关标签
  

闽ICP备14008679号