rk3399c-ai问题总结

烧录

linux 烧录

注意:系统从7.1升级到10.0需要用mask模式;相同的系统,可以采用loader模式

mask 模式

操作步骤如下:

  1. 设备断开所有电源。
  2. 拔出 SD
  3. 用 Type-C 数据线连接好设备和主卡。机。
  4. 用金属镊子接通 AIO-3399C 上的如下图所示的两个测试点并保持(如下图所示)。
  5. 设备插入电源。
  6. 稍候片刻,之后松开镊子。

ADB 调试

  1. AIO-3399C 用 Type-C 数据线连接设备 Type-C 口和主机
    AIO-3399C(AI) 用双端公头 USB 数据线连接设备蓝色 USB 3.0 口和主机
    如下图:
  2. 根据当前 Android 版本勾选对应路径下的 Connect to PC
1
2
Android7.1、Android8.1 选择 Setting -> USB,然后勾选 Connect to PC
Android10.0 选择 Setting -> Connected devices 然后勾选 Connect to PC

ttysWK1-4 消失

https://dev.t-firefly.com/forum.php?mod=viewthread&tid=100003&extra=&highlight=%B4%AE%BF%DA&page=2

wk2124 驱动文章

https://www.cnblogs.com/chorm590/p/11840606.html
https://blog.51cto.com/u_13640625/5603561?articleABtest=0

wk2124 官网驱动下载

http://www.wkmic.com/News_List.php?tag=Jszc&theId=14

写文件的时候不希望写入一半的时候掉电丢失

Christoph Hellwig 在 2019 Linux Storage, Filesystem, and Memory-Management Summit (LSFMM)会议上,分享了他关于文件系统原子操作的思考。如果 application 在写文件的时候出现了程序崩溃,人们肯定希望文件系统里的数据要么是旧数据,要么是新数据,肯定不希望看到新旧数据混杂在一起。这样就需要对文件有 atomic write 操作的能力。他介绍了在 XFS 里实现的 atomic write,想看看其他文件系统开发者有什么想法。

目前,如果 application 希望对文件做 atomic write,会有两种方法。一种是在 user space 加锁来保护,数据库方案里面通常会这样来做;另一种是重新写一个新文件,然后做“atomic rename”。可惜,应用程序开发者通常都没有正确使用 fsync(),所以最终数据还是会有丢失。

在现代存储系统里面,哪怕存储设备硬件本身,在写操作的时候都不是立刻写入存储单元的。例如闪存设备都有一个 flash translation layer (FTL)抽象层,会把写操作分发到 flash 的各个地方去,避免某些存储单元被写入太多过早损坏(wear leveling),所以它们实际上从来不会在原地址更新数据。对 NVMe 设备来说,每次更新它的一个逻辑块地址(LBA)的数据的时候,都是能确保是 atomic 操作的,不过这个接口地位比较尴尬,估计很少人会用。SCSI 的接口更加好一些,在做 atomic write 的时候能够有错误报告,不过他也没见过哪个厂商真的实现了这个接口。

有的文件系统可以在写操作的时候写在别的地址 ,例如 XFS, Btrfs,等等。这样就能很容易在文件系统层实现 aotmic write。在 5 年前,HP Research 就有一篇有意思的论文,介绍了如何增加一个特殊的 open() flag 来专门指定要 atomic write。这篇论文还只是学术论文,没有真正处理各种 corner case,以及针对现实生活中的限制来实现,不过想法很合理。

在这个系统中,用户写入文件的时候无论写入多少数据都没用,在明确调用 commit 操作之前都不会真正生效。当 commit 操作结束后,所有的改动就真正生效了。这里比较简单的一种实现方式就是在 fsync()里面来恰当地调用 commit 操作,这样就不需要再加一个新的系统调用了。

不久之前,他开始在 XFS 里面用这种方式实现 atomic write。他向社区发布出了一组 patch,不过当时还有不少问题,因此他后来继续修改了这组 patch。目前论文的原作者一直在跟他紧密交流希望能拿到代码,然后就能跟他合作再写一篇论文出来。此外还有一些人也希望使用这个功能。

Chris Mason 问他这里的粒度是多大,是针对每个单独的 write(),还是更多?Hellwig 回答,在 commit 操作之前的所有 write,都会等 commit 的时候一次写入。文件系统会负责对最多能写多少数据来设一个上限。对 XFS 来说,会根据这些 write 所涉及到的不连续区域的数量,来决定这个上限。

不光是传统的 write()系统调用,mmap()映射出来的区域也一样适用。例如,人们现在更改 B-Tree 的多个节点的时候,很难做 atomic update,而这个功能合入后,application 可以简单的在文件 mmap 出来的内存区域做这些更改,然后简单做一次 commit 即可。如果 application 崩溃了,文件系统里存储的数据仍然保证是旧版本或者是新版本,不会混杂起来。

Ted Ts’o 提到他的 Android 领域的朋友也在提需求想要这么一个功能,不过是针对每个文件系统级别的。他们希望每次对 Android 做版本更新的时候,ext4 或者 F2FS 文件系统都可以通过一个 magic option 来加载上来并且关闭所有日志记录真正触发写入操作。等文件更新完毕然后就发一个 ioctl()来开始把所有那些日志都刷到存储设备里。这个方案有点不美观,不过能实现 90%的功能。最后,Ts’o 也认为 ext4 会需要有一个 atomic write 功能,不过每次 commit 之前究竟能更新多少数据,这里可能更加受限制一点。

Hellwig 表示了一些担忧,因为他此前也做过类似的实现方案,都是在内存里面做数据更新,不过最终发现每一批次能缓存的数据非常有限。Ts’o 介绍了 Android 的情况,这里数据块都是会写入存储设备的,而内存中缓存的只是 metadata 相关的更新,一般也就缓存几分钟,这是个非常特殊的应用场景,不具有普适性。不过这个新的实现方法替代了此前的利用 device-mapper 的机制(那个太慢了)。

Chris Mason 提到,只要 interface 设计的好,他很愿意让 Btrfs 支持这个功能。Hellwig 也说对 Btrfs 来说实现这个功能会很直接。对他来说一个比较大的阻碍是怎么支持 O_DIRECT。如果某个 application 先做了 atomic write,然后又把内容读回来,最好是能把刚刚写入的数据读回来。一般的 application 都不会这么做,不过 NFS 确实有这种行为。Linux I/O 的代码里面没有完全支持好这部分功能,所以他还需要做一些修改。

还有一些讨论是关于为什么利用 fsync()的,为什么不用一个专用的系统调用,或者其他什么接口。Hellwig 觉得用 fsync()没有什么不好,毕竟这也是它的本来含义,不应该只做一部分工作,而不做完。Amir Goldstein 问到是否有可能其他进程同时也对这个文件做 fsync()操作,相当于是某种类型的攻击。 Hellwig 说他本来是使用了一个 open()的 flag,不过后来有人提醒没有用过的 flag 可能不会在 open()里面检查,所以利用 flag 来保证数据一致性不是一个很好的主意。 在那种使用模式下,使用 fsync()的接口仅仅会对那些被用这个 flag 打开的 file descriptor 才会做 commit 操作。后来他改成了使用 inode 的 flag,这样更加合理一点,不过目前还没有处理好那些恶意的 fsync()调用的问题。

android 设备写入文件,立即断电重启后,文件丢失,数据没有保存

在 android 开发的过程中碰到写入文件后,立即断电重启,发现写入的文件丢失了

写入时检查了,写入是没有失败的,经过查找资料可能是如下问题引起:

Linux/Unix 系统中,在文件或数据处理过程中一般先放到内存缓冲区中,等到适当的时候再写入磁盘,以提高系统的运行效率。

可能是因为断电时,文件没有写入的物理介质中导致,解决办法如下:

   在write/fwrite写入后,添加fsync(), 这样可以将缓存中的内容强制写入到磁盘中

关于 write/fwrite 和 fsync 的关系如下:
read/write/fsync:

  1. Linux 底层操作;

  2. 内核调用, 涉及到进程上下文的切换,即用户态到核心态的转换,这是个比较消耗性能的操作。

fread/fwrite/fflush:

  1. C 语言标准规定的 io 流操作,建立在 read/write/fsync 之上

  2. 在用户层, 又增加了一层缓冲机制,用于减少内核调用次数,但是增加了一次内存拷贝。

两者之间的关系,见下图:

补充:

  1. 对于输入设备,调用 fsync/fflush 将清空相应的缓冲区,其内数据将被丢弃;
  2. 对于输出设备或磁盘文件,fflush 只能保证数据到达内核缓冲区,并不能保证数据到达物理设备, 因此应该在调用 fflush 后,调用 fsync(fileno(stream)),确保数据存入磁盘。
  3. 在 android java 层中,需要调用 FileDescriptor 的 sync()方法来确保数据存入磁盘。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/* Java 示例代码 */

FileOutputStream fos = null;

byte[] buf = {1,2,3,4};

try {

fos = new FileOutputStream("/sdcard/test.txt");

//将buf中的数据写入fos

fos.write(buf);

//将fos的数据保存到内核缓冲区

//不能确保数据保存到物理存储设备上,如突然断点可能导致文件未保存

fos.flush();

//将数据同步到达物理存储设备

FileDescriptor fd = fos.getFD();

fd.sync();

} catch(Exception e) {

e.printStackTrace();

} finally {

if(fos!=null)

fos.close();

}

修复ubuntu22.4无法上网

如图,正常的 VMware 里 Ubuntu22.4, 在用桥接网络/NAT 时是这样的。有一个网络标志。

如果没有,则按照如下操作修复:

  1. 终端中,输入命令,如下
1
ip addr

输出如下图:

图中,ens33,没有出现 ip,则网络配置有问题

  1. 修改 01-network-manager-all.yaml 文件
    sudo gedit /etc/netplan/01-network-manager-all.yaml
    打开后,如果只有前面 4 行,则补充

    1
    2
    network:
    version: 2

Let NetworkManager manage all devices on this system

1
2
3
4
5
6
7
8
network:
version: 2
renderer: NetworkManager
ethernets:
ens33: #根据自己配置的网卡名称改,使用 ip addr 查看得到
dhcp4: true #dhcp4 开启
addresses: [] #设置本机 IP 及掩码,空
optional: true
  1. 修改 NetworkManager.conf 文件
    sudo gedit /etc/NetworkManager/NetworkManager.conf
1
maneged=false改为true
  1. 重启网络
1
2
3
4
sudo service network-manager stop
sudo rm /var/lib/NetworkManager/NetworkManager.state
sudo service network-manager start

  1. 经过上述步骤还是不能上网,则检查网卡是否开启

    没有开启,则输入如下:
1
2
3
sudo ip link set ens33 up
sudo dhclient ens33

  1. 重启电脑
    reboot

通过repo管理Android源码

以下操作,都是基于 ubuntu 22.4 系统

准备资源

  1. repo
  2. python3

安装

  1. repo
    sudo apt-get install repo

  2. python3.8.5

建立 repo 配置

常见问题

Apple ID提示“这个人不在激活状态”或者“被停用”的解决方案

不论是国内 ID 还是国外 ID,解决未激活或者停用,都有一定的失败几率。不能保证 100%成功,但是之前我教了很多人,成功率也有 80%以上。

Apple ID 出现“个人不在激活状态”或者“停用”是触发到苹果自检系统的机制。

为了避免这个情况,尽可能的保存好自己的密保和完善账户资料。比如:绑定安全邮箱、修改出生年月日、修改密保问答,让自己的账户变得安全,这样可以减少苹果自检系统的排查!(从 iCloud 登录会大大增加苹果自检系统的排查,所以不要从 iCloud 登录。)

当然完善了这些也有可能排查的到,毕竟你是在大陆使用海外 ID,这本来就不符合苹果的条款规定,对于想下载海外 APP,这一点是无法避免的。甚至就在 6 月份的时候,我 2 个用了近 4 年的海外老账号也被封了,大势已去,我也无法阻挡!

如果是大陆 Apple ID 出现这种情况,直接联系苹果客服 400-666-8800,把自己的事情如实跟客服说,客服能解决就解决,解决不了也没办法。

如果是海外 ID,目前有两种解决方法,第一种是直接电话联系美国苹果总部,电话号码是 001 800 275 2273(需要开通国际漫游、而且需要非常熟练说英语),第二种就是下面我即将要讲解的方法!

不论是国内 ID 还是国外 ID,解决未激活或者停用,都有一定的失败几率。不能保证 100%成功,但是之前我教了很多人,成功率也有 80%以上。

准备工具
1、PC 电脑一台,MAC 也行!

2、谷歌浏览器。(谷歌浏览器带有自动翻译功能,所以这里推荐谷歌,整个过程不需要翻墙)

3、出现问题的海外 Apple ID。(必须记得出生年月日和密保问答资料)

开始解决:
第一步:在谷歌浏览器中打开苹果官网:https://www.apple.com进入官网,把浏览页面滑动到最下面,找到「管理你的Apple ID」点进去。(大家可以看到右下角的国家是“美国”,只有这样进入,才能让联系美国客服,不这样进入,联系的基本是国内客服了。)

第二步:在 Apple ID 管理中心,选择“忘记了 Apple ID 或者密码”!

第三步:选择「FAQ」,这个就是中文的“常见问题”!

第四步:到了常见问题的页面,在最下面点击「请访问 Apple 支持」

第五步:到了 Apple 支持的页面后,继续滑动到最下面,然后点击“得到支持”!(有可能我和你的页面显示的不一样,你可能是英文,所以你可以参考我图片点击也一样的效果)

第六步:进入了“得到支持”的页面后,点击「禁用的 Apple ID」。

第七步:选择“主题未列出”!然后再框框中填写你出现的问题。框框之中必须得使用英文填写,美国客服看不懂!(不会英语的就用“在线汉译英”)

然后再框框中填写你出现的问题。框框之中必须得使用英文填写,美国客服看不懂!(不会英语的就用“在线汉译英”)

第八步:点击聊天室!(有时候可能没有聊天室的时候,那么就是美国苹果客服下班了!美国客服在线时间是:9:00-21:00,以美国加利福利亚现在的时间为准!然后等待时间一般显示 5 分钟的基本是美国客服,如果提示的是 2 分钟,那么就是中国客服,如果是中国客服,你再把之前的操作重新再操作一次)

第九步:把自己出现“个人不在激活状态”通过汉译英后表述给美国苹果客服看!他们问你什么,你就如实回答即可!他们会一步一步的帮你解决!

我并不懂英语!但是他们每问我一个问题。我会立刻使用汉译英来进行翻译,并做出相应的回答!然后客服帮我解封了,之后挂断客服了后,我立刻登录了 ID 到苹果管理中心,发现能正常的登录了,不再提示“未激活”,但是在手机上面登录上后,发现无法下载 APP。提示“在 App Store 与 iTunes Store 里禁用”。之后我又再次以上面的方式联系上了美国客服,他们又帮我解决了这个问题!

感觉整个过程有点复杂,其实自己操作一遍之后,就发现非常的简单了!如果觉得没必要去解除,也可以选择重新再买一个海外 Apple ID。