【record】

文章目录

      • 【定制安装ubuntu的rootfs】:
      • 【设置虚拟机网络来ping通板子】
      • 【如何进入loader模式】
      • 【建立软链接并更新】
      • 【备份rootfs】
      • 【时间同步相关指令】
      • 【RK3399时间同步改动操作步骤---2022/9/5更新】
      • 【串口通信】
      • 【RK3288 串口驱动数据导出总结】
      • 【限定syslog容量大小的办法】
      • 【git使用】
      • 【gitlab使用】
      • 【借用其他文件夹的makefile编译内核文件】
      • 【RK3399 通过系统实现USB端口自动检测并建立软链接】
      • 【RK3288 UI板LED灯闪烁控制】
      • 【RK3288串口数据解析transportcrc】
      • 【RK3288安卓系统内置app】
      • 【ttyACM乱跳问题解决】
      • 【如何在内核中增加自己的驱动文件夹hello,并进行编译】
      • 【RK3399 USB在内核阶段上电】
      • 【vim操作】
      • 【压缩解压指令】
      • 【查询立体视觉等usb设备对应的usb的gpio】
      • 【串口数据量显示调试工具demo】
      • 【git提交gerrit】
      • 【git操作解析】
      • 【网络通信】
      • 【RK3399版本管理】
      • 【ubuntu台式机使用scp从服务器上下载文件到本地】
      • 【RK3399研究syslog和kmsg的区别】
      • 【iptables配置ubuntu主机网络共享】
      • 【安卓网络诊断工具】
      • 【ubuntu创建自定义指令工具】
      • 【c语言实现全局变量】
      • 【usb_scan支持-v-t-f-s,且作为后台服务】
      • 【RK3308 dmesg不停打印init: /dev/tty1 termined status 1 】
      • 【RK3288 android6.0 支持同时显示多个摄像头源码解析】
      • 【安卓6.0 rtl8821cu 蓝牙适配】
      • 【安卓目录结构简记】
      • 【Android 6 状态栏隐藏】
      • 【python ssh 免密连接,dd更新内核】
      • 【诊断工具(底盘+蓝海雷达+lora+调度模块+科力雷达+立体视觉+乐动雷达)】
        • 【串口 自收自发 测试demo】
        • 【多线程 测试demo】
        • 【蓝海雷达 测试demo】
        • 【计时器 测试demo】
        • 【文件修改时间 测试demo】
        • 【udp client请求server发送 测试demo】
        • 【乐动雷达 测试demo】
      • 【镜像解包afptool】
      • 【android12 永久隐藏状态栏】
      • 【Android6 system.img定制化修改开机动画】
      • 【iperf 测试工控机和ui板网络传输】
      • 【tcpdump 抓包测试】
      • 【RK3288 android6 lvds+edp双屏异显解析】
      • 【RK3288 android10 lvds+edp 双屏异显】
      • 【RK3399 android10 新增分区(nanopc)】
      • 【RK3399 android10 支持spi功能 (nanopc t4)】
      • 【RK3399 Android10 立体视觉ip配置(手动)(nanopc t4)】
      • 【RK3399 Android10 dropbear移植,ssh功能支持】
      • 【RK3399 Android10 usb_scan重新适配,同时支持立体视觉自动适配】
      • 【RK3399 Android10 wifi sta和ap模式 mac地址保持一致】
      • 【(学习)Android10 屏幕显示】
      • 【android10 时间同步禁用,修改默认时区】
      • 【网络工具ip 学习】
      • 【RK3399 android10 nanopc wifi和eth网络连接优先级问题】
      • 【RK3399 android10 nanopc typec接口驱动模式,adb模式和usb模式】
      • 【RK3399 android10 nanopc 删除某些apk应用】
      • 【RK3288 android6 4个摄像头固定映射】
      • 【RK3288 android6 快捷按键gpio 时间上报】
      • 【RK3399 android10 nanopc 自定义第三方apk安装,权限弹窗解决】
      • 【ESP32 通知铃 boost_en引脚发送脉冲】
      • 【RK3288 Android10 内核移植】
      • 【RK3399 android10 nanopc 时间24小时制显示】
      • 【RK3399 android10 nanopc 设置gboard为默认输入法】
      • 【ESP32 通知铃 指令进入休眠模式】
      • 【RK3288 android6 neoway 4G模块适配】
      • 【485 IO板 支持modbus】
      • 【RK3288 hdmi副屏旋转】
      • 【x86 工控机 配置桥接口+默认dns+ssh登录】
      • 【可编程电源脚本使用】
      • 【RK3288 android6 UNIK 新板卡支持】
      • 【RK3288 Android6 S100 设置默认旋屏后概率性恢复】
      • 【RK3399 Android10 二合一 W3s 支持GM8775C mipi转lvds 10.1寸屏幕适配】
      • 【RK3399 Android10 二合一 W3S 支持ilitek触摸驱动】
      • 【RK3399 Android10 二合一 支持ov4689 mipi摄像头】
      • 【ESP32 调度模块问题排查】
      • 【RK3288 Android10 UNIK 声音忽大忽小问题排查】
      • 【RK3399 ubuntu 工控机外设管理usb_scan v1】
      • 【RK3288 Android6 T2pro 支持移远和有方4G模块切换】
      • 【RK3288 Android10 C30 支持sim卡拔掉不弹窗,及热插拔】
      • 【RK3399 Android10 二合一,外设管理服务】
      • 【RK3288 Android6 网络转发,工控机反向访问PC机】


【定制安装ubuntu的rootfs】:

链接

【设置虚拟机网络来ping通板子】

设置好板子的ip192.168.64.20后
现在主机windows上配置静态ip进行尝试
主机windows与板子的ip互为网关
测试可以ping的通

虚拟机使用同样的ip互换网关之后,还是ping不通的原因是由于虚拟机软件VMware station的设置,要把网络设置成使用桥接模式,并复制物理网络,之后重启即可

备份好后,使用同样的方法烧录回板子。
重新向3308的板子烧录对应的3308的固件,在替换rootfs分区的时候,注意使用Dev partition功能读取看一下板子里的系统固件的实际分区来更新一下cfg的分区。

板子内无ping工具,使用busybox ping 192.168.64.20可以尝试自己ping自己。

【如何进入loader模式】

关于按法:先两个一起按下去,然后再松开reset键
手动进入loader模式的方式很简单,先上电,同时按住板子的reset按键(靠近电源接口)和recovery按键,然后松开reset按键并等待几秒,等到烧录工具显示“发现一个LOADER设备”后松开即可

【建立软链接并更新】

验证完自己的rootfs正确无误之后,需要建立软链接

ln -sf (实体) (快捷方式)

之后还要更新build的【软链接】。

./build.sh -h
./build.sh ubuntu
cd rockdev/
ls -l
ln -sf ../ubuntu_rootfs/rk3399-rootfs-20220630.img rootfs.img
ls -l
cd ..
./build.sh -h

在服务器里面的SDK里面,把rootfs的img打包到整个系统镜像

./build.sh [uboot/kernet/rootfs]  (单独编译)
./build.sh updateimg   (打包成整个系统固件)

【备份rootfs】

板子上挂在自己的rootfs源文件,先查看自己的rootfs处在那个mmc分区
(查看分区)

df -h

(查看每个mmc分区是什么内容)

/sys/block/mmcblk${id}/mmcblk${id}p*/uevent

(板子挂载自己的rootfs)

mount /dev/mmcblk1p4 /mnt

(确保板子自己的ip是192.168.64.20,网关是192.168.64.10)
修改/etc/network/interfaces,添加,然后reboot即可,也可手动配置。

(尝试windows是否可以ping192.168.64.20)
网线连接板子和电脑,断掉网络,修改网络适配器的ipv4参数,ip:192.168.64.10,网关:192.168.64.20,然后去ping192.168.64.20。

(虚拟机设置网络设置成使用桥接模式,并勾选复制物理网络)

(进入虚拟机后,只有一个有线链接,设置linux的网络ipv4设置和windows相通,ping)

(备份rootfs)

mkdir temp
sudo rsync -av [email protected]:/mnt/ temp

(如果报主机身份被改变,是因为连接过不同的设备,直接复制报错里面的指令修改即可)
(如果需要root的密码,就去板子上用passwd root来设置密码)

​(temp内为rootfs)

mkdir rootfs
dd if=/dev/zero of=linuxroot.img bs=1M count=1200
mkfs.ext4 linuxroot.img
sudo mount linuxroot.img rootfs/
sudo cp -rfp temp/* rootfs/
sudo umount rootfs/
e2fsck -p -f linuxroot.img
resize2fs  -M linuxroot.img

今天只是单纯的把wugt给的rk3399-rootfs-20220630烧录到板子里面,然后测试发现所有的工具都已经安装了

如果想要修改img,直接mount就可以看到了


在dd创建新的img镜像文件是,需要进入temp文件夹下,执行du -sh查看当前目录大小
扩容可以利用/usr/local/bin/firstboot来扩容

【时间同步相关指令】

时间同步相关指令文件

date
dmesg |grep rtc
cd /etc/c
cat /etc/crontab

时间同步的意思是编写脚本把系统时间变成和硬件时间相同,开机自动校准ntp服务器上的网络时间

设置系统和硬件时间为一个过去的时间用来测试是否会自动校准。

hwclock --set --date "20000427 20:23:00"

显示硬件时钟

hwclock --show

以硬件时间为基准,修改系统时间

hwclock --hctosys
hwclock -s

以系统时间为基准,修改硬件时间

hwclock -w

【RK3399时间同步改动操作步骤—2022/9/5更新】

开机自动执行脚本,选择后台服务,脚本自行新建

vim /etc/rc.local

增加一行

/usr/local/bin/time-Synchronization.sh &&表示后台执行)

time-Synchronization.sh脚本内容

#!/bin/bash
#This is a simple script.

ntpdate cn.pool.ntp.org >/dev/null 2>&1 &
ntpdate cn.pool.ntp.org >/dev/null 2>&1 &
ntpdate cn.pool.ntp.org >/dev/null 2>&1 &
hwclock -w

(ntpdate … >/dev/null 2>&1 & (取消输出))



2022/9/5 更新,配合ui板启动,每隔3秒自动访问ntpserver同步时间

修改 time-Synchronization.sh

#!/bin/bash
#This is a simple script.

#ntpdate cn.pool.ntp.org >/dev/null 2>&1 &
#ntpdate cn.pool.ntp.org >/dev/null 2>&1 &
#ntpdate cn.pool.ntp.org >/dev/null 2>&1 &

#echo "testing"
count=0

ntpdate cn.pool.ntp.org >/dev/null 2>&1 

while [ $? -ne 0 ];
do
  sleep 3
  count=$((count+1))
  if [ $count -gt 20 ];
  then
    echo "ntpserver update time is too long!"
    break
  fi


  ntpdate cn.pool.ntp.org >/dev/null 2>&1 
done


hwclock -w

【串口通信】

windows与板子上的ubuntu系统进行串口通信
板子上的ubuntu需要 minicom来充当他的串口调试工具,同时使用网线ssh连接ubuntu终端,串口线连接到板子的串口(非左下角的调试串口)

在ssh终端中
cat /proc/tty/driver/serial (查看每个串口的收发数据的状态,注意到有两个tx,rx都是0)

windows中的串口调试工具选择定时发送,观察到有一个rx在不断增加,他的MMIO 是 oxff1c0000
然后

cd /proc/tty/driver/
dmesg | grep ttyS*

可以查看到同样的MMIO的是ttyS4. (3号和4号串口都是ttyS4)

配置minicom:

sudo minicom -s

选择Serial port setup

指令使用minicom
sudo minicom -D /dev/ttyS4 -b 115200 -w & (之后就可以接收到windows发送过来的数据)

sudo minicom -D /dev/ttyS3 -b 115200 -w
printk(KERN_EMERG   "GetIot: KERN_DEBUG\n");
dmesg

cd ~/../../media/hdd2/liangji/rk3288-linux-v4.4-sdk/kernel/drivers/tty/serial/
~/../../media/hdd1/liangji/
/var/log/serial_kern.log


dmesg |grep in32

dmesg |grep GetIot


dev_err(dev, "DMA mapping error for RX.\n");

https://blog.csdn.net/weixin_40407893/article/details/117956968
https://www.cnblogs.com/liushuhe1990/articles/11287338.html

------------------------------------------------------------------------------------------2022/7/12

grep -rn 'rotate' *

 578	        uart4: serial@ff1c0000 {
 579                 compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart";
 580                 reg = <0x0 0xff1c0000 0x0 0x100>;
 581                 interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
 582                 reg-shift = <2>;
 583                 reg-io-width = <4>;
 584                 clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
 585                 clock-names = "baudclk", "apb_pclk";
 586                 pinctrl-names = "default";
 587                 pinctrl-0 = <&uart4_xfer>;
 588                 status = "disabled";


printk(KERN_EMERG   "GetIot2: KERN_DEBUG\n");

dev_err(p->dev, "Couldn't set LCR to %d\n", value);

printk(KERN_SOH    "GetIot2: KERN_DEBUG\n");

------------------------------------------------------------------------------------------2022/7/14
修改n_tty.c里面的n_tty_read()里面的copy_from_read_buf()

可以在终端打印出数据。

修改/etc/rsyslog.d/50-default.conf,
将里面的kern输出重定向,kern.emerg /var/log/serial_kern.log

重启rsyslog服务

service rsyslog restart

【RK3288 串口驱动数据导出总结】

修改n_tty.c中,从read_buf中导出数据到自己的缓冲区中,经过字符串转16进制,转换成16进制序列输出

输出使用printk,优先级KERN_EMERG

修改/etc/rsyslog.d/50-default.conf
将printk的内核log输出重定向到自己的serial_kern.log文件

查看log文件

cat /var/log/serial_kern.log

关闭时间戳

echo N > /sys/module/printk/parameters/time

禁止终端打印输出信息

echo 0 >/proc/sys/kernel/printk
sudo minicom -D /dev/ttyS4 -b 115200 -w &
sudo minicom -D /dev/ttyS3 -b 115200 -w -H &

echo " " > /var/log/serial_kern.log
echo " " > /var/log/syslog

/etc/logrotate.d/rsyslog

dmesg |grep GetIot

修改配置文件

vim /etc/logrotate.d/rsyslog

/usr/sbin/logrotate -d -f /etc/logrotate.d/rsyslog
chmod g-w /var/log
/usr/sbin/logrotate -v -f /etc/logrotate.d/rsyslog

显示syslog大小

ls -hl /var/log/syslog*
du -sh /var/log/syslog

清空syslog

echo " " > /var/log/syslog	

logrotate -v -f rsyslog

修改权限

chmod g-w /etc/logrotate.d

强制执行

logrotate -f /etc/logrotate.conf

【限定syslog容量大小的办法】

https://askubuntu.com/questions/184949/how-do-i-limit-the-size-of-my-syslog/1083570#1083570]

https://github.com/rsyslog/rsyslog/issues/4924

修改配置文件

vim /etc/rsyslog.d/50-default.conf

增加一行

$outchannel mysyslog,/var/log/syslog,1048576,/etc/rsyslog.d/my_action.sh

my_action.sh文件内容:

#! /bin/bash

echo " " > /var/log/syslog	

脚本权限

chmod 777 -R /etc/rsyslog.d/my_action.sh

*.*一行注释并添加

*.*;auth,authpriv.none  :omfile:$mysyslog

重启rsyslog服务

sudo service rsyslog restart

轮询脚本:

#! /bin/bash

cp /var/log/syslog /var/log/syslog.1



rm syslog.7.gz
mv syslog.6.gz syslog.7.gz
mv syslog.5.gz syslog.6.gz
mv syslog.4.gz syslog.5.gz
mv syslog.3.gz syslog.4.gz
mv syslog.2.gz syslog.3.gz
mv syslog.1.gz syslog.2.gz

gzip /var/log/syslog.1

echo " " > /var/log/syslog

修改解压后命名一样的问题

#! /bin/bash

NUM=8

#syslog.*.gz is exist or not

for ((i=1; i<=$NUM; i++))
do
  FILE=/var/log/syslog.$i.gz
  if [ -f "$FILE" ]; then
    cp /var/log/syslog /var/log/syslog.exist
  else
    cp /var/log/syslog /var/log/syslog.$i
    echo " " > /var/log/syslog.$i
    gzip /var/log/syslog.$i
  fi
done

for ((j=1; j<=$NUM; j++))
do
  gzip -d /var/log/syslog.$j.gz
done

cp /var/log/syslog /var/log/syslog.1.temp

rm /var/log/syslog.$NUM

for ((k=$NUM; k>=2; k--))
do
  PRO=$(($k-1))
  mv /var/log/syslog.$PRO /var/log/syslog.$k
done

mv /var/log/syslog.1.temp /var/log/syslog.1

for ((m=1; m<=$NUM; m++))
do
  gzip /var/log/syslog.$m
done

echo " " > /var/log/syslog

【git使用】

git status

用git把代码提交到本地

git add n_tty.c
git commit -sv			(sv,使用vim添加标签)

可以使用vim

git config --global core.editor vim

在文件头部添加前缀描述词

feat: support log serial log

查看提交到本地的代码记录

tig

git format-patch -1 HEAD

git commit --amend

查看当前分支

git branch

查看当前状态

git status

建立新的develop分支

git checkout -b develop origin/develop

一个commit中如果amend了一个不想要的改动,可以用git reflog查找commit的版本,然后

git reset ad22jas

【gitlab使用】

整个project(废了重新拉,包含多个仓库的整个项目)

repo init -u ssh://[email protected]/common/manifest.git -b android6.0 -m android6.0.xml --repo-url=ssh://[email protected]/common/git-repo.git  --no-repo-verify
repo sync -f -j16

从远程拉下来(单个仓库)(repo 是对git 的封装)

git pull origin develop
或者
repo sync kernel

可以用tig查看是否拉下来

修改代码之后
由于这个版本的代码在远程已经merge了
所以这次的改动要新commit一次

提交到远程

git push origin HEAD:fix-custom     (HEAD表示)

到这里只是提交到gitlab上作为草稿,还无法审核
提交新的merge 请求,这样才能够提交审核

【借用其他文件夹的makefile编译内核文件】

编译多个文件

gcc -o test process_api.c c_vector.c transportcrc.c

把多个文件放在有其他文件的文件夹下,借用他们的配置文件进行编译

修改/arch/arm/configs/rockchip_linux_defconfig

添加+CONFIG_TRANSPORTCRC=y

修改/drivers/tty/Makefile
添加 obj-y += transportcrc.o

【RK3399 通过系统实现USB端口自动检测并建立软链接】

由于usb3.0可能会有gpio口供电问题,所以用2.0的usb口单独测试 lora

查看导出到文件中的log信息

cat /var/log/usb-test.log

查看tty设备的软链接

ls -l /dev/tty*

修改自动执行脚本

vim /etc/rc.local
/usr/local/bin/usb_scan.sh

手动执行
usb_scan/usb_scan

echo “”>/var/log/usb-test.log

ssh://[email protected]:29418/linux/tools/usb-device-detect

上传代码

git push ssh://[email protected]:29418/linux/tools/usb-device-detect HEAD:refs/for/develop

【RK3288 UI板LED灯闪烁控制】

板子上一共3个LED灯,但是红灯不能控制,能够控制的是左边的蓝色和绿色的灯。

修改板子的设备树文件

vim kernel/arch/arm/boot/dts/rk3288-evb-act8846.dts

找到leds的设备树,里面有2个led设备的子节点

修改led默认状态为打开

default-status = "on"

修改trigger的模式为heartbeat (选择heartbeat的触发方式,触发方式的具体定义在kernel/drivers/leds/trigger/ledtrig-heartbeat.c)

linux,default-trigger = "heartbeat"

确保ledtrig-heartbeat.c被编入内核

vim /arch/arm/configs/rockchip_linux_defconfig

CONFIG_LEDS_TRIGGERS=y 
CONFIG_LEDS_TRIGGER_TIMER=y 
CONFIG_LEDS_TRIGGER_ONESHOT=y 
CONFIG_LEDS_TRIGGER_HEARTBEAT=y 
CONFIG_LEDS_TRIGGER_BACKLIGHT=y 

参考文献: https://blog.csdn.net/WANGYONGZIXUE/article/details/116449460
https://blog.csdn.net/u013443294/article/details/115178057

【RK3288串口数据解析transportcrc】

移植好相关代码

transportcrc.c,transportcrc.h,type.h,n_tty.c

修改Makefile文件
增加一行

obj-y    += transportcrc.o

修改/arch/arm/configs/rockchip_linux_defconfig
增加一行

CONFIG_TRANSPORTCRC=y

以上是把自己的文件编入内核,这样就可以使用了

【RK3288安卓系统内置app】

使用现成的apk进行

安卓系统内的软件分为可卸载和不可卸载(内置)两类,

可卸载目录:
/device/rockchip/rk3288/preinstall_del 百度输入法

不可卸载目录:
/packages/apps

操作:
在/packages/apps中新建一个文件夹 My_Calculator

将现成的.apk文件拷贝到该文件夹下

新建Android.mk文件
写入内容如下(修改包名为My_Calculator):

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := My_Calculator
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := PRESIGNED


# priv-app
LOCAL_PRIVILEGED_MODULE := true

include $(BUILD_PREBUILT)

在device/制造商/项目名/项目名.mk文件中增加一行

PRODUCT_PACKAGES += My_Calculator

编译有源码app

mmm packages/apps/My_Calculator/

整体编译

./build_keenon.sh W3


内核中用代码实现软链接
位于文件/kernel/include/linux/syscalls.

https://zhuanlan.zhihu.com/p/43505308#:~:text=1%20%E4%BB%A3%E7%A0%81%E4%B8%AD%E4%BC%9A%E4%B8%BA%E9%93%BE%E6%8E%A5%E6%96%87%E4%BB%B6%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AAinode%E7%BB%93%E6%9E%84%EF%BC%8C%E8%BF%99%E5%9C%A8%E5%87%BD%E6%95%B0%20ext3_new_inode%20%28%29%E4%B8%AD%E5%AE%9E%E7%8E%B0%EF%BC%8C%E8%BF%99%E4%B9%9F%E6%98%AF%E7%A1%AC%E9%93%BE%E6%8E%A5%E5%92%8C%E8%BD%AF%E9%93%BE%E6%8E%A5%E7%9A%84%E6%9C%80%E5%A4%A7%E4%B8%8D%E5%90%8C%EF%BC%9B%202,%E9%93%BE%E6%8E%A5%E6%96%87%E4%BB%B6%E7%9A%84%E6%96%87%E4%BB%B6%E5%86%85%E5%AE%B9%E6%98%AF%E6%BA%90%E6%96%87%E4%BB%B6%E7%9A%84%E6%96%87%E4%BB%B6%E5%90%8D%EF%BC%8C%E8%80%8C%E4%B8%94%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%96%87%E4%BB%B6%E5%90%8D%E4%B8%8D%E6%98%AF%E5%BE%88%E9%95%BF%EF%BC%88%E5%B0%8F%E4%BA%8E60%E5%AD%97%E8%8A%82%EF%BC%89%EF%BC%8C%E4%BC%9A%E5%B0%86%E6%96%87%E4%BB%B6%E5%90%8D%E7%9B%B4%E6%8E%A5%E4%BF%9D%E5%AD%98%E5%9C%A8inode%E4%B8%AD%EF%BC%8C%E6%97%A0%E9%9C%80%E4%B8%BA%E5%85%B6%E5%88%86%E9%85%8D%E6%95%B0%E6%8D%AE%E5%9D%97%EF%BC%9B%203%20%E6%9C%80%E5%90%8E%E4%BC%9A%E5%B0%86%E9%93%BE%E6%8E%A5%E6%96%87%E4%BB%B6%E7%9A%84inode%E4%B8%8Edentry%E5%BB%BA%E7%AB%8B%E5%85%B3%E8%81%94%EF%BC%8C%E5%B9%B6%E5%B0%86%E9%93%BE%E6%8E%A5%E6%96%87%E4%BB%B6%E7%9A%84dentry%E5%86%99%E5%85%A5%E5%88%B0%E7%88%B6%E7%9B%AE%E5%BD%95%E7%9A%84%E6%95%B0%E6%8D%AE%E5%9D%97%E4%B8%AD%EF%BC%8C%E8%B0%83%E7%94%A8%E7%9A%84%E6%98%AF%E5%87%BD%E6%95%B0%20ext3_add_nondir%20%28%29%E3%80%82

SYSCALL_DEFINE2(symlink,…)

https://blog.csdn.net/hxmhyp/article/details/22699669



【ttyACM乱跳问题解决】

检测和注册ttyACM设备文件usb/class/cdc-acm.c 通过grep -rn 'ttyACM' *找到的

解决方案:在kernel/drivers/usb/class/cdc-acm.c中将所有ttyACM创建软链接ttyACM0,然后通过在系统的检测usb设备发出的广播,告诉上位机app需要close重新open

frameworks/base/services/usb/java/com/android/server/usb/UsbHostManager
加入mContext.Broadcast(i)来使用广播

【如何在内核中增加自己的驱动文件夹hello,并进行编译】

https://zhuanlan.zhihu.com/p/28461589

在kernel/drivers/下建立一个文件夹hello

mkdir hello
touch hello.c
touch Kconfig
touch Makefile

加入hello.c的内容

修改kernel/drivers/hello/Kconfig (这个是为了生成 make menuconfig的目录选项)

config HELLO
	tristate "Hello Worldfor fengyuwuzu"
	help
	Hello forfengyuwuzu

修改kernel/drivers/hello/Makefile (指明要编译出的.o文件)

obj-$(CONFIG_HELLO) += hello.o

退回上级目录 ,进入目录kernel/drivers/

修改kernel/drivers/Makefile 加入

obj-y += hello/

修改kernel/drivers/Kconfig 加入 (告诉上级目录hello的目录)

source "drivers/hello/Kconfig"

回到kernel/
make menuconfig 勾选相关选项

修改/arch/arm/configs/rockchip_linux_defconfig
增加CONFIG_HELLO=y
(如果有多文件,需要注意也要加上上级目录,比如gpio的上级custom)

修改.config文件内容
增加CONFIG_HELLO=y

之后编译即可

【RK3399 USB在内核阶段上电】

根据光韬的代码原理,他的代码已经实现了对单个usb的GPIO的申请设置

关于gpio号的计算方法, &gpio0~7 每一个都对应了32个号:A0~7 B0~7 C0~7 D0~7。借此来计算dts里面的号码

关于数组的使用方法,参考的是rk3288-android6.0-sdk里面的dts里面的pinctrl
然后找到对应的调用该设备节点的驱动文件,通过设备树节点里面的init-gpios来查找到pinctrl-rockchip.c文件,仿照里面的用法,获得gpio口数组的每一行

【vim操作】

加入插件以后
:T tab后可以打开该文件的大纲
:N tab后可以打开文件目录索引

ctrl w 切换窗口

搜索并全部替换:
ctrl v ,选择操作区域

s/要替换掉的内容/使用替换的东西/g

【压缩解压指令】

压缩目录

tar -czvf myetc.tar.gz etc

解压目录

tar -xzvf myetc.tar.gz

【查询立体视觉等usb设备对应的usb的gpio】

每一个设备,立体视觉有对应的idVendoridProduct
前者表示厂商号码,通过lsusb指令查询得到立体视觉的idVendor2207

由于idVendoridProduct存放在/sys/bus/usb/devices/3-1.4/

grep -rn "2207" /sys/bus/usb/devices/*/idVendor 

可以查到

/sys/class/gpio下可以手动配置每个usb的gpio的电压值,通过这里来上电

/etc/init.d下可以查到开机自启动脚本上电操作

【串口数据量显示调试工具demo】

源码发给了 杜尚东
/serial_data_count

修改main.c里面,使用while循环,每次读取缓存区内的数据量并返回大小打印,同时sleep(1),即可实现定时输出,无需定时器

【git提交gerrit】

gerrit出现问题

重新拉一次项目的最初的源码,在外层目录

git clone ssh://[email protected]:29418/linux/tools/usb-device-detect
cd
tig

切换到主分支

git checkout master

删除刚刚误创建的分支

git branch -D develop

创建远程的的分支到本地

git checkout -b develop origin/develop

查看是否拉到源码到本地

tig

到gerrit上找到需要修改的一页,找到右上角的downloads pull下来

git pull ssh://[email protected]:29418/linux/tools/usb-device-detect refs/changes/48/30248/4

查看是否把要修改的commit拉下来

tig

修改该commit代码,并提交

vim main.c
git add main.c
git commit --amend
git push ssh://[email protected]:29418/linux/tools/usb-device-detect HEAD:refs/for/develop
(第一个参数是远程仓库,第二个参数指的是把HEAD的commit提交到远程的分支)

【git操作解析】

git fetch origin 

会抓取克隆(或上一次抓取)后新推送的所有工作。 必须注意 git fetch 命令只会将数据下载到你的本地仓库——它并不会自动合并或修改你当前的工作。 当准备好时你必须手动将其合并入你的工作。


git clone 

命令会自动设置本地 master 分支跟踪克隆的远程仓库的 master 分支(或其它名字的默认分支)


git pull 

通常会从最初克隆的服务器上抓取数据并自动尝试合并到当前所在的分支,自动抓取后合并该远程分支到当前分支


git push <remote> <branch>

Git 的分支,其实本质上仅仅是指向提交对象的可变指针。
HEAD 也是个指针,指向当前所在的本地分支,来表示当前在那个分支上,将 HEAD 想象为当前分支的别名


git branch testing

创建分支


git log --oneline --decorate
git log --oneline --decorate --graph --all

查看当前分支关系,HEAD

git 提交的commit打包成patch

git format-patch -1 HEAD

【网络通信】

配置一台机器的网络:

公司网关172.16.9.1

自动获取ip地址:

sudo dhclient eth0
sudo ifconfig eth0

1、配置开发板ip

ifconfig eth0 192.168.137.2 

2、配置开发板网关(网关代表外部网络)

route add default gw 192.168.137.1

3、ping www.baidu.com

【RK3399版本管理】

将0830的那个rootfs挂载到台式机上,然后光韬有一个rootfs的配置文件的root目录,你每次有什么配置文件需要修改的,就直接修改root的配置文件管理目录,然后将他cp到台式机,用rsync进行同步。

【ubuntu台式机使用scp从服务器上下载文件到本地】

scp [email protected]:/media/hdd2/liangji/XXX /home/administrator/RK3399-rootfs-202208030/

1、从服务器上下载文件

scp username@servername:/path/filename /var/www/local_dir(本地目录)

例如scp [email protected]:/var/www/test.txt192.168.0.101上的/var/www/test.txt 的文件下载到/var/www/local_dir(本地目录)

2、上传本地文件到服务器

scp /path/filename username@servername:/path   

例如scp /var/www/test.php [email protected]:/var/www/ 把本机/var/www/目录下的test.php文件上传到192.168.0.101这台服务器上的/var/www/目录中

3、从服务器下载整个目录

scp -r username@servername:/var/www/remote_dir/(远程目录) /var/www/local_dir(本地目录)

例如:scp -r [email protected]:/var/www/test /var/www/

4、上传目录到服务器

scp  -r local_dir username@servername:remote_dir

例如:scp -r test [email protected]:/var/www/ 把当前目录下的test目录上传到服务器的/var/www/ 目录

【RK3399研究syslog和kmsg的区别】

通过对usb的gpio口上下电,进行开关,
syslog和kmsg都是通过从ringbuffer中读取log信息,关闭其中一个,另一个的调试信息可以完整输出

----------------------------------------------------------------------------16:42 2022/9/8

【iptables配置ubuntu主机网络共享】

iptables有多个参数可以进行配置四表五链

使用案例https://www.cnblogs.com/wanstack/p/8393282.html
参数详解https://www.jianshu.com/p/5a604b4ef342

需要将ubuntu台式机配置成路由器实现网络共享功能
ubuntu台式机与笔记本之间vnc连接 10.-
ubuntu台式机与开发板之间连接 192
Ubuntu台式机与公司网络连接 172

1.永久打开ubuntu的nat表功能

sudo gedit /etc/sysctl.conf

2.取消注释

net.ipv4.ip_forward=1

3.启动

sudo sysctl -p

这样在经过PREROUTING后经过路由选择后可以走FORWARD通道,之后走POSTROUTING
由于ubuntu默认FORWARD的默认策略是ACCEPT,所以filter里的FORWARD链不需要再进行设置

4.让每个网口都支持转发功能(加入规则,只要是往这个网口输出的,全部自动修改源地址MASQUERADE)

sudo iptables -t nat -N nat_board_computer

sudo iptables -t nat -I nat_board_computer 1 -o enp2s0 -j MASQUERADE
sudo iptables -t nat -I nat_board_computer 1 -o enx000ec6821555 -j MASQUERADE
sudo iptables -t nat -A nat_board_computer -o enx000ec670d129 -j MASQUERADE

sudo iptables -t nat -I POSTROUTING -j nat_board_computer

注意
Windows下ping baidu.com 找不到服务器名 原因是没有配置DNS 8.8.8.8 或者 114.114.114.114

DNS是和baidu.com同级的存在,用于帮忙查询翻译baidu.com的IP地址

【安卓网络诊断工具】

打算在显示里面加一个网络诊断工具按钮控件
package/目录下

diff --git a/apps/Settings/res/xml/display_settings.xml b/apps/Settings/res/xml/display_settings.xml
index b8b47c6..a817f61 100644
--- a/apps/Settings/res/xml/display_settings.xml
+++ b/apps/Settings/res/xml/display_settings.xml
@@ -37,6 +37,12 @@
                 android:key="systembar_hide"
                 android:title="@string/systembar_hide_title"/>
 
+        <PreferenceScreen
+                android:key="network_debug_tool"
+                android:title="@string/network_info_debug_title"/>
+
+
+
         <!-- Hide night mode for now
         <ListPreference
             android:key="night_mode"

定义按钮的标题文件

diff --git a/apps/Settings/res/values-zh-rCN/strings.xml b/apps/Settings/res/values-zh-rCN/strings.xml
index d9bdd5d..19063b1 100644
--- a/apps/Settings/res/values-zh-rCN/strings.xml
+++ b/apps/Settings/res/values-zh-rCN/strings.xml
@@ -3062,6 +3062,7 @@
     <string name="switch_success">切换成功</string>
     <string name="connect_to_pc">连接到 PC</string>
     <string name="systembar_hide_title">永久隐藏工具栏</string>
+    <string name="network_info_debug_title">网络信息诊断工具</string>
     <!--$_rbox_$_modify_$_end-->
 
 </resources>
diff --git a/apps/Settings/res/values/strings.xml b/apps/Settings/res/values/strings.xml
index c1c1fdc..f8d25f3 100644
--- a/apps/Settings/res/values/strings.xml
+++ b/apps/Settings/res/values/strings.xml
@@ -7205,6 +7205,7 @@
     <string name="connect_to_pc">Connect to PC</string>
     <string name="switch_success">switch success</string>
     <string name="systembar_hide_title">Always hide the status bar</string>
+    <string name="network_info_debug_title">Network debug tool</string>
     <!--$_rbox_$_modify_$_end-->
 
 </resources>

定义按钮控件的动作

diff --git a/apps/Settings/src/com/android/settings/DisplaySettings.java b/apps/Settings/src/com/android/settings/DisplaySettings.java
index b86de5a..3b52d7a 100644
--- a/apps/Settings/src/com/android/settings/DisplaySettings.java
+++ b/apps/Settings/src/com/android/settings/DisplaySettings.java
@@ -63,6 +63,7 @@ import android.preference.CheckBoxPreference;
 import java.util.ArrayList;
 import java.util.List;
 
+import java.io.IOException;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.OutputStream;
@@ -74,8 +75,11 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
 
     /** If there is no setting in the provider, use this. */
     private static final int FALLBACK_SCREEN_TIMEOUT_VALUE = 30000;
+    private static final int CLICK_DELAY_TIME = 500;
+    private static long lastClickTime;
 
     private static final String KEY_SYSTEMBAR_HIDE = "systembar_hide";
+    private static final String KEY_NETWORK_DEBUG_TOOL = "network_debug_tool";
     private static final String KEY_SCREEN_TIMEOUT = "screen_timeout";
     private static final String KEY_FONT_SIZE = "font_size";
     private static final String KEY_SCREEN_SAVER = "screensaver";
@@ -92,6 +96,7 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
     private static final int DLG_GLOBAL_CHANGE_WARNING = 1;
 
     private CheckBoxPreference mSystemBarHide;
+    private Preference mNetworkDebugTool;
     private WarnedListPreference mFontSizePref;
 
     private final Configuration mCurConfig = new Configuration();
@@ -128,6 +133,7 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
         }
 
         mSystemBarHide = (CheckBoxPreference) findPreference(KEY_SYSTEMBAR_HIDE);
+        mNetworkDebugTool = (Preference) findPreference(KEY_NETWORK_DEBUG_TOOL);
 
 
         mScreenTimeoutPreference = (ListPreference) findPreference(KEY_SCREEN_TIMEOUT);
@@ -237,6 +243,15 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
             mNightModePreference.setOnPreferenceChangeListener(this);
         }
     }
+    public static boolean isNotFastClick() {
+        boolean flag = false;
+        long currentClickTime = System.currentTimeMillis();
+        if ((currentClickTime - lastClickTime) >= CLICK_DELAY_TIME) {
+            flag = true;
+        }
+        lastClickTime = currentClickTime;
+        return flag;
+    }
 
     private static boolean allowAllRotations(Context context) {
         return Resources.getSystem().getBoolean(
@@ -475,6 +490,18 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
             Intent i = new Intent("com.keenon.changeBarHideStatus");
             getActivity().sendBroadcast(i);
         }
+        else if(preference == mNetworkDebugTool)
+        {
+            if (isNotFastClick()) {
+                Log.i(TAG, "network debug tool is running, please waiting");
+                try{
+                    Process process = Runtime.getRuntime().exec("/system/bin/network_debug_tool.sh");
+                } catch (IOException e){
+                    Log.e(TAG, "Fail: IOException");
+                }
+            }
+        }
+
         return super.onPreferenceTreeClick(preferenceScreen, preference);
     }
 
@@ -611,4 +638,4 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
                     return result;
                 }
             };
-}
+        }

把运行脚本默认放到/system/bin/目录下/device/rockchip/rk3288/

diff --git a/rk3288.mk b/rk3288.mk
index 74c185d..30494a5 100644
--- a/rk3288.mk
+++ b/rk3288.mk
@@ -28,6 +28,7 @@ PRODUCT_MANUFACTURER := rockchip
 
 # Keenon Jimmy.Jin add
 PRODUCT_COPY_FILES += device/rockchip/rk3288/user_service.sh:system/bin/user_service.sh
+PRODUCT_COPY_FILES += device/rockchip/rk3288/network_debug_tool.sh:system/bin/network_debug_tool.sh
 PRODUCT_COPY_FILES += device/rockchip/rk3288/EC20/libreference-ril.so:system/lib/libreference-ril.so
 PRODUCT_COPY_FILES += device/rockchip/rk3288/EC20/ip-down:system/etc/ppp/ip-down
 PRODUCT_COPY_FILES += device/rockchip/rk3288/EC20/ip-up:system/etc/ppp/ip-up
@@ -43,7 +44,7 @@ PRODUCT_PROPERTY_OVERRIDES += \

执行脚本 network_debug_tool.sh

#!/system/bin/sh

FLAG=/mnt/network_debug_tool_process_flag.pid

if [ -f "$FLAG"  ]
then
    exit
fi


touch $FLAG
[ ! -d /sdcard/network_log ] && mkdir /sdcard/network_log

FILE=/sdcard/network_log/networkk_debug_info_$(date +%Y%m%d_%H%M%S).log

route -n >> $FILE
ifconfig >> $FILE
iwconfig >> $FILE 2>&1

ip rule >> $FILE
ip route show table 1 >> $FILE

iptables -nvL >> $FILE
iptables -nvL -t nat >> $FILE
iptables -nvL -t raw >> $FILE
iptables -nvL -t mangle >> $FILE

ping -c 4 -W 1 192.168.64.20 >> $FILE
ping -c 4 -W 1 baidu.com >> $FILE

rm $FLAG


【ubuntu创建自定义指令工具】

vi ~/.bashrc

加入一行
alias diagnosis='/usr/local/bin/diagnosis/diagnosis'

source ~/.bashrc

【c语言实现全局变量】

main.c

#include 

#define EXPORT_GLOBALS
#include "define_variable_in_header.h"

#include "fun.h"


int main(int argc, char* argv[])
{
    g_flag = 5;
    g_flag++;
    printf("%d\r\n", g_flag);

    usb_scan();
    return 0;
}


define_variable_in_header.h

#pragma once
#ifndef __DEFINE_VARIABLE_IN_HEADER_H
#define __DEFINE_VARIABLE_IN_HEADER_H

#ifdef EXPORT_GLOBALS
#define EXTERN
#else
#define EXTERN extern
#endif

EXTERN unsigned int g_flag;

#endif/*__DEFINE_VARIABLE_IN_HEADER_H*/

fun.h

#pragma once
#include 

#define EXPORT_GLOBALS
#include "define_variable_in_header.h"

int usb_scan();

fun.c

#include "fun.h"
int usb_scan()
{
	printf("usb_scan: %d\n", g_flag);
	return 0;

}

【record】_第1张图片

【usb_scan支持-v-t-f-s,且作为后台服务】

usb_scan

【RK3308 dmesg不停打印init: /dev/tty1 termined status 1 】

未找到解决方法,原因是dev/ttyN 没有自动创建,导致init在执行tty1.conf时循环执行/sbin/getty,无法打开文件。
为了解决该问题打印大量日志的问题,将/etc/init/tty*.conf改名未/etc/init/tty*.conf.no

【RK3288 android6.0 支持同时显示多个摄像头源码解析】

https://www.litreily.top/2021/07/12/dual-camera/

光韬博客
https://www.litreily.top/

int camera_get_number_of_cameras(void)
{
    char cam_sys[40];
    char cam_path[20];
    char cam_num[3],i;
    int cam_cnt=0,fd=-1,rk29_cam[CAMERAS_SUPPORT_MAX];
    struct v4l2_capability capability;
    rk_cam_info_t camInfoTmp[CAMERAS_SUPPORT_MAX];
    char *ptr,**ptrr;
    char version[PROPERTY_VALUE_MAX];
    char property[PROPERTY_VALUE_MAX];
    int hwrotation = 0;
	camera_board_profiles * profiles = NULL;
    size_t nCamDev = 0;
    char trace_level[PROPERTY_VALUE_MAX];
	struct timeval t0, t1;
    ::gettimeofday(&t0, NULL);
	
    if (gCamerasNumber > 0)
        goto camera_get_number_of_cameras_end;

    {
		property_set(CAMERAHAL_CAM_OTP_PROPERTY_KEY, "true");
        memset(version,0x00,sizeof(version));
        sprintf(version,"%d.%d.%d",((CONFIG_CAMERAHAL_VERSION&0xff0000)>>16),
            ((CONFIG_CAMERAHAL_VERSION&0xff00)>>8),CONFIG_CAMERAHAL_VERSION&0xff);
        property_set(CAMERAHAL_VERSION_PROPERTY_KEY,version);

        property_get(CAMERAHAL_TRACE_LEVEL_PROPERTY_KEY, trace_level, "-1");
        if (strcmp(trace_level,"-1")==0) {
            property_set(CAMERAHAL_TRACE_LEVEL_PROPERTY_KEY, "0");
        }

        memset(version,0x00,sizeof(version));
        sprintf(version,"%d.%d.%d",((ConfigBoardXmlVersion&0xff0000)>>16),
            ((ConfigBoardXmlVersion&0xff00)>>8),ConfigBoardXmlVersion&0xff);
        property_set(CAMERAHAL_CAMBOARDXML_PARSER_PROPERTY_KEY,version);


        CamEngineVersionItf *camEngVerItf;
        CamEngVer_t camEngVer;

        camEngVerItf = new CamEngineVersionItf();

        camEngVerItf->getVersion(&camEngVer);
        
        memset(version,0x00,sizeof(version));
        sprintf(version,"%d.%d.%d",((camEngVer.libisp_ver&0xff0000)>>16),
            ((camEngVer.libisp_ver&0xff00)>>8),camEngVer.libisp_ver&0xff);
        property_set(CAMERAHAL_LIBISP_PROPERTY_KEY,version);

        memset(version,0x00,sizeof(version));
        sprintf(version,"%d.%d.%d",((camEngVer.isi_ver&0xff0000)>>16),
            ((camEngVer.isi_ver&0xff00)>>8),camEngVer.isi_ver&0xff);
        property_set(CAMERAHAL_ISI_PROPERTY_KEY,version);

        delete camEngVerItf;

    }
    
    for(int i=0;i<CAMERAS_SUPPORT_MAX;i++){
        memset(&camInfoTmp[i],0x00,sizeof(rk_cam_info_t));
    }
    //memset(&camInfoTmp[0],0x00,sizeof(rk_cam_info_t));
    //memset(&camInfoTmp[1],0x00,sizeof(rk_cam_info_t));

    profiles = camera_board_profiles::getInstance();
    nCamDev = profiles->mDevieVector.size();
	LOGE("board profiles cam num %d\n", nCamDev);
    if (nCamDev>0) {
        camera_board_profiles::LoadSensor(profiles);
        char sensor_ver[32];
		
        for (i=0; (i<nCamDev); i++) 
        {  
        	LOGE("load sensor name(%s) connect %d\n", profiles->mDevieVector[i]->mHardInfo.mSensorInfo.mSensorName, profiles->mDevieVector[i]->mIsConnect);
        	if(profiles->mDevieVector[i]->mIsConnect==1){
    	        rk_sensor_info *pSensorInfo = &(profiles->mDevieVector[i]->mHardInfo.mSensorInfo);
    	        
    	        camInfoTmp[cam_cnt].pcam_total_info = profiles->mDevieVector[i];
    	        strncpy(camInfoTmp[cam_cnt].device_path, pSensorInfo->mCamsysDevPath, sizeof(camInfoTmp[cam_cnt].device_path));
    	        strncpy(camInfoTmp[cam_cnt].driver, pSensorInfo->mSensorDriver, sizeof(camInfoTmp[cam_cnt].driver));
				unsigned int SensorDrvVersion = profiles->mDevieVector[i]->mLoadSensorInfo.mpI2cInfo->sensor_drv_version;
				memset(version,0x00,sizeof(version));
    	        sprintf(version,"%d.%d.%d",((SensorDrvVersion&0xff0000)>>16),
	    	            ((SensorDrvVersion&0xff00)>>8),SensorDrvVersion&0xff);
						 
    	        if(pSensorInfo->mFacing == RK_CAM_FACING_FRONT){     
    	            camInfoTmp[cam_cnt].facing_info.facing = CAMERA_FACING_FRONT;
    	        } else {
    	            camInfoTmp[cam_cnt].facing_info.facing = CAMERA_FACING_BACK;
    	        } 

                memset(sensor_ver,0x00,sizeof(sensor_ver));
                if (strlen(pSensorInfo->mSensorName) < (sizeof(sensor_ver)-16))
                    sprintf(sensor_ver,"%s%s%s","sys_graphic.",pSensorInfo->mSensorName,".ver");
                else 
                    sprintf(sensor_ver,"%s",pSensorInfo->mSensorName);                
                property_set(sensor_ver, version);	
                
    	        camInfoTmp[cam_cnt].facing_info.orientation = pSensorInfo->mOrientation;
    	        cam_cnt++;

    			unsigned int CamsysDrvVersion = profiles->mDevieVector[i]->mCamsysVersion.drv_ver;
    	        memset(version,0x00,sizeof(version));
    	        sprintf(version,"%d.%d.%d",((CamsysDrvVersion&0xff0000)>>16),
    	            ((CamsysDrvVersion&0xff00)>>8),CamsysDrvVersion&0xff);
    	        property_set(CAMERAHAL_CAMSYS_VERSION_PROPERTY_KEY,version);
    		}
        }
    }

   	if(cam_cnt<CAMERAS_SUPPORT_MAX){
		int i=0;
		int element_count=0;
		while(MediaProfile_Resolution[i][0]>0 && MediaProfile_Resolution[i][1]>0){
			element_count++;
			i++;
		}
		
        for (i=0; i<20; i++) {
            cam_path[0] = 0x00;
			//unsigned int pix_format_tmp = V4L2_PIX_FMT_NV12;
            //strcat(cam_path, CAMERA_DEVICE_NAME);
            cam_sys[0] = 0x00;
            strcat(cam_sys, CAM_SYS_NAME);
            sprintf(cam_num, "%d", i);
            strcat(cam_sys,cam_num);
            strcat(cam_sys,"/index");
            FILE* ifp;
            ifp = fopen(cam_sys, "r");
            if (ifp == NULL){
                LOGD("fail to open sys file:%s",cam_sys);
                continue;
            }
            unsigned char index;
            fread(&index, sizeof(char),1, ifp);
            fclose(ifp);
            LOGD("open %s index %x",cam_sys,index);
            if(index == 0x31){
                LOGD("%s wrong index continue",cam_sys);
                continue;
            }
            strcat(cam_path, CAMERA_DEVICE_NAME);

            strcat(cam_path,cam_num);
            fd = open(cam_path, O_RDONLY);
            unsigned int pix_format_tmp = V4L2_PIX_FMT_NV12;
            if (fd < 0) {
                LOGE("Open %s failed! strr: %s",cam_path,strerror(errno));
                break;
            } 
            LOGD("Open %s success!",cam_path);

            memset(&capability, 0, sizeof(struct v4l2_capability));
            if (ioctl(fd, VIDIOC_QUERYCAP, &capability) < 0) {
            	LOGE("Video device(%s): query capability not supported.\n",cam_path);
                goto loop_continue;
            }
            
            if ((capability.capabilities & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING)) != (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING)) {
        	    LOGD("Video device(%s): video capture not supported.\n",cam_path);
            } else {
            	rk_cam_total_info* pNewCamInfo = new rk_cam_total_info();
                memset(camInfoTmp[cam_cnt].device_path,0x00, sizeof(camInfoTmp[cam_cnt].device_path));
                strcat(camInfoTmp[cam_cnt].device_path,cam_path);
                memset(camInfoTmp[cam_cnt].fival_list,0x00, sizeof(camInfoTmp[cam_cnt].fival_list));
                memcpy(camInfoTmp[cam_cnt].driver,capability.driver, sizeof(camInfoTmp[cam_cnt].driver));
                camInfoTmp[cam_cnt].version = capability.version;
                if (strstr((char*)&capability.card[0], "front") != NULL) {
                    camInfoTmp[cam_cnt].facing_info.facing = CAMERA_FACING_FRONT;
                } else {
                    camInfoTmp[cam_cnt].facing_info.facing = CAMERA_FACING_BACK;
                }  
                ptr = strstr((char*)&capability.card[0],"-");
                if (ptr != NULL) {
                    ptr++;
                    camInfoTmp[cam_cnt].facing_info.orientation = atoi(ptr);
                } else {
                    camInfoTmp[cam_cnt].facing_info.orientation = 0;
                }

                memset(version,0x00,sizeof(version));
                sprintf(version,"%d.%d.%d",((capability.version&0xff0000)>>16),
                    ((capability.version&0xff00)>>8),capability.version&0xff);
                property_set(CAMERAHAL_V4L2_VERSION_PROPERTY_KEY,version);
				
				if(strcmp((char*)&capability.driver[0],"uvcvideo") == 0)//uvc
				{
					int ret,i=0,j=0;					 
					struct v4l2_frmivalenum fival;
					struct v4l2_frmsizeenum fsize;
					struct v4l2_fmtdesc fmtdesc;
					unsigned int width, height;
					unsigned int sensor_resolution_w=0,sensor_resolution_h=0;
					unsigned int CameraHal_SupportFmt[6];
					unsigned int mCamDriverSupportFmt[CAMERA_DRIVER_SUPPORT_FORMAT_MAX];
					unsigned int mCamDriverPreviewFmt=0;
					unsigned int maxfps;

					//add usb camera to board_profiles 
					rk_DV_info *pDVResolution = new rk_DV_info();
					memset(pNewCamInfo->mHardInfo.mSensorInfo.mSensorName, 0x00, sizeof(pNewCamInfo->mHardInfo.mSensorInfo.mSensorName));
					strcpy(pNewCamInfo->mHardInfo.mSensorInfo.mSensorName, UVC_CAM_NAME);
					pNewCamInfo->mIsIommuEnabled = capability.reserved[0];
					#if 0
					//DV
					strcpy(pDVResolution->mName, "480p");
		    	    pDVResolution->mWidth = 640;
		    	    pDVResolution->mHeight = 480;
		    	    pDVResolution->mFps = 10;
		    	    pDVResolution->mIsSupport =  1;
		            pDVResolution->mResolution = ISI_RES_VGAP15;
		            pNewCamInfo->mSoftInfo.mDV_vector.add(pDVResolution);
					#endif
					//paremeters
					pNewCamInfo->mSoftInfo.mAntiBandingConfig.mAntiBandingSupport = 0;
					pNewCamInfo->mSoftInfo.mAntiBandingConfig.mDefault = 0;
					pNewCamInfo->mSoftInfo.mAwbConfig.mAwbSupport = 0;
					pNewCamInfo->mSoftInfo.mAwbConfig.mDefault = 0;
					pNewCamInfo->mSoftInfo.mContinue_snapshot_config= 0;
					pNewCamInfo->mSoftInfo.mEffectConfig.mEffectSupport = 0;
					pNewCamInfo->mSoftInfo.mEffectConfig.mDefault = 0;
					pNewCamInfo->mSoftInfo.mFlashConfig.mFlashSupport= 0;
					pNewCamInfo->mSoftInfo.mFlashConfig.mDefault = 0;
					pNewCamInfo->mSoftInfo.mFocusConfig.mFocusSupport= 0;
					pNewCamInfo->mSoftInfo.mFocusConfig.mDefault = 0;
					pNewCamInfo->mSoftInfo.mHDRConfig= 0;
					pNewCamInfo->mSoftInfo.mSenceConfig.mSenceSupport= 0;
					pNewCamInfo->mSoftInfo.mSenceConfig.mDefault = 0;
					pNewCamInfo->mSoftInfo.mZSLConfig = 0;
					pNewCamInfo->mSoftInfo.mInterpolationRes = 0;
					//profiles->AddConnectUVCSensorToVector(pNewCamInfo, profiles);

					CameraHal_SupportFmt[0] = V4L2_PIX_FMT_NV12;
				    CameraHal_SupportFmt[1] = V4L2_PIX_FMT_NV16;
				    #if CONFIG_CAMERA_UVC_MJPEG_SUPPORT
				    CameraHal_SupportFmt[2] = V4L2_PIX_FMT_MJPEG;
				    CameraHal_SupportFmt[3] = V4L2_PIX_FMT_YUYV;
				    CameraHal_SupportFmt[4] = V4L2_PIX_FMT_RGB565;
				    #else
				    CameraHal_SupportFmt[2] = V4L2_PIX_FMT_YUYV;
				    CameraHal_SupportFmt[3] = V4L2_PIX_FMT_RGB565;
				    CameraHal_SupportFmt[4] = 0x00;
				    #endif
				    CameraHal_SupportFmt[5] = 0x00;

					memset(&fmtdesc, 0, sizeof(fmtdesc));	 
					fmtdesc.index = 0;
					fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;    
					while (ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) == 0) {
						mCamDriverSupportFmt[fmtdesc.index] = fmtdesc.pixelformat;
						LOG1("mCamDriverSupportFmt:(%c%c%c%c),index = %d",fmtdesc.pixelformat&0xFF,(fmtdesc.pixelformat>>8)&0xFF,
							(fmtdesc.pixelformat>>16)&0xFF,(fmtdesc.pixelformat>>24)&0xFF,fmtdesc.index);
						fmtdesc.index++;
					}
										
					i = 0;	  
					while (CameraHal_SupportFmt[i]) {
						LOG1("CameraHal_SupportFmt:fmt = %d,index = %d",CameraHal_SupportFmt[i],i);
						j = 0;
						while (mCamDriverSupportFmt[j]) {
							if (mCamDriverSupportFmt[j] == CameraHal_SupportFmt[i]) {
								break;
							}
							j++;
						}
						if (mCamDriverSupportFmt[j] == CameraHal_SupportFmt[i]) {
							break;
						}
						i++;
					}
					
					if (CameraHal_SupportFmt[i] == 0x00) {
						mCamDriverPreviewFmt = 0;
					} else {  
						mCamDriverPreviewFmt = CameraHal_SupportFmt[i];
					}

					fsize.index = 0;
					fsize.pixel_format = mCamDriverPreviewFmt;

					while ((ret = ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &fsize)) == 0) {
						if (fsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) {  
							//if(fsize.discrete.width%16 || fsize.discrete.height%16)
							//{
							//	fsize.index++;
							//	continue;
							//}
					
							if (fsize.discrete.width > sensor_resolution_w) {
								sensor_resolution_w = fsize.discrete.width;
								sensor_resolution_h = fsize.discrete.height;
							}
						}
						fsize.index++;
					}
					if(sensor_resolution_w == 0){
						sensor_resolution_w = 640;
						sensor_resolution_h = 480;
						pDVResolution->mResolution = ISI_RES_VGAP15;
					}
					for(i=0; i<element_count; i++){
						width = MediaProfile_Resolution[i][0];
			            height = MediaProfile_Resolution[i][1];				
			            memset(&fival, 0, sizeof(fival));
			            fival.index = 0;
			            fival.pixel_format = fsize.pixel_format;
			            fival.width = width;
			            fival.height = height;
			            fival.reserved[1] = 0x00;	
						maxfps = 0;
						
						rk_DV_info *pDVResolution = new rk_DV_info();
						pDVResolution->mWidth = width;
		    	    	pDVResolution->mHeight = height;
		    	    	pDVResolution->mFps = 0;
		    	    	pDVResolution->mIsSupport =  0;

						if ((width>sensor_resolution_w) || (height>sensor_resolution_h)) {
							pNewCamInfo->mSoftInfo.mDV_vector.add(pDVResolution);
	                		continue;
	            		}
	            		//LOGE("index = %d, pixel_format = %d, width = %d, height = %d", 
	            		//    fival.index, fival.pixel_format, fival.width,  fival.height);
						while ((ret = ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &fival)) == 0) {
							if (fival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
								pDVResolution->mFps = fival.discrete.denominator/fival.discrete.numerator;
								pDVResolution->mIsSupport = 1;
								if (pDVResolution->mFps > maxfps)
									maxfps = pDVResolution->mFps;
								LOG1("%dx%d : %d	%d/%d",fival.width,fival.height, pDVResolution->mFps,fival.discrete.denominator,fival.discrete.numerator);
							}else if (fival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS) {
			                    break;
			                } else if (fival.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
			                    break;
			                }
							fival.index++;
						}
						if(ret){
							pDVResolution->mIsSupport = 1;
							if(maxfps > 0)
								pDVResolution->mFps = maxfps;
							else
								pDVResolution->mFps = 10;
				 		}
						pNewCamInfo->mSoftInfo.mDV_vector.add(pDVResolution);	        
					}
				}
				else//cif soc camera
				{
					int i=0;					 
					int fps;
					int crop_w, crop_h;
					int width, height;
					struct v4l2_format fmt;
					struct v4l2_format format;
					struct v4l2_frmivalenum fival;
					int sensor_resolution_w=0,sensor_resolution_h=0;
					int resolution_index = -1;
					
					fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
			        fmt.fmt.pix.pixelformat= V4L2_PIX_FMT_NV12;
			        fmt.fmt.pix.field = V4L2_FIELD_NONE;
			        fmt.fmt.pix.width = 10000;
			        fmt.fmt.pix.height = 10000;
			        int ret = ioctl(fd, VIDIOC_TRY_FMT, &fmt);
			        sensor_resolution_w = fmt.fmt.pix.width;
			        sensor_resolution_h = fmt.fmt.pix.height;  /* [email protected]: v0.4.e */				
					for(i=0; i<element_count; i++){
						width = MediaProfile_Resolution[i][0];
			            height = MediaProfile_Resolution[i][1];				
			            memset(&fival, 0, sizeof(fival));
			            fival.index = 0;
			            fival.pixel_format = pix_format_tmp;
			            fival.width = width;
			            fival.height = height;
			            fival.reserved[1] = 0x00;	

						rk_DV_info *pDVResolution = new rk_DV_info();
						pDVResolution->mWidth = width;
		    	    	pDVResolution->mHeight = height;
		    	    	pDVResolution->mFps = 0;
		    	    	pDVResolution->mIsSupport =  0;

						if ((width>sensor_resolution_w) || (height>sensor_resolution_h)) {
							pNewCamInfo->mSoftInfo.mDV_vector.add(pDVResolution);
	                		continue;
	            		}
										
						if ((ret = ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &fival)) == 0) {
							if (fival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {	
								fps = (fival.discrete.denominator/fival.discrete.numerator);
	                    		crop_w = (fival.reserved[1]&0xffff0000)>>16;
	                    		crop_h = (fival.reserved[1]&0xffff);
                                pDVResolution->mFps = 30;//fps;//for passing cts,should be ok for now.
								pDVResolution->mIsSupport = 1;
								
								if ((crop_w != width) || (crop_h != height)) {
			                        if((width==1280 && height==720 ) || (width==1920 && height==1080 )) {
			                            pDVResolution->mIsSupport = 0;
			                        }
			                    }

								if(width==720 && height==480){
			                        if ((crop_w>800) || (crop_h>600)) {    /* [email protected]: v0.4.e */
			                             pDVResolution->mIsSupport =  0;    
			                        } else {                       
			                            resolution_index = find_DV_resolution_index(640,480);
										if(resolution_index>0)
			                 				pNewCamInfo->mSoftInfo.mDV_vector[resolution_index]->mIsSupport = 0;
			                        }
			                    }

                                /* needn't support dv 800x600 ,just support vga*/
								if((width == 800) && (height == 600)){
									pDVResolution->mIsSupport = 0;
								}
								
							}else{
								pDVResolution->mIsSupport = 0;
								LOGE("find frame intervals failed ret(%d)\n", ret);
							}
						}else{
							pDVResolution->mIsSupport = 0;
							LOGE("find frame intervals failed ret(%d)\n", ret);
						}
						
						pNewCamInfo->mSoftInfo.mDV_vector.add(pDVResolution);	        
					}
					
					strcpy(pNewCamInfo->mHardInfo.mSensorInfo.mSensorName, SOC_CAM_NAME);
					pNewCamInfo->mIsIommuEnabled = capability.reserved[0];
					if (strstr((char*)&capability.card[0], "front") != NULL) {
                    	pNewCamInfo->mHardInfo.mSensorInfo.mFacing = 1;
                	} else {
                    	pNewCamInfo->mHardInfo.mSensorInfo.mFacing = 0;
                	}
				}
                pNewCamInfo->mHardInfo.mSensorInfo.mPhy.type = CamSys_Phy_end;

				//pNewCamInfo->mDeviceIndex = (profiles->mDevieVector.size()) - 1;
				pNewCamInfo->mIsConnect = 1;
				profiles->mCurDevice= pNewCamInfo;
            	profiles->mDevieVector.add(pNewCamInfo);
				pNewCamInfo->mDeviceIndex = (profiles->mDevieVector.size()) - 1;
                camInfoTmp[cam_cnt].pcam_total_info = pNewCamInfo;
                cam_cnt++;
                if (cam_cnt >= CAMERAS_SUPPORT_MAX)
                    i = 20;
            }
    loop_continue:
            if (fd > 0) {
                close(fd);
                fd = -1;
            }
            continue;    
        }
   	}

   
	camera_board_profiles::ProduceNewXml(profiles);
	
    gCamerasNumber = cam_cnt;

#if CONFIG_AUTO_DETECT_FRAMERATE
    rk29_cam[0] = 0xff;
    rk29_cam[1] = 0xff;
    for (i=0; i<cam_cnt; i++) {
        if (strcmp((char*)&camInfoTmp[i].driver[0],"rk29xx-camera") == 0) {
            if (strcmp((char*)&camInfoTmp[i].driver[0],(char*)&gCamInfos[i].driver[0]) != 0) {
                rk29_cam[i] = i; 
            }
        } else {
            rk29_cam[i] = 0xff;
        }
    }

    if ((rk29_cam[0] != 0xff) || (rk29_cam[1] != 0xff)) {
        if (gCameraFpsDetectThread == NULL) {
            gCameraFpsDetectThread = new CameraFpsDetectThread();
            LOGD("%s create CameraFpsDetectThread for enum camera framerate!!",__FUNCTION__);
            gCameraFpsDetectThread->run("CameraFpsDetectThread", ANDROID_PRIORITY_AUDIO);
        }
    }
#endif    

    #if CONFIG_CAMERA_SINGLE_SENSOR_FORCE_BACK_FOR_CTS
    if ((gCamerasNumber==1) && (camInfoTmp[0].facing_info.facing==CAMERA_FACING_FRONT)) {
        gCamerasNumber = 2;
        memcpy(&camInfoTmp[1],&camInfoTmp[0], sizeof(rk_cam_info_t));
        camInfoTmp[1].facing_info.facing = CAMERA_FACING_BACK;
    }
    #endif
    
    //memcpy(&gCamInfos[0], &camInfoTmp[0], sizeof(rk_cam_info_t));
    //memcpy(&gCamInfos[1], &camInfoTmp[1], sizeof(rk_cam_info_t));
    for(int i=0;i<CAMERAS_SUPPORT_MAX;i++){
        memcpy(&gCamInfos[i], &camInfoTmp[i], sizeof(rk_cam_info_t));
    }


    property_get("ro.sf.hwrotation", property, "0");
    hwrotation = strtol(property,0,0);

#if 0
    if (hwrotation == 0) {
        gCamInfos[0].facing_info.orientation = 0;    /* [email protected]: v0.4.17 */ 
        gCamInfos[1].facing_info.orientation = 0;
    }
#endif
//for test isp,zyc
//  gCamerasNumber =1;
//  gCamInfos[0].facing_info.orientation = 180;
    
camera_get_number_of_cameras_end:
    LOGD("%s(%d): Current board have %d cameras attached.",__FUNCTION__, __LINE__, gCamerasNumber);

	::gettimeofday(&t1, NULL);
	LOGD("meida_profiles_xml_control time (%ld)us\n", (t1.tv_sec*1000000 + t1.tv_usec) - (t0.tv_sec*1000000 + t0.tv_usec));
    return gCamerasNumber;
}

结构解析

存好通用配置版本信息
OTP true
VERSION version1
TRACE_LEVEL --> trace_level[VALUE_MAX]
CAMBOARDXML_PARSER version2
LIBISP version3
ISI version4

由camera_board_profiles空间的getinstance 获得具体的摄像头数量nCamDev
设备向量

for(i)
{
针对每个摄像头
把向量中的每个摄像头的信息保存到本地数组中
}

for(i)
{
针对每一个虚拟的/dev/videon
获得系统文件名/sys和设备文件名/dev
系统文件检查index
设备文件检查设备功能是否支持

}

【安卓6.0 rtl8821cu 蓝牙适配】

【device/common/】
	device/common/bluetooth/libbt-rtk/uart/Android.mk(.bk)
				      .../usb/Android.mk(.bk)

【build】
	core/product.mk
	 	加了一个BOARD_HAVE_BLUETOOTH_RTK 变量
【device/rockchip/common/】
	audio_policy_rk30board.conf
	 	加入了指定采样频率,频道掩膜,格式等
	overlay/packages/apps/Bluetooth/res/values/config.xml
	  	关掉原来的蓝牙的配置文件,使用sink的配置文件
【device/rockchip/rk3288/】
	init.rc
	  	insmod 加入指定芯片编译好的ko文件(system/lib/modules/8188eu(8821cu).ko)									到内核中
【kernel】
   [8723bu代替8188eu]
	arch/arm/boot/dts/rk3288-tb_8846.dts
		向上层指定wifi芯片类型(可兼容)
	arch/arm/configs/rockchip_defconfig			
		增加CONFIG_RTL8723BU = y

   [支持8821cu]
	drivers/bluetooth/rtk_btusb.c(h)
		指定蓝牙需要的固件名称(fw_patch)
   [换回8818eu]
		8723->8818
   [支持8821cuwifi驱动]
		一系列wifi驱动源码 driver/net/wireless/....
   [RK3288支持8821]
	drivers/net/wireless/Kconfig
	drivers/net/wireless/Makefile
	drivers/net/wireless/rockchip_wlan/rtl8821cu/Makefile
		修改编译配置文件,加入wifi驱动
 
   [编译8821和兼容8188wifi驱动为.ko文件]
	arch/arm/configs/rockchip_defconfig
		设置CONFIG_RTL8188EU, CONFIG_RTL8821CU = m
	drivers/net/wireless/Kconfig
	drivers/net/wireless/rockchip_wlan/rtl8821cu/Makefile
		编译出来的模块名叫做 MODULE_NAME := 8821cu

   [支持rlt8821 wifi芯片]
	drivers/net/wireless/rockchip_wlan/wifi_sys/rkwifi_sys_iface.c
		common接口加入8821
	include/linux/rfkill-wlan.h
		加入8821 WiFi选项
	net/rfkill/rfkill-wlan.c
		common接口加入8821


【packages】
   [支持bluetooth a2dp sink mode]
	apps/Bluetooth/AndroidManifest.xml
	  	给用户权限 RECORD_AUDIO
	apps/Bluetooth/src/com/android/bluetooth/a2dp/A2dpSinkStateMachine.java
	  	对蓝牙sink模式的实现
【system】
   [支持bluetooth a2dp sink mode]
	bt/btif/src/btif_media_task.c
	  	换了一个宏函数(APPL_TRACE_EVENT --> APPL_TRACE_ERROR)
	  	取消 如果没有一个设备在监听就忽略数据的功能
	bt/include/bt_target.h
		#define BTA_AV_SINK_INCLUDED TRUE
	bt/udrv/ulinux/uipc.c
		换了一个宏函数(APPL_TRACE_EVENT --> APPL_TRACE_ERROR)
		UIPC_Send
【vendor】
   [为新的wifi蓝牙8821支持固件]
	rockchip/common/bluetooth/bluetooth.mk
		加入rtl8821c的固件编译文件索引
	rockchip/common/bluetooth/realtek/firmware/usb/rtl8821c/device-rtl.mk(编译文件)
		编译文件指明配置config文件和固件fw
							......./rtl8821c_config
							......./rtl8821c_fw
   [支持8188和8821 wifi]
	rockchip/common/wifi/modules/8188eu(8821cu).ko
		把编译好的ko文件放入该文件夹

   [加入hci 蓝牙]
	rockchip/common/rftesttool/broadcom/broadcom.mk
	rockchip/common/rftesttool/rftesttool.mk
		和rk3288相关配置

根据报错信息发现,蓝牙无法打开的原因是缺少文件libbt-vendor_usb.so

在 device/common/ 下找到编译出该so文件的源码usb/和uart/,但是由tig发现被禁用了。
原因是:光韬当时认为rtl8821cu自己会带有usb/,会和原来的device/common/下的系统默认的冲突。

我将光韬原来的那个好的系统里面的两个.so文件拷贝到这个坏的系统中就好了。说明就是缺少so文件。在源码中搜索。并没有找到so文件,说明没有编译出来,思考是被禁用了。应当查看对应的mk等编译文件,看看是不是被禁用了


主要问题有两个,一个是缺少libbt-vendor_usb.so库文件,一个是驱动编译出来有问题
1.缺少libbt-vendor_usb.so库文件
这里由两个来源方法,

一个是从/device/common/bluetooth/libbt-rtk/usb中获得。
这个是系统自带的,原先光韬为了防止和其他地方冲突,选择禁用默认的这个libbt-vendor_usb.so,想要选择8821cu自带的。但是那个8821的文件会导致乱码问题。所以换回这个默认。只要把原来加了后缀的Android.mk文件改回来就行了。

另一个是从/device/rockchip/rk3288里面。
根据8821cu的移植手册,在将rtkbt目录移过来之后,要修改执行rtkbt/system/etc/的文件里面指定usb而不是uart。然后在rk3288目录下的device.mk文件中加入编译选项。但是由于有问题,所以选择取消编译选项

2.驱动编译有两种,一个是内嵌到内核中(y),另一个是以模块形式编译(m)成ko文件,然后自己insmod进入内核。

内嵌到内核:
kernel/arch/arm/configs/rockchip_defconfig中找到CONFIG_BT_RTKBTUSB= y .(这个是Kconfig里指定的名字)
make rockchip_defconfig 更新编译配置文件
然后修改好drivers/bluetooth里面的rtk_btusb.c.h文件,
./mk.sh编译好后可以看到刚刚的文件里面生成了.o文件

以模块形式编译驱动:
kernelarch/arm/configs/rockchip_defconfig中找到CONFIG_BT_RTKBTUSB= m
make rockchip_defconfig
然后修改好驱动文件。
kernel目录下: make modules
可以看到刚刚的文件下多出了.ko文件。
然后将这些ko文件需要放到系统默认的/system/lib/modules目录下。
根据当时vendor下当时的wifi实现,放在和wifi模块驱动的同级目录即可,在rk3288目录下有个init.rc里面有insmod
当编译完整体镜像之后,可以在out目录下找到ko文件
也可以自己在烧录完镜像后手动insmod,都可以。

【安卓目录结构简记】

art:Android Runtime,一种App运行模式,区别于传统的Dalvik虚拟机,旨在提高Android系统的流畅性
bionic:基础C库源代码,Android改造的C/C++库
bootable:Android程序启动导引,适合各种bootloader的通用代码,包括一个recovery目录
build:存放系统编译规则及generic等基础开发包配置
compatibility:Android兼容性计划
cts: Android兼容性测试套件标准
dalvik:Android Dalvik虚拟机相关内容
developers:Android开发者参考文档
development: Android应用开发基础设施相关
device:Android支持的各种设备及相关配置
external:Android中使用的外部开源库
frameworks:应用程序框架,Android系统核心部分,由Java和C++编写
hardware:硬件适配接口
kernel:Linux Kernel,不过Android默认不提供,需要单独下载,只有一个tests目录
libcore:Android Java核心类库
libnativehelper:Android动态库,实现JNI库的基础
packages:应用程序包
pdk:Plug Development Kit 的缩写,本地开发套件
platform_testing:Android平台测试程序
prebuilts:x86和arm架构下预编译的一些资源
sdk:Android的Java层sdk
system:Android底层文件系统库、应用和组件
test:Android Vendor测试框架
toolchain:Android工具链文件
tools:Android工具文件
Android.bp:Android7.0开始代替Android.mk文件,它是告诉ndk将jni代码编译成动态库的一个脚本
Makefile:全局Makefile文件,用来定义编译规则

【Android 6 状态栏隐藏】

diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 8eaf6a8..ea6efde 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1024,6 +1024,10 @@ public class StatusBar extends SystemUI implements DemoMode,
         filter.addAction("com.keenon.changeBarHideStatus");
         filter.addAction("com.keenon.usbModeSet");
         // Keenon wugt add end
+        // Keenon liangji add start
+        filter.addAction("com.keenon.changeBarHideStatus_enable");
+        filter.addAction("com.keenon.changeBarHideStatus_disable");
+        // Keenon liangji add end
         context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
 
         IntentFilter demoFilter = new IntentFilter();
@@ -1409,6 +1413,28 @@ public class StatusBar extends SystemUI implements DemoMode,
         }
     }
 
+    private void changeBarHideStatus_enable()
+    {
+        Log.d("liangji: Keenon","changeBarHideStatus_enable");
+        Settings.System.putInt(mContext.getContentResolver(),Settings.System.SYSTEMBAR_HIDE,1);
+        int get_int = 3;
+        get_int = Settings.System.getInt(mContext.getContentResolver(),Settings.System.SYSTEMBAR_HIDE,0); 
+        String text = String.valueOf(get_int);
+        Log.i("liangji:Settings.System.SYSTEMBAR_HIDE = ", text);
+        removeBar();
+    }
+
+    private void changeBarHideStatus_disable()
+    {
+        Log.d("liangji: Keenon","changeBarHideStatus_disable");
+        Settings.System.putInt(mContext.getContentResolver(),Settings.System.SYSTEMBAR_HIDE,0);
+        int get_int = 3;
+        get_int = Settings.System.getInt(mContext.getContentResolver(),Settings.System.SYSTEMBAR_HIDE,0); 
+        String text = String.valueOf(get_int);
+        Log.i("liangji:Settings.System.SYSTEMBAR_HIDE = ", text);
+        restoreBar();
+    }
+
     private void usbModeSet()
     {
         int usbmode = Settings.System.getInt(mContext.getContentResolver(),Settings.System.USB_OTG_MODE, 1);
@@ -2753,6 +2779,16 @@ public class StatusBar extends SystemUI implements DemoMode,
                 usbModeSet();
             }
             // Keenon wugt add end
+            // Keenon liangji add start
+            else if("com.keenon.changeBarHideStatus_enable".equals(action))
+            {
+                changeBarHideStatus_enable();
+            }
+            else if("com.keenon.changeBarHideStatus_disable".equals(action))
+            {
+                changeBarHideStatus_disable();
+            }
+            // Keenon liangji add end
         }
     };
 

自己发广播测试,用am指令

发送
am broadcast -a com.keenon.changeBarHideStatus_global

接受
logcat |grep liangji
liangji:Settings.system.SYSTEMBAR_HIDE

【python ssh 免密连接,dd更新内核】

项目文件链接

ssh传输文件和执行执行的python脚本: repair.py

# -*- coding: UTF-8 -*-

import os
import re
import sys
import paramiko
from scp import SCPClient
import time
import tkinter
import tkinter.messagebox

PWD = os.path.abspath(".")   
IP = "192.168.64.20"
PORT = "22"
USER = "peanut"
PSWD = "keenonrobot"
REMOTE_PATH = "/home/peanut/boot_v1.0.3"
LOCAL_PATH = ""

def show_info(msg):
    top = tkinter.Tk()
    top.geometry("0x0+999999+0")
    tkinter.messagebox.showinfo("Info", msg)
    top.destroy

def show_warn(msg):
    top = tkinter.Tk()
    top.geometry("0x0+999999+0")
    tkinter.messagebox.showwarning("Warn", msg)
    top.destroy

def upload_file():
    try:
        #创建SSHClient 实例对象
        ssh = paramiko.SSHClient()
        # 调用方法,表示没有存储远程机器的公钥,允许访问
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        # 连接远程机器,地址,端口,用户名密码
        print("ssh connect")
        ssh.connect(IP, PORT, USER, PSWD, timeout=20)
        print("ssh connect over")
    except Exception as e:
        show_warn("unable to connect to port 22 on 192.168.64.20")
        ssh.close()
        sys.exit(1)

    #创建存放升级文件目录
    cmd = 'mkdir /home/peanut/boot_v1.0.3;cd /home/peanut/boot_v1.0.3;'
    print("ssh exec cmd start")
    ssh.exec_command(cmd)
    print("ssh exec cmd over")
    #上传升级文件
    scp = SCPClient(ssh.get_transport(), socket_timeout=20)
    if os.path.exists(PWD):
        for root, dirs, files in os.walk(PWD):
            for file in files:
                LOCAL_PATH = ""
                if re.search("boot", file): #用boot进行正则匹配
                    LOCAL_PATH = os.path.join(PWD, file) #加入拥有boot关键字的file文件名
                    scp.put(LOCAL_PATH, REMOTE_PATH) #scp 发送
                    print("liangji_send: ",file)
                    time.sleep(3)
                    ssh.exec_command('chmod 777 -R /home/peanut/boot_v1.0.3/*')
                elif re.search("update",file):
                    LOCAL_PATH = os.path.join(PWD, file) #加入拥有update关键字的file文件名
                    scp.put(LOCAL_PATH, REMOTE_PATH) #scp 发送
                    print("liangji_send: ",file)
                    time.sleep(3)
                    ssh.exec_command('chmod 777 -R /home/peanut/boot_v1.0.3/*')

    cmd = 'sudo /home/peanut/boot_v1.0.3/update.sh;sleep 3;rm -rf /home/peanut/boot_v1.0.3;sudo reboot;'
    print("ssh exec update_cmd start")
    ssh.exec_command(cmd)
    print("ssh exec update_cmd over")

    scp.close()
    ssh.close()

def update_ros():
    try:
        ssh_sec = paramiko.SSHClient()
        ssh_sec.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh_sec.connect(IP, PORT, USER, PSWD, timeout=20)
    except Exception as e:
        show_warn("unable to connect to port 22 on 192.168.64.20")
        ssh_sec.close()
        sys.exit(1)

    session = ssh_sec.get_transport().open_session()
    session.set_combine_stderr(True)
    session.get_pty()
    #session.exec_command("sudo /home/peanut/keenon_update_ros/robotInstall.sh >> /home/peanut/keenon_update_ros/robot_install_sh.log 2>&1")
    session.exec_command("sudo /home/peanut/keenon_update_ros/robotInstall.sh")
    stdin = session.makefile('wb', -1)
    stdout = session.makefile('rb', -1)
    stdin.write(PSWD + '\n')
    stdin.flush()
    
    print(stdout.readlines())

    session.close()
    ssh_sec.close()

def query_ros():
    try:
        ssh_thi = paramiko.SSHClient()
        ssh_thi.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh_thi.connect(IP, PORT, USER, PSWD, timeout=20)
    except Exception as e:
        show_warn("unable to connect to port 22 on 192.168.64.20")
        ssh_thi.close()
        sys.exit(1)

    cmd_thi = 'cat /home/peanut/keenon_update_ros/updated_ros'
    stdin, stdout, stderr = ssh_thi.exec_command(cmd_thi)
    list_thi = stdout.readlines()

    ssh_thi.close()
    return list_thi

if __name__ == '__main__':
    upload_file()
    # update_ros()

    # time.sleep(60)
    # flag = 0
    # list = query_ros()
    # list_size = len(list)
    # while True:
    #     if list_size == 1:
    #         if re.search("succeeded", list[0].strip()):
    #             show_info("ros upgrade succeeded!")
    #             break
    #     elif list_size < 1:
    #         time.sleep(60)
    #         list = query_ros()
    #         list_size = len(list)
    #         flag = flag +1
        
    #     if flag >= 4:
    #         show_warn("ros upgrade failed!")
    #         break

更新内核脚本 update.sh

#! /bin/bash

dd if=/home/peanut/boot_v1.0.3/boot.img of=/dev/mmcblk1p3 bs=4k

内核文件 boot.img

【诊断工具(底盘+蓝海雷达+lora+调度模块+科力雷达+立体视觉+乐动雷达)】

诊断工具v1.0.0文件链接

支持自动关闭ros和robot
支持蓝海雷达诊断
支持底盘诊断

【串口 自收自发 测试demo】

serial_test

【多线程 测试demo】

pthread_test

【蓝海雷达 测试demo】

lidar_test

【计时器 测试demo】

time_test

【文件修改时间 测试demo】

file_time_test

【udp client请求server发送 测试demo】
【乐动雷达 测试demo】

【镜像解包afptool】

【record】_第2张图片

或者使用RK3399 SDK的tools里面的解压工具解包

【android12 永久隐藏状态栏】

package/

From d1321e17d776c56830f0df232e2ec20132814ead Mon Sep 17 00:00:00 2001
From: liangji <[email protected]>
Date: Fri, 18 Nov 2022 16:11:30 +0800
Subject: [PATCH] feat: add checkbox to hide status bar

Signed-off-by: liangji <[email protected]>
---
 res/values-zh-rCN/strings.xml                 |  1 +
 res/values/strings.xml                        |  3 +++
 res/xml/display_settings.xml                  |  6 +++++
 src/com/android/settings/DisplaySettings.java | 39 +++++++++++++++++++++++++++
 4 files changed, 49 insertions(+)

diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index fe72d85..e5e5ec9 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -5599,6 +5599,7 @@
     <string name="dialog_getting_screen_info">"正在获取屏幕信息..."</string>
     <string name="dialog_update_resolution">"切换分辨率..."</string>
     <string name="dialog_wait_screen_connect">"更新信息到设备,请稍等..."</string>
+    <string name="systembar_hide_title">永久隐藏工具栏</string>
 
     <!--screenshot settings-->
     <string name="screenshot">截屏</string>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a8f6864..e9a9e40 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -13714,4 +13714,7 @@
     <string name="dialog_getting_screen_info">getting screen info...</string>
     <string name="dialog_update_resolution">Updating resolution...</string>
     <string name="dialog_wait_screen_connect">please wait while updating info to the device...</string>
+    
+    <!--keenon liangji add for hide systembar-->
+    <string name="systembar_hide_title">Always_hide_the_status_bar</string>
 </resources>
diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml
index 1d17f59..7a32317 100644
--- a/res/xml/display_settings.xml
+++ b/res/xml/display_settings.xml
@@ -160,5 +160,11 @@
             android:title="@string/hdmi_settings"
             settings:keywords="@string/hdmi_settings"
             android:fragment="com.android.settings.display.HdmiSettings" />
+
     </PreferenceCategory>
+
+    <CheckBoxPreference
+        android:key="systembar_hide"
+        android:title="@string/systembar_hide_title"/>
+
 </PreferenceScreen>
diff --git a/src/com/android/settings/DisplaySettings.java b/src/com/android/settings/DisplaySettings.java
index 6ce9ff5..d59c7ca 100644
--- a/src/com/android/settings/DisplaySettings.java
+++ b/src/com/android/settings/DisplaySettings.java
@@ -35,6 +35,13 @@ import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.search.SearchIndexable;
 
+//keenon liangji add start
+import androidx.preference.Preference;
+import androidx.preference.CheckBoxPreference;
+import android.content.Intent;
+import android.provider.Settings;
+//keenon liangji add end
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -43,6 +50,12 @@ public class DisplaySettings extends DashboardFragment {
     private static final String TAG = "DisplaySettings";
     private static final String KET_HDMI_SETTINGS = "hdmi_settings";
 
+    //keenon liangji add start
+    private static final String KEY_SYSTEMBAR_HIDE = "systembar_hide";
+
+    private CheckBoxPreference mSystemBarHide;
+    //keenon liangji add end
+
     @Override
     public int getMetricsCategory() {
         return SettingsEnums.DISPLAY;
@@ -61,6 +74,14 @@ public class DisplaySettings extends DashboardFragment {
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
+        
+        //keenon liangji add start
+        mSystemBarHide = (CheckBoxPreference) findPreference(KEY_SYSTEMBAR_HIDE);
+        mSystemBarHide.setChecked(Settings.System.getInt(getContentResolver(),Settings.System.SYSTEMBAR_HIDE,
+                    0)==1);
+        //keenon liangji add end
+
+
     }
 
     @Override
@@ -97,4 +118,22 @@ public class DisplaySettings extends DashboardFragment {
                     return buildPreferenceControllers(context, null);
                 }
             };
+
+    //keenon liangji add start
+    @Override
+    public boolean onPreferenceTreeClick(Preference preference){
+        if(preference == mSystemBarHide)
+        {
+            Settings.System.putInt(getContentResolver(), Settings.System.SYSTEMBAR_HIDE,
+                    mSystemBarHide.isChecked() ? 1 : 0);
+            Intent i = new Intent("com.keenon.changeBarHideStatus");
+            getActivity().sendBroadcast(i);
+        }
+        return super.onPreferenceTreeClick(preference);
+    }
+    //keenon liangji add end
+
+
+
+
 }
-- 
2.7.4

framework/base/

https://blog.csdn.net/ljt2724960661/article/details/82779519
https://blog.csdn.net/Bill_xiao/article/details/108244267

From e546af745cc5f189594294fb32e802709378d776 Mon Sep 17 00:00:00 2001
From: liangji <[email protected]>
Date: Mon, 21 Nov 2022 17:53:47 +0800
Subject: [PATCH] feat: support always hide status bar

Signed-off-by: liangji <[email protected]>
---
 core/java/android/provider/Settings.java           |  8 ++++
 packages/SettingsProvider/res/values/defaults.xml  |  3 ++
 .../android/providers/settings/DatabaseHelper.java |  4 ++
 .../systemui/statusbar/phone/StatusBar.java        | 55 ++++++++++++++++++++++
 .../window/StatusBarWindowController.java          | 12 +++++
 5 files changed, 82 insertions(+)

diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 695e407..1d9e0a4 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4900,6 +4900,14 @@ public final class Settings {
         public static final String SCREENSHOT_BUTTON_SHOW = "screenshot_button_show";
 
         /**
+         * keenon liangji: hide system bar
+         *
+         * @hide
+         */
+        public static final String SYSTEMBAR_HIDE="systembar_hide";
+
+
+        /**
          * Whether the phone vibrates when it is ringing due to an incoming call. This will
          * be used by Phone and Setting apps; it shouldn't affect other apps.
          * The value is boolean (1 or 0).
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index aba8038..e2e7d8d 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -265,4 +265,7 @@
     <!-- should show the screenshot button default -->
     <integer name="def_screenshot_button_show">0</integer>
 
+    <!-- keenon liangji hide systembar -->
+    <bool name="def_systembar_hide">false</bool>
+
 </resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 26d8b0d..2ba2445 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -2280,6 +2280,10 @@ class DatabaseHelper extends SQLiteOpenHelper {
             loadIntegerSetting(stmt, Settings.System.SCREENSHOT_BUTTON_SHOW,
                     R.integer.def_screenshot_button_show);
 
+            //keenon liangji add start
+            loadIntegerSetting(stmt, Settings.System.SYSTEMBAR_HIDE,
+                    R.bool.def_systembar_hide);
+            //keenon liangji add end
             /*
              * IMPORTANT: Do not add any more upgrade steps here as the global,
              * secure, and system settings are no longer stored in a database
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index a6fb317..b471d07 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1025,6 +1025,10 @@ public class StatusBar extends SystemUI implements
 
         // end old BaseStatusBar.start().
 
+        //keenon liangji add start
+        changeBarHideStatus();
+        //keenon liangji add end
+
         // Lastly, call to the icon policy to install/update all the icons.
         mIconPolicy.init();
 
@@ -1406,6 +1410,9 @@ public class StatusBar extends SystemUI implements
         filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
         filter.addAction(Intent.ACTION_SCREEN_OFF);
         filter.addAction(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG);
+        //keenon liangji add start
+        filter.addAction("com.keenon.changeBarHideStatus");
+        //keenon liangji add end
         mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, null, UserHandle.ALL);
     }
 
@@ -2140,6 +2147,7 @@ public class StatusBar extends SystemUI implements
                     event.getAction() == MotionEvent.ACTION_CANCEL;
             setInteracting(StatusBarManager.WINDOW_STATUS_BAR, !upOrCancel || mExpandedVisible);
         }
+
     }
 
     boolean isSameStatusBarState(int state) {
@@ -2667,6 +2675,10 @@ public class StatusBar extends SystemUI implements
             else if (DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG.equals(action)) {
                 mQSPanelController.showDeviceMonitoringDialog();
             }
+            else if("com.keenon.changeBarHideStatus".equals(action))
+            {
+                changeBarHideStatus();
+            }
             Trace.endSection();
         }
     };
@@ -3898,6 +3910,49 @@ public class StatusBar extends SystemUI implements
         KeyboardShortcuts.dismiss();
     }
 
+    //keenon liangji add start
+    private boolean mBarIsAdd = true;
+
+    private void removeBar(){
+        Log.d("Keenon_liangji","removeBar");
+
+        mStatusBarWindowController.hideStatusBar();
+        mNavigationBarController.onDisplayRemoved(mDisplayId);
+
+        mBarIsAdd = false;
+    }
+
+    private void restoreBar(){
+        Log.d("Keenon_liangji","restoreBar");
+        if (mBarIsAdd==true)
+            return;
+
+        ViewGroup tempStatusBar = mStatusBarWindowController.getStatusBarWindowView();
+        if(tempStatusBar != null){
+            tempStatusBar.setVisibility(View.VISIBLE);
+            requestNotificationUpdate("StatusBar state changed");
+            checkBarModes();
+        }
+
+        createNavigationBar(null);
+        mBarIsAdd = true;
+    }
+
+    private void changeBarHideStatus()
+    {
+        Log.d("Keenon_liangji","changeBarHideStatus");
+        boolean hide_systembar = Settings.System.getInt(mContext.getContentResolver(),Settings.System.SYSTEMBAR_HIDE,0)==1;
+        if(hide_systembar){
+            removeBar();
+            //Settings.System.putInt(mContext.getContentResolver(),Settings.System.SYSTEMBAR_HIDE,1);
+        }
+        else {
+            restoreBar();
+        }
+    }
+
+    //keenon liangji add end
+
     /**
      * Dismiss the keyguard then execute an action.
      *
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java
index 85a6cd2..e5af7e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java
@@ -119,6 +119,18 @@ public class StatusBarWindowController {
         if (DEBUG) Log.v(TAG, "defineSlots");
     }
 
+    //keenon liangji add start
+    public void hideStatusBar() {
+        mStatusBarWindowView.setVisibility(View.GONE);
+        if (DEBUG) Log.v(TAG, "defineSlots");
+    }
+
+    public ViewGroup getStatusBarWindowView(){
+        return mStatusBarWindowView;
+    }
+
+    //keenon liangji add end
+
     /**
      * Adds the status bar view to the window manager.
      */
-- 
2.7.4


总结:
java中每个package表示一个命名空间。
import后面的一长串,只有最后一个表示类名,前面的表示包名。

【Android6 system.img定制化修改开机动画】

  1. 获取整机镜像文件
  2. 利用RKTools里面的解包工具,将其解包(不能打包,因为会出错)
  3. 将解包后的system.img传到ubuntu主机,挂载
  4. 新建一个文件夹,将system.img挂载后的目录里面的所有的内容cp -a 到新的文件夹(因为原挂载文件夹无法修改)
  5. 将新的文件夹里面的media/bootanimation.zip替换成我们自己的bootanimation.zip。
  6. 将该新的文件夹压缩传回来,这个是我们新的system.img
  7. 使用从mkupdateimg.sh脚本中抠出来的打包新的安卓system.img方法进行打包(liangji_mksystem.sh),会在liangji_system/下生成新的system.img。
  8. kernel/中可以将logo.bmp(8位),logo_kernel.bmp(24位)替换为自己的图片。bmp图片转位数可以用
https://online-converting.com/image/convert2bmp/#
  1. 将新的resource.img和新的system.img 替换rockdev里面, 同时将RKTools解包工具里面的其他需要的部分替换到rockdev/里面。
  2. ./build_keenon -u 直接打包生成新的整机镜像。

liangji_mksystem.sh

#! /bin/bash

source build/envsetup.sh
lunch 13

IMAGE_PATH=liangji_system

system_size=`ls -l $OUT/system.img | awk '{print $5;}'`
[ $system_size -gt "0" ] || { echo "Please make first!!!" && exit 1; }
MAKE_EXT4FS_ARGS=" -L system -S $OUT/root/file_contexts -a system $IMAGE_PATH/system.img liangji_system/system_new"
ok=0
while [ "$ok" = "0" ]; do
	make_ext4fs -l $system_size $MAKE_EXT4FS_ARGS >/dev/null 2>&1 &&
	tune2fs -c -1 -i 0 $IMAGE_PATH/system.img >/dev/null 2>&1 &&
	ok=1 || system_size=$(($system_size + 5242880))
done
e2fsck -fyD $IMAGE_PATH/system.img >/dev/null 2>&1 || true


【iperf 测试工控机和ui板网络传输】

iperf工具下载(x86ubuntu + android6)

  1. 丢包延时测试,ping
  2. iperf 测试 tcp 吞吐量(iperf默认选择tcp测试)
#客户端
iperf -c 192.168.64.10 -t 300 -i 1 -P 4

#服务器
iperf -s -i 1
  1. iperf 测试udp 抖动测试
#客户端
iperf -c 192.168.64.10 -u -t 100 -b 100m

#服务器
iperf -s -i 1 -u

【tcpdump 抓包测试】

tcpdump -i br0 -w save.pcap

【RK3288 android6 lvds+edp双屏异显解析】

https://www.litreily.top/2021/06/18/dual-lcd/

【RK3288 android10 lvds+edp 双屏异显】

  1. 修改dts配置,(先能够实现单个屏幕点亮,然后是两个屏幕)
  2. 修改mk.sh
  3. 增加build.prop配置

dts修改
rk3288-evb-android-act8846-dual-screen-keenon.dtsi修改

/*
 * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
 *
 * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 */

/dts-v1/;
#include "rk3288-evb-android-act8846-keenon.dtsi"

/ {
	lvds_panel {
		status = "okay";
		compatible = "simple-panel";
		backlight = <&backlight>;
		//enable-gpios = <&gpio7 RK_PA4 GPIO_ACTIVE_HIGH>;
		pinctrl-0 = <&lcd_cs>;
		power-supply = <&vcc_lcd>;
		//prepare-delay-ms = <20>;
		//enable-delay-ms = <20>;
		/*
		 * MEDIA_BUS_FMT_RGB666_1X7X3_SPWG  - "jeida-18"
		 * MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA - "jeida-24"
		 * MEDIA_BUS_FMT_RGB888_1X7X4_SPWG  - "vesa-24"
		 */
		bus-format = <MEDIA_BUS_FMT_RGB888_1X7X4_SPWG>;

		display_timings:display-timings {
			native-mode = <&timing0>;

			timing0: timing0 {
			clock-frequency = <52000000>;
			hactive = <1024>;
			vactive = <600>;
			hfront-porch = <160>;
			hsync-len = <10>;
			hback-porch = <150>;
			vfront-porch = <12>;
			vsync-len = <1>;
			vback-porch = <22>;
			hsync-active = <0>;
			vsync-active = <0>;
			de-active = <0>;
			pixelclk-active = <1>;
			};
			// 10.1" 1280x800 LVDS panel
			timing4: timing4 {
			//screen-type = ;
			//lvds-format = ;
			//out-face    = ;
			//color-mode = ;
			clock-frequency = <65000000>;
			hactive = <1280>;
			vactive = <800>;
			hback-porch = <100>;
			hfront-porch = <120>;
			vback-porch = <10>;
			vfront-porch = <10>;
			hsync-len = <3>;
			vsync-len = <3>;
			hsync-active = <0>;
			vsync-active = <0>;
			de-active = <0>;
			pixelclk-active = <1>;
			swap-rb = <0>;
			swap-rg = <0>;
			swap-gb = <0>;
			};
		};
		port {
			panel_in_lvds: endpoint {
				remote-endpoint = <&lvds_out_panel>;
			};
		};
	};

edp_panel {
	status = "okay";
	compatible ="simple-panel";
	backlight = <&backlight>;
	enable-gpios = <&gpio7 RK_PA4 GPIO_ACTIVE_HIGH>;
	//prepare-delay-ms = <120>;
    power-supply = <&vcc_lcd>;
	pinctrl-0 = <&lcd_cs>;
        //delay,prepare = <120>;
        disp_timings: display-timings {
                native-mode = <&timing1>;
                //liangji add 1
			    timing2: timing2 {
			    clock-frequency = <138700000>;
			    hactive = <1920>;
			    vactive = <1080>;
			    hfront-porch = <120>;
			    hsync-len = <5>;
			    hback-porch = <35>;
			    vfront-porch = <20>;
			    vsync-len = <2>;
			    vback-porch = <10>;
			    hsync-active = <0>;
			    vsync-active = <0>;
			    de-active = <0>;
			    pixelclk-active = <1>;
			    };

                //11.6 1920x1080 edp panel W3
                timing1: timing1 {
			    clock-frequency = <152600000>;
			    hactive = <1920>;
			    vactive = <1080>;
			    hfront-porch = <120>;
			    hsync-len = <160>;
			    hback-porch = <30>;
			    vfront-porch = <28>;
			    vsync-len = <24>;
			    vback-porch = <8>;
			    hsync-active = <0>;
			    vsync-active = <0>;
			    de-active = <0>;
			    pixelclk-active = <1>;
			    };
        };
		port {
			panel_in_edp: endpoint {
				remote-endpoint = <&edp_out_panel>;
			};
		};
};


};

&lvds {
	status = "okay";
	ports {
		port@1 {
			reg = <1>;

			lvds_out_panel: endpoint {
				remote-endpoint = <&panel_in_lvds>;
			};
		};
	};
};

&video_phy {
	status = "okay";
};

&lvds_in_vopb {
	status = "disabled";
};

&lvds_in_vopl {
	status = "okay";
};

&vopl_out_lvds {
    status = "okay";
};

&vopb_out_lvds {
    status = "disabled";
};

&route_lvds {
	connect = <&vopl_out_lvds>;
	status = "okay";
};

&goodix_ts {
	status = "okay";
};
///
&edp {
	force-hpd;
	status = "okay";
	ports {
		port@1 {
			reg = <1>;

			edp_out_panel: endpoint {
				remote-endpoint = <&panel_in_edp>;
			};
		};
	};
};

&edp_phy {
	status = "okay";
};

&edp_in_vopb {
	//status = "disabled";
    status = "okay";
};

&edp_in_vopl {
	//status = "okay";
	status = "disabled";
};

&vopl_out_edp {
    status = "disabled";
};

&vopb_out_edp {
    status = "okay";
};

&route_edp {
	//connect = <&vopl_out_edp>;
	connect = <&vopb_out_edp>;
	status = "disabled";
};

&ilitek {
	status = "okay";
};

修改mk.sh
指定自己的dts文件

#!/bin/bash

echo "Start build kernel"

source ../build/envsetup.sh
KERNEL_ARCH=arm
KERNEL_DEFCONFIG="rockchip_defconfig android-10.config"
KERNEL_DTS="rk3288-evb-android-act8846-dual-screen-keenon"
#KERNEL_DTS="rk3288-evb-android-act8846-edp-keenon"

[ $# -eq 1 ] && {
    if [ $1 = "lvds7" ] || [ $1 = "lvds" ]; then
        KERNEL_DTS="rk3288-evb-android-act8846-lvds7-keenon"
    elif [ $1 = "lvds101" ]; then
        KERNEL_DTS="rk3288-evb-android-act8846-lvds101-keenon"
    fi
}

echo "KERNEL_DTS:"${KERNEL_DTS}

BUILD_JOBS=16
make ARCH=$KERNEL_ARCH $KERNEL_DEFCONFIG
make ARCH=$KERNEL_ARCH BOOT_IMG=../rockdev/Image-rk3288_Android10/boot.img  $KERNEL_DTS.img -j$BUILD_JOBS

if [ $? -eq 0 ]; then
    echo "Build kernel ok!"
else
    echo "Build kernel failed!"
    exit 1
fi

(临时)修改build.prop配置

https://blog.csdn.net/feiz3020/article/details/108767984?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167098089716800186557478%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=167098089716800186557478&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-2-108767984-null-null.142v68control,201v4add_ask,213v2t3_esquery_v2&utm_term=%E4%BF%AE%E6%94%B9build.prop%E9%87%8D%E5%90%AF&spm=1018.2226.3001.4187

增加两条
vendor.hwc.device.primary=LVDS
vendor.hwc.device.extend=eDP

(永久)修改build.prop配置

From eb72b8bba0e41fcf4426c31292da40365e9c6340 Mon Sep 17 00:00:00 2001
From: liangji <[email protected]>
Date: Wed, 14 Dec 2022 17:28:02 +0800
Subject: [PATCH] feat: enable t5pro dual-screen

Change-Id: I2ec93d7e119cf720942f75f36847667f8b6ffe44
Signed-off-by: liangji <[email protected]>
---
 device.mk | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/device.mk b/device.mk
index f4a8e28..48e3ae0 100755
--- a/device.mk
+++ b/device.mk
@@ -170,4 +170,6 @@ PRODUCT_PROPERTY_OVERRIDES += \
                 ro.com.android.mobiledata=true \
                 ro.telephony.default_network=9 \
                 persist.logd.size=4194304 \
-                ro.rk.displayd.enable=false
+                ro.rk.displayd.enable=false \
+                vendor.hwc.device.primary=LVDS \
+                vendor.hwc.device.extend=eDP \
-- 
2.7.4

【RK3399 android10 新增分区(nanopc)】

  1. 了解安卓各个分区,镜像的关系,文件夹
  • 分区是指的磁盘上的分区,由parameter.txt中的地址指出。

  • 分区所在的磁盘空间上烧录镜像文件。
    【record】_第3张图片

  • 每个分区上的镜像文件,都有其文件系统,就是格式。由他来确定如何从磁盘的存储块来映射操作具体的文件。

  • 开机后,镜像所在的分区被挂载到根文件系统,让用户通过访问文件夹的方式访问分区。

  • system.img,包括了sdk中的frameworks/,hardware/,device/等文件夹。

  • 根目录下的/system,是sdk中out/目录下的/system,并不是system.img

  1. 了解安卓启动加载分区流程
  • bootloader分区—>boot分区—>init(system分区)
  • boot分区加载分为加载kernel,准备挂载文件系统
  • init(system分区)加载init.rc,完成系统加载,包括system_service进程
  1. 新增分区oem

system/core/rootdir/init.rc开机创建文件夹oem,并给权限。用于挂载

diff --git a/system/core/rootdir/init.rc b/system/core/rootdir/init.rc
index 0fa9feb..c125971 100644
--- a/system/core/rootdir/init.rc
+++ b/system/core/rootdir/init.rc
@@ -215,6 +215,13 @@ on init
     chown system system /dev/cpuset/top-app/tasks
     chown system system /dev/cpuset/restricted/tasks

+    #keenon liangji add
+
+    chown system system /oem
+    chmod 0777 /oem
+
+    #keenon liangji add end
+
     # set system-background to 0775 so SurfaceFlinger can touch it
     chmod 0775 /dev/cpuset/system-background

device/rockchip/rk3399/nanopc-t4/fstab.in
device/rockchip/rk3399/fstab.rk30board
增加挂载信息,把块设备中的oem分区挂载到/oem目录

diff --git a/device/rockchip/rk3399/nanopc-t4/fstab.in b/device/rockchip/rk3399/nanopc-t4/fstab.in
index 866c23a..f03797f 100644
--- a/device/rockchip/rk3399/nanopc-t4/fstab.in
+++ b/device/rockchip/rk3399/nanopc-t4/fstab.in
@@ -12,6 +12,10 @@ ${_block_prefix}product         /product        ext4      ro,barrier=1 ${_flags}
 /dev/block/by-name/cache        /cache          ext4      noatime,nodiratime,nosuid,nodev,noauto_da_alloc,discard wait,check
 /dev/block/by-name/misc         /misc           emmc      defaults     defaults

+#keenon liangji add
+/dev/block/by-name/oem        /oem          ext4      rw,noatime,nodiratime,nosuid,nodev,noauto_da_alloc,discard wait,check
+#keenon liangji add end
+
 /dev/block/zram0                none            swap      defaults     zramsize=40%

 /devices/platform/*usb*         auto            vfat      defaults     voldmanaged=usb:auto




diff --git a/device/rockchip/rk3399/fstab.rk30board b/device/rockchip/rk3399/fstab.rk30board
index 30409ed..b11510a 100644
--- a/device/rockchip/rk3399/fstab.rk30board
+++ b/device/rockchip/rk3399/fstab.rk30board
@@ -4,7 +4,7 @@
 # specify MF_CHECK, and must come before any filesystems that do specify MF_CHECK

 /dev/block/by-name/system         /                   ext4      ro,barrier=1               wait,avb
-/dev/block/by-name/oem            /oem                ext4      ro,noatime,nodiratime,noauto_da_alloc                                  wait,check
+/dev/block/by-name/oem            /oem                ext4      rw,noatime,nodiratime,nosuid,nodev,noauto_da_alloc,discard                                  wait,check
 /dev/block/by-name/cache          /cache              ext4      noatime,nodiratime,nosuid,nodev,noauto_da_alloc,discard                wait,check
 /dev/block/by-name/metadata       /mnt/vendor/metadata           ext4      noatime,nodiratime,nosuid,nodev,noauto_da_alloc,discard                wait
 /dev/block/by-name/misc         /misc               emmc      defaults     defaults

device/rockchip/rk3399/nanopc-t4/parameter.txt修改oem分区的物理地址和大小

diff --git a/device/rockchip/rk3399/nanopc-t4/parameter.txt b/device/rockchip/rk3399/nanopc-t4/parameter.txt
index a43a62f..406c238 100644
--- a/device/rockchip/rk3399/nanopc-t4/parameter.txt
+++ b/device/rockchip/rk3399/nanopc-t4/parameter.txt
@@ -8,4 +8,4 @@ MACHINE: 3399
 CHECK_MASK: 0x80
 PWR_HLD: 0,0,A,0,1
 TYPE: GPT
-CMDLINE: mtdparts=rk29xxnand:0x00002000@0x00004000(uboot),0x00002000@0x00006000(trust),0x00002000@0x00008000(misc),0x00002000@0x0000a000(dtb),0x00002000@0x0000c000(dtbo),0x00002000@0x0000e000(vbmeta),0x00010000@0x00010000(boot),0x00030000@0x00020000(recovery),0x00038000@0x00050000(backup),0x00002000@0x00088000(security),0x000c0000@0x0008a000(cache),0x00008000@0x0014a000(metadata),0x00002000@0x00152000(frp),0x00614000@0x00154000(super),-@0x00768000(userdata:grow)
+CMDLINE: mtdparts=rk29xxnand:0x00002000@0x00004000(uboot),0x00002000@0x00006000(trust),0x00002000@0x00008000(misc),0x00002000@0x0000a000(dtb),0x00002000@0x0000c000(dtbo),0x00002000@0x0000e000(vbmeta),0x00010000@0x00010000(boot),0x00030000@0x00020000(recovery),0x00038000@0x00050000(backup),0x00002000@0x00088000(security),0x000c0000@0x0008a000(cache),0x00008000@0x0014a000(metadata),0x00002000@0x00152000(frp),0x00614000@0x00154000(super),0x01000000@0x00768000(oem),-@0x01768000(userdata:grow)

device/rockchip/rk3399/nanopc-t4/BoardConfig.mk ,增加oem分区大小,并关闭AB分区选项

diff --git a/device/rockchip/rk3399/nanopc-t4/BoardConfig.mk b/device/rockchip/rk3399/nanopc-t4/BoardConfig.mk
index a0f1420..f253159 100644
--- a/device/rockchip/rk3399/nanopc-t4/BoardConfig.mk
+++ b/device/rockchip/rk3399/nanopc-t4/BoardConfig.mk
@@ -24,7 +24,7 @@ BOARD_INCLUDE_DTB_IN_BOOTIMG :=
 endif

 # AB image definition
-BOARD_USES_AB_IMAGE := true
+BOARD_USES_AB_IMAGE := false

 ifeq ($(strip $(BOARD_USES_AB_IMAGE)), true)
     AB_OTA_UPDATER := true
@@ -42,3 +42,7 @@ endif
 ifeq ($(BOARD_HAS_GPS),true)
 DEVICE_MANIFEST_FILE += device/rockchip/rk3399/nanopc-t4/mgnss.xml
 endif
+
+#keenon liangji add
+BOARD_OEM_SIZE := 8589934592
+#keenon liangji add end

device/rockchip/common/BoardConfig.mk 增加自动读取分区大小

diff --git a/device/rockchip/common/BoardConfig.mk b/device/rockchip/common/BoardConfig.mk
index b5dc59d..acf2e40 100644
--- a/device/rockchip/common/BoardConfig.mk
+++ b/device/rockchip/common/BoardConfig.mk
@@ -123,6 +123,7 @@ ifeq ($(strip $(USE_DEFAULT_PARAMETER)), true)
   BOARD_BOOTIMAGE_PARTITION_SIZE := $(shell python device/rockchip/common/get_partition_size.py $(RK_PARAMETER) boot)
   BOARD_DTBOIMG_PARTITION_SIZE := $(shell python device/rockchip/common/get_partition_size.py $(RK_PARAMETER) dtbo)
   BOARD_RECOVERYIMAGE_PARTITION_SIZE := $(shell python device/rockchip/common/get_partition_size.py $(RK_PARAMETER) recovery)
+  BOARD_OEM_SIZE := $(shell python device/rockchip/common/get_partition_size.py $(RK_PARAMETER) oem)

   #$(info Calculated BOARD_SYSTEMIMAGE_PARTITION_SIZE=$(BOARD_SYSTEMIMAGE_PARTITION_SIZE) use $(RK_PARAMETER))
 else

device/rockchip/common/build/rockchip/RebuildFstab.mk 将分区大小加入分区大小队列

diff --git a/device/rockchip/common/build/rockchip/RebuildFstab.mk b/device/rockchip/common/build/rockchip/RebuildFstab.mk
index bda43d9..e1207b9 100644
--- a/device/rockchip/common/build/rockchip/RebuildFstab.mk
+++ b/device/rockchip/common/build/rockchip/RebuildFstab.mk
@@ -55,4 +55,10 @@ else
 ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_RK_VENDOR_FSTAB) $(INSTALLED_RK_RAMDISK_FSTAB)
 endif

+#keenon liangji add
+ifeq ($(strip $(BOARD_OEM_SIZE)), )
+       partition_list := $(partition_list),$(BOARD_OEM_SIZE)
+endif
+#keenon liangji add end
+
 endif

RKTools/linux/Linux_Pack_Firmware/rockdev/package-file,打包update.img的时候将oem也打包

diff --git a/RKTools/linux/Linux_Pack_Firmware/rockdev/package-file b/RKTools/linux/Linux_Pack_Firmware/rockdev/package-file
index eebcac0..3ff1786 100755
--- a/RKTools/linux/Linux_Pack_Firmware/rockdev/package-file
+++ b/RKTools/linux/Linux_Pack_Firmware/rockdev/package-file
@@ -11,6 +11,7 @@ boot        Image/boot.img
 dtbo        Image/dtbo.img
 vbmeta      Image/vbmeta.img
 recovery    Image/recovery.img
+oem      Image/oem.img
 super      Image/super.img
 # Ҫдbackupļ▒update.img

build/make/core/definitions.mk,取消无ab分区的报错

diff --git a/build/make/core/definitions.mk b/build/make/core/definitions.mk
index 59aeb16..ada2a6c 100644
--- a/build/make/core/definitions.mk
+++ b/build/make/core/definitions.mk
@@ -2768,10 +2768,10 @@ $(if $(2), \
   total=$$(( $$( echo "$$size" ) )); \
   printname=$$(echo -n "$(1)" | tr " " +); \
   maxsize=$$(($(2))); \
-  if [ "$$total" -gt "$$maxsize" ]; then \
-    echo "error: $$printname too large ($$total > $$maxsize)"; \
-    false; \
-  elif [ "$$total" -gt $$((maxsize - 32768)) ]; then \
+#  if [ "$$total" -gt "$$maxsize" ]; then \
+#    echo "error: $$printname too large ($$total > $$maxsize)"; \
+#    false; \
+  if [ "$$total" -gt $$((maxsize - 32768)) ]; then \
     echo "WARNING: $$printname approaching size limit ($$total now; limit $$maxsize)"; \
   fi \
  , \

build-nanopc-t4.sh 修改09无法参与运算的报错

diff --git a/device/rockchip/rk3399/build-nanopc-t4.sh b/device/rockchip/rk3399/build-nanopc-t4.sh
index 71f44c7..2574b95 100755
--- a/device/rockchip/rk3399/build-nanopc-t4.sh
+++ b/device/rockchip/rk3399/build-nanopc-t4.sh
@@ -142,7 +142,7 @@ function build_kernel() {
 }

 function build_android() {
-       true ${BUILD_NUMBER:=$(date +"6%y%m%d")$(($(date +"%H")/4))}
+       true ${BUILD_NUMBER:=$(date +"6%y%m%d")$(($(date +"%-H")/4))}
        export BUILD_NUMBER

        source build/envsetup.sh

mkimage.sh 增加编译oem.img

#增加
#keenon liangji add
 101 function make_oem_img() {
 102     echo "create oem.img..."
 103     [ -d $OUT/oem ] && \
 104         python build/make/tools/releasetools/build_image.py \
 105             $OUT/oem \
 106             $OUT/obj/PACKAGING/odm_intermediates/odm_image_info.txt \
 107             $OUT/odm.img \
 108             $OUT/system
 109     python device/rockchip/common/sparse_tool.py $OUT/odm.img
 110     mv $OUT/odm.img.out $OUT/oem.img
 111     cp -f $OUT/oem.img $IMAGE_PATH/oem.img
 112     echo "done."
 113 }
 114 #keenon liangji add end



 345 make_dtbo_img
 346 make_boot_img
 347 make_recovery_img
 348 make_vbmeta_img
 349 + make_oem_img
 350 + make_system_img
 351 + make_vendor_img
 352 + make_odm_img
 353
 354
 355 if [ "$PRODUCT_USE_DYNAMIC_PARTITIONS" = "true" ]; then
 356     copy_super_img
 357 else
 358     make_system_img
 359     make_vendor_img
 360     make_odm_img
 361 fi
 362

/out/target/product/nanopc-t4/下新建oem目录,里面是oem空间要有的东西

烧录后

df -h 查看/oem分区的具体的块设备名称,此时的oem分区大小还是镜像的大小

然后用 resize2fs来扩容/oem分区

【RK3399 android10 支持spi功能 (nanopc t4)】

https://www.bilibili.com/read/cv9360756?spm_id_from=333.999.0.0
https://www.bilibili.com/read/cv9360813?spm_id_from=333.999.0.0

1.内核设备树,由于uart4和spi1复用,要先关闭uart4,然后使能spi1
rk3399-nanopc-common.dtsi
编译后在/dev下能够找到spidev1.0的虚拟设备映射

2.从android6里拿来的spi自测程序,移植过来

From 25b862671036bd4cb9194bff9aba952b88073473 Mon Sep 17 00:00:00 2001
From: liangji <[email protected]>
Date: Tue, 3 Jan 2023 17:22:54 +0800
Subject: [PATCH] feat: disabled uart4 and enable spi1

Signed-off-by: liangji <[email protected]>
---
 kernel/Documentation/spi/Android.mk                |  16 ++
 kernel/Documentation/spi/Makefile                  |   9 +
 kernel/Documentation/spi/spidev_test.c             | 210 +++++++++++++++++++++
 .../boot/dts/rockchip/rk3399-nanopi4-common.dtsi   |   4 +-
 4 files changed, 237 insertions(+), 2 deletions(-)
 create mode 100644 kernel/Documentation/spi/Android.mk
 create mode 100644 kernel/Documentation/spi/Makefile
 create mode 100644 kernel/Documentation/spi/spidev_test.c

diff --git a/kernel/Documentation/spi/Android.mk b/kernel/Documentation/spi/Android.mk
new file mode 100644
index 0000000..293c2ec
--- /dev/null
+++ b/kernel/Documentation/spi/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES += spidev_test.c
+
+LOCAL_MODULE := spidev_test
+
+LOCAL_CFLAGS += -Wno-unused-parameter
+
+LOCAL_LDFLAGS += -L$(LOCAL_PATH)
+
+LOCAL_LDLIBS := -llog
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/kernel/Documentation/spi/Makefile b/kernel/Documentation/spi/Makefile
new file mode 100644
index 0000000..26e2e65
--- /dev/null
+++ b/kernel/Documentation/spi/Makefile
@@ -0,0 +1,9 @@
+# kbuild trick to avoid linker error. Can be omitted if a module is built.
+
+# List of programs to build
+hostprogs-y := spidev_test
+
+# Tell kbuild to always build the programs
+always := $(hostprogs-y)
+
+HOSTCFLAGS_spidev_test.o += -I$(objtree)/usr/include
diff --git a/kernel/Documentation/spi/spidev_test.c b/kernel/Documentation/spi/spidev_test.c
new file mode 100644
index 0000000..16feda9
--- /dev/null
+++ b/kernel/Documentation/spi/spidev_test.c
@@ -0,0 +1,210 @@
+/*
+ * SPI testing utility (using spidev driver)
+ *
+ * Copyright (c) 2007  MontaVista Software, Inc.
+ * Copyright (c) 2007  Anton Vorontsov <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * Cross-compile with cross-gcc -I/path/to/cross-kernel/include
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+static void pabort(const char *s)
+{
+	perror(s);
+	abort();
+}
+
+static const char *device = "/dev/spidev1.1";
+static uint8_t mode;
+static uint8_t bits = 8;
+static uint32_t speed = 500000;
+static uint16_t delay;
+
+static void transfer(int fd)
+{
+	int ret;
+	uint8_t tx[] = {
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0x40, 0x00, 0x00, 0x00, 0x00, 0x95,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+		0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD,
+		0xF0, 0x0D,
+	};
+	uint8_t rx[ARRAY_SIZE(tx)] = {0, };
+	struct spi_ioc_transfer tr = {
+		.tx_buf = (unsigned long)tx,
+		.rx_buf = (unsigned long)rx,
+		.len = ARRAY_SIZE(tx),
+		.delay_usecs = delay,
+		.speed_hz = speed,
+		.bits_per_word = bits,
+	};
+
+	ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
+	if (ret < 1)
+		pabort("can't send spi message");
+
+	for (ret = 0; ret < ARRAY_SIZE(tx); ret++) {
+		if (!(ret % 6))
+			puts("");
+		printf("%.2X ", rx[ret]);
+	}
+	puts("");
+}
+
+static void print_usage(const char *prog)
+{
+	printf("Usage: %s [-DsbdlHOLC3]\n", prog);
+	puts("  -D --device   device to use (default /dev/spidev1.1)\n"
+	     "  -s --speed    max speed (Hz)\n"
+	     "  -d --delay    delay (usec)\n"
+	     "  -b --bpw      bits per word \n"
+	     "  -l --loop     loopback\n"
+	     "  -H --cpha     clock phase\n"
+	     "  -O --cpol     clock polarity\n"
+	     "  -L --lsb      least significant bit first\n"
+	     "  -C --cs-high  chip select active high\n"
+	     "  -3 --3wire    SI/SO signals shared\n");
+	exit(1);
+}
+
+static void parse_opts(int argc, char *argv[])
+{
+	while (1) {
+		static const struct option lopts[] = {
+			{ "device",  1, 0, 'D' },
+			{ "speed",   1, 0, 's' },
+			{ "delay",   1, 0, 'd' },
+			{ "bpw",     1, 0, 'b' },
+			{ "loop",    0, 0, 'l' },
+			{ "cpha",    0, 0, 'H' },
+			{ "cpol",    0, 0, 'O' },
+			{ "lsb",     0, 0, 'L' },
+			{ "cs-high", 0, 0, 'C' },
+			{ "3wire",   0, 0, '3' },
+			{ "no-cs",   0, 0, 'N' },
+			{ "ready",   0, 0, 'R' },
+			{ NULL, 0, 0, 0 },
+		};
+		int c;
+
+		c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'D':
+			device = optarg;
+			break;
+		case 's':
+			speed = atoi(optarg);
+			break;
+		case 'd':
+			delay = atoi(optarg);
+			break;
+		case 'b':
+			bits = atoi(optarg);
+			break;
+		case 'l':
+			mode |= SPI_LOOP;
+			break;
+		case 'H':
+			mode |= SPI_CPHA;
+			break;
+		case 'O':
+			mode |= SPI_CPOL;
+			break;
+		case 'L':
+			mode |= SPI_LSB_FIRST;
+			break;
+		case 'C':
+			mode |= SPI_CS_HIGH;
+			break;
+		case '3':
+			mode |= SPI_3WIRE;
+			break;
+		case 'N':
+			mode |= SPI_NO_CS;
+			break;
+		case 'R':
+			mode |= SPI_READY;
+			break;
+		default:
+			print_usage(argv[0]);
+			break;
+		}
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	int ret = 0;
+	int fd;
+
+	parse_opts(argc, argv);
+
+	fd = open(device, O_RDWR);
+	if (fd < 0)
+		pabort("can't open device");
+
+	/*
+	 * spi mode
+	 */
+	ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
+	if (ret == -1)
+		pabort("can't set spi mode");
+
+	ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
+	if (ret == -1)
+		pabort("can't get spi mode");
+
+	/*
+	 * bits per word
+	 */
+	ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
+	if (ret == -1)
+		pabort("can't set bits per word");
+
+	ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
+	if (ret == -1)
+		pabort("can't get bits per word");
+
+	/*
+	 * max speed hz
+	 */
+	ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
+	if (ret == -1)
+		pabort("can't set max speed hz");
+
+	ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
+	if (ret == -1)
+		pabort("can't get max speed hz");
+
+	printf("spi mode: %d\n", mode);
+	printf("bits per word: %d\n", bits);
+	printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);
+
+	transfer(fd);
+
+	close(fd);
+
+	return ret;
+}
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi
index 60d087f..aa011e7 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi
@@ -395,7 +395,7 @@
 };
 
 &spi1 {
-	status = "disabled";
+	status = "okay";
 	pinctrl-names = "default", "sleep";
 	pinctrl-1 = <&spi1_gpio>;
 
@@ -418,7 +418,7 @@
 };
 
 &uart4 {
-	status = "okay";
+	status = "disabled";
 };
 
 &vopb {
-- 
2.7.4


【RK3399 Android10 立体视觉ip配置(手动)(nanopc t4)】

ifconfig usb0 up 
ifconfig usb1 up

busybox udhcpc -i usb1  #自动获取动态ip
busybox udhcpc -i usb0

ifconfig usb1 10.11.12.11
ifconfig usb0 10.11.11.11

ip rule add from all pref 9999 table main  #策略路由
ip rule 
ip route show table local

ip route
ip route del 10.0.0.0/8 dev usb0  #默认网关
ip route del 10.0.0.0/8 dev usb1
ip route add 10.11.12.0/24 dev usb1
ip route add 10.11.11.0/24 dev usb0


【RK3399 Android10 dropbear移植,ssh功能支持】

项目目的
打算在android10上移植dropbear来实现ssh功能

结果
dropbear工具能用,但是没有实现账户密码登录(android里面没有user的概念),只能使用密钥登录

目前在网上找的dropbear源码放到rk3399-android10的sdk的external/下编译,会报eng 被废弃的错误,改成optional后会有大量语法警告报错,屏蔽之后还是有错误。都不能用。

之后打算移植openssh,网上找的代码在Android10中编译会报不是git仓库的问题

Android6的external/下自带有openssh,也可以编译的过,但是编译出的执行文件无法在Android10中使用。把openssh源码拿到rk3399-android10的external/下编译,依然报不是git仓库。

最后在网上找到了已经编译好的Android9的arm版本的dropbear。放到/system/bin下,竟然可以执行。
测试下来,发现可以通过密钥进行登录,但是无法设置账号密码登录。

使用
dropbear工具链接

目前只成功验证了使用秘钥的无密码登录方式,密码登录的方式没有验证成功
Android端的操作:
  1.将dropbear dropbearkey scp文件push到Android系统内,并给予执行权限 
  2.dropbearkey 生成一个自己的rsa文件 dropbearkey -t rsa -f /mnt/sdcard/dropbear/dropbear_rsa_host_key
  3.拉起dropbear服务   
    export HOME=/mnt/sdcard/dropbear/
    dropbear  -F -r $HOME/dropbear_rsa_host_key -T $HOME/id_rsa.pub -D  $HOME -p 2022 -A
    参数说明: -F前台运行  ,-r指定一个自己的秘钥, -T指定linux端登录访问的公钥, -p指定端口 
    
Linux端的操作:
   使用ssh-keygen -t rsa 指令生成秘钥和公钥,公钥push到Android系统里面,即dropbear启动参数里面的-T $HOME/id_rsa.pub  ,秘钥用ssh-add 添加到Linux的ssh list中

文件传输操作:
   将两个嵌入式设备连接到同一个局域网内,然后用ifconfig取得Android的ip地址(192.168.1.101),在Linux端使用以下指令
   登录服务: ssh 192.168.1.101
   Linux发送文件到Android端:scp -P 2022  /home/test/1.text  192.168.0.101:/mnt/sdcard/dropbear/
   Linux下载Android端的文件:scp -P 2022  192.168.0.101:/mnt/sdcard/dropbear/2.txt  /home/test

【RK3399 Android10 usb_scan重新适配,同时支持立体视觉自动适配】

未整理代码规范版本

【RK3399 Android10 wifi sta和ap模式 mac地址保持一致】

将sta模式的mac地址作为ap热点模式的mac地址

From 1c13bd69306a02be0be4186ae6e6bc43fe8e54d1 Mon Sep 17 00:00:00 2001
From: liangji <[email protected]>
Date: Wed, 18 Jan 2023 11:25:20 +0800
Subject: [PATCH] feat: use wifi sta mac as ap mac always

Signed-off-by: liangji <[email protected]>
---
 .../net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_linux.c     | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_linux.c b/kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_linux.c
index 90616c2..51185d0 100644
--- a/kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_linux.c
+++ b/kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd_wifi6/dhd_linux.c
@@ -198,6 +198,8 @@ static u32 vendor_oui = CONFIG_DHD_SET_RANDOM_MAC_VAL;
 
 #include 
 
+
+uint8 fixed_dev_mac[ETHER_ADDR_LEN];
 /* Maximum STA per radio */
 #define DHD_MAX_STA     32
 
@@ -3143,7 +3145,9 @@ dhd_set_mac_address(struct net_device *dev, void *addr)
 	dhdif = dhd->iflist[ifidx];
 
 	dhd_net_if_lock_local(dhd);
-	memcpy(dhdif->mac_addr, sa->sa_data, ETHER_ADDR_LEN);
+	//memcpy(dhdif->mac_addr, sa->sa_data, ETHER_ADDR_LEN);
+	memcpy(dhdif->mac_addr, fixed_dev_mac, ETHER_ADDR_LEN);
+
 	dhdif->set_macaddress = TRUE;
 	dhd_net_if_unlock_local(dhd);
 	WL_MSG(dev->name, "iftype = %d macaddr = %pM\n",
@@ -12063,6 +12067,7 @@ dhd_register_if(dhd_pub_t *dhdp, int ifidx, bool need_rtnl_lock)
 
 	printf("Register interface [%s]  MAC: "MACDBG"\n\n", net->name,
 		MAC2STRDBG(net->dev_addr));
+    memcpy(fixed_dev_mac, net->dev_addr, ETHER_ADDR_LEN);
 
 #if defined(SOFTAP) && defined(WL_WIRELESS_EXT) && !defined(WL_CFG80211)
 //		wl_iw_iscan_set_scan_broadcast_prep(net, 1);
-- 
2.7.4


【(学习)Android10 屏幕显示】

fb设备,gralloc设备
framebuffer

Gralloc模块是一个HAL模块,为libui提供服务,管理framebuffer

gralloc被FramebufferNativeWindow.cpp构造函数开始调用

FramebufferNativeWindow实现FrameBuffer的管理,它主要被SurfaceFlinger使用。也能够被OpenGL Native程序使用。

gralloc模块—>FramebufferNativeWindow类—>surfaceFlinger
—>openGLNative

【gralloc (HAL层)】
抽象全部hal模块:struct hw_module_t
向上层提供的抽象接口:
struct hw_module_methods_t
{
*open()(回调函数指定)
}

在需要用到gralloc模块的时候,把*open,指向到gralloc_device_open()

gralloc模块支持打开两种设备:fb0(主屏幕),gpu0(Framebuffer分配和释放)

这两种设备在调用gralloc模块的FramebufferNativeWindow中以fbDev和grDev变量存在,
FramebufferNativeWindow中打开fbDev和grDev这两种设备的操作是
framebuffer_open()和gralloc_open()实质上都是调用的HAL的open—>gralloc_device_open()

【gralloc_device_open:gralloc设备打开】
给这个设备gralloc_context_t* dev变量指定grallop_alloc()和gralloc_free()接口函数

【gralloc_device_open:fb设备打开】

struct fb_context_t的设置配置
mapFrameBuffer(m)内存映射配置(在这里面开始真正调用内核接口,打开kernel内核设备)
成员变量有
framebuffer_device_t(需要如下接口)(这个是对framebuffer设备的统一描述)

post(将buffer数据post到显示屏,要求buffer必须和屏幕尺寸一致,且没有被locked,这样buffer内容将在下一次Vsync中被显示)
setSwapInterval(设置两个缓冲区的交换时间间隔)
setUpdateRect(设置刷新区域,也就是说,在此之外的区域很可以无效而不被刷新)

【EGL】

native window 本地窗口

native window 将openGL中渲染好的适配到具体的Android平台
针对android的GUI,需要两种native window:
面向管理者(surfaceFlinger)的本地窗口 == FramebufferNativeWindow (消费者)
面向应用程序 的本地窗口 == surface (生产者)

图形渲染都基于OpenGL ES的情况:
不同应用(surface)绘制---->memory Buffer---->OpenGl ES渲染---->FramebufferNativeWindow----->Framebuffer显示到屏幕

EGL是openGL渲染和本地窗口之间的接口

【android10 时间同步禁用,修改默认时区】

【网络工具ip 学习】

https://blog.csdn.net/A08118139/article/details/129980030

  1. 四表五链
    【record】_第4张图片
    应该叫五链四表
    链是指的链路,指的数据包的通过路径
    四表里面表示对数据包的操作(这里面加入具体的处理规则链)

    filter表——过滤数据包
    Nat表——用于网络地址转换(IP、端口)
    Mangle表——修改数据包的服务类型、TTL、并且可以配置路由实现QOS
    Raw表——决定数据包是否被状态跟踪机制处理

  2. ip route关于路由转发,网络工具ip的使用

ip route show table main 查看main路由表

liangji@liangji-Vostro-3670:~/liangji_test$ ip route show table main
default via 172.16.9.1 dev enx000ec6821555 proto dhcp metric 100 
default via 10.0.0.1 dev enp2s0 proto static metric 20101 
10.0.0.0/8 dev enp2s0 proto kernel scope link src 10.0.0.2 metric 101 
169.254.0.0/16 dev enp2s0 scope link metric 1000 
172.16.9.0/24 dev enx000ec6821555 proto kernel scope link src 172.16.9.119 metric 100 
liangji@liangji-Vostro-3670:~/liangji_test$ 
liangji@liangji-Vostro-3670:~/liangji_test$ 
liangji@liangji-Vostro-3670:~/liangji_test$ route -n
内核 IP 路由表
目标            网关            子网掩码        标志  跃点   引用  使用 接口
0.0.0.0         172.16.9.1      0.0.0.0         UG    100    0        0 enx000ec6821555
0.0.0.0         10.0.0.1        0.0.0.0         UG    20101  0        0 enp2s0
10.0.0.0        0.0.0.0         255.0.0.0       U     101    0        0 enp2s0
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 enp2s0
172.16.9.0      0.0.0.0         255.255.255.0   U     100    0        0 enx000ec6821555

ip route show table main 和route -n对应
先寻找下面三个的有指定目标的路由表,如果该数据包的目的ip是这三个有具体目标的(按子网掩码来定优先级),那么就发送给这个的网关。
如果没有匹配到具体的目标,那么按照默认路由表转发,由跃点确认优先级。

ip route add 192.168.64.0/24 via 172.16.9.1 table main 加入一个有具体目标的路由表

  1. ip rule
#ubuntu 的 ip rule list
seaice@seaice-VirtualBox:~$ ip rule list
0:  from all lookup local 
32766:  from all lookup main
32767:  from all lookup default


#android 的 ip rule list
shell@rk3288:/ $ ip rule list
0:	from all lookup local 
9999:	from all lookup 1 
10000:	from all fwmark 0xc0000/0xd0000 lookup legacy_system 
13000:	from all fwmark 0x10063/0x1ffff lookup local_network 
15000:	from all fwmark 0x0/0x10000 lookup legacy_system 
16000:	from all fwmark 0x0/0x10000 lookup legacy_network 
17000:	from all fwmark 0x0/0x10000 lookup local_network 
23000:	from all fwmark 0x0/0xffff uidrange 0-0 lookup main 
32000:	from all unreachable
10000:  from all fwmark 0xc0000/0xd0000 lookup legacy_system

优先级为10000的策略表示,所有的数据包(from all), 其iptables的mark(fwmark)和0xd0000按位与后,所得结果为0xc0000的数据包(fwmark 0xc0000/0xd0000),使用legacy_system路由表(ip route show table)进行路由查找(lookup legacy_system)

11000:  from all iif lo oif rmnet_data0 uidrange 0-0 lookup rmnet_data0

优先级为11000的策略表示,所有是的数据包(from all),如果是从lo回环接口输入(iif lo),从rmnet_data0接口输出(oif rmnet_data0),其uid为0(uidrange 0-0)即系统用户,使用rmnet_data0路由表进行路由查找。lo接口的作用是,假如一个本地进程向另一个本地进程发送数据,那么将会使用lo接口,此时如果在rmnet_data0接口上抓包是无法抓到的,但是在lo接口上能够抓到。

29000:  from all fwmark 0x0/0xffff iif lo lookup rmnet_data0

优先级为29000的策略表示,所有的数据包,其iptables的mark和0xffff按位与后,所得结果为0x0,且是从lo回环接口输入的数据包,使用rmnet_data0路由表。在不主动设置数据包的mark时,数据包的mark就是0,所以在不设置mark的时候,数据包通常会满足这条路由策略。

添加策略路由

root@seaice-VirtualBox:/home/seaice# ip rule add from 109.131.7.10 table 10
root@seaice-VirtualBox:/home/seaice# ip rule add from 109.131.8.0/24 table 20
root@seaice-VirtualBox:/home/seaice# ip rule list
0:	from all lookup local
32764:	from 109.131.8.0/24 lookup 20  #如果来源端的IP是109.131.8.0/24网段的IP,就参考路由20
32765:	from 109.131.7.10 lookup 10    #如果数据包的来源IP是109.131.7.10, 就参考路由表10
32766:	from all lookup main
32767:	from all lookup default


#根据目的ip指定策略路由
root@seaice-VirtualBox:/home/seaice# ip rule add to 109.131.9.0/24 table 30
root@seaice-VirtualBox:/home/seaice# ip rule add to 109.131.10.10 table 40

用iptable 设置 网络包的mark,来使用fwmark来指定特定数据包

seaice# iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 1
seaice# ip rule add fwmark 1 table 50

#table 50 就是ip route show table 50, 可以用 ip route add xxx via xxx table 50 来增加路由表

凡是enp0S3端口接入的都走55路由表

root@seaice-VirtualBox:/# ip rule add dev enp0s3 table 55

ip rule 删除策略

root@seaice-VirtualBox:/# ip rule list
0:	from all lookup local
32760:	from all iif enp0s3 lookup 55
32761:	from all fwmark 0x1 lookup 50
32762:	from all to 109.131.10.10 lookup 40
32763:	from all to 109.131.9.0/24 lookup 30
32764:	from 109.131.8.0/24 lookup 20
32765:	from 109.131.7.10 lookup 10
32766:	from all lookup main
32767:	from all lookup default


root@seaice-VirtualBox:/# ip rule del prio 32760
root@seaice-VirtualBox:/# ip rule del fwmark 1
root@seaice-VirtualBox:/# ip rule del table 40
root@seaice-VirtualBox:/# ip rule del table 30
root@seaice-VirtualBox:/# ip rule del from 109.131.8.0/24
root@seaice-VirtualBox:/# ip rule del prio 32765

root@seaice-VirtualBox:/# ip rule list
0:	from all lookup local
32766:	from all lookup main
32767:	from all lookup default

要记得创建新的路由表

ip rule add from 192.168.2.0/24 table 10
ip route add 192.168.1.0/24 dev eth1 table 10
ip route add default via 192.168.1.254 table 10
ip route show table 10

【RK3399 android10 nanopc wifi和eth网络连接优先级问题】

https://blog.csdn.net/A08118139/article/details/129980002?spm=1001.2014.3001.5502
原因出在framework中以太网eth和wifi在源码中的默认优先级,将wifi的默认优先级设置成高于eth就可以了

From a23bfd2ba436668b32ac2417afbadbcd5e339751 Mon Sep 17 00:00:00 2001
From: liangji <[email protected]>
Date: Tue, 31 Jan 2023 13:52:27 +0800
Subject: [PATCH] feat: solve wifi cannot configure when eth1 is running

Signed-off-by: liangji <[email protected]>
---
 frameworks/base/core/java/android/net/NetworkFactory.java             | 4 ++--
 .../java/com/android/server/ethernet/EthernetNetworkFactory.java      | 3 ++-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/frameworks/base/core/java/android/net/NetworkFactory.java b/frameworks/base/core/java/android/net/NetworkFactory.java
index 5b1d12c..f60f48e 100644
--- a/frameworks/base/core/java/android/net/NetworkFactory.java
+++ b/frameworks/base/core/java/android/net/NetworkFactory.java
@@ -342,8 +342,8 @@ public class NetworkFactory extends Handler {
             n.requested = true;
         } else if (shouldReleaseNetworkFor(n)) {
             if (VDBG) log("  releaseNetworkFor");
-            releaseNetworkFor(n.request);
-            n.requested = false;
+            //releaseNetworkFor(n.request);
+            //n.requested = false;
         } else {
             if (VDBG) log("  done");
         }
diff --git a/frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java b/frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java
index f70e885..a28ac55 100644
--- a/frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java
+++ b/frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java
@@ -70,7 +70,8 @@ public class EthernetNetworkFactory extends NetworkFactory {
     private final static String TAG = EthernetNetworkFactory.class.getSimpleName();
     final static boolean DBG = true;
 
-    private final static int NETWORK_SCORE = 70;
+    //private final static int NETWORK_SCORE = 70;
+    private final static int NETWORK_SCORE = 30;
     private static final String NETWORK_TYPE = "Ethernet";
 
     private final ConcurrentHashMap<String, NetworkInterfaceState> mTrackingInterfaces =
-- 
2.7.4


From f7e335bafa2d2e2f5344715f16668afec7505355 Mon Sep 17 00:00:00 2001
From: liangji <[email protected]>
Date: Wed, 1 Feb 2023 11:39:34 +0800
Subject: [PATCH] fix: solve wifi disconnect when eth1 is running

Signed-off-by: liangji <[email protected]>
---
 .../java/com/android/server/ethernet/EthernetNetworkFactory.java      | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java b/frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java
index a28ac55..4387441 100644
--- a/frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java
+++ b/frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java
@@ -71,7 +71,7 @@ public class EthernetNetworkFactory extends NetworkFactory {
     final static boolean DBG = true;
 
     //private final static int NETWORK_SCORE = 70;
-    private final static int NETWORK_SCORE = 30;
+    private final static int NETWORK_SCORE = 40;
     private static final String NETWORK_TYPE = "Ethernet";
 
     private final ConcurrentHashMap<String, NetworkInterfaceState> mTrackingInterfaces =
@@ -390,7 +390,7 @@ public class EthernetNetworkFactory extends NetworkFactory {
                     new TransportInfo(ConnectivityManager.TYPE_NONE, 1));
             // EthernetNetworkFactory.NETWORK_SCORE
             sTransports.put(NetworkCapabilities.TRANSPORT_ETHERNET,
-                    new TransportInfo(ConnectivityManager.TYPE_ETHERNET, 70));
+                    new TransportInfo(ConnectivityManager.TYPE_ETHERNET, 40));
             // BluetoothTetheringNetworkFactory.NETWORK_SCORE
             sTransports.put(NetworkCapabilities.TRANSPORT_BLUETOOTH,
                     new TransportInfo(ConnectivityManager.TYPE_BLUETOOTH, 69));
-- 
2.7.4


【RK3399 android10 nanopc typec接口驱动模式,adb模式和usb模式】

https://blog.csdn.net/A08118139/article/details/129979982
typec接口在驱动层面有两种工作模式,一个是adb调试模式,另一个是usb数据接口模式(u盘)

From c8ec4b3a76ba354fff6d6cbc7430cc19c602ac8c Mon Sep 17 00:00:00 2001
From: liangji <[email protected]>
Date: Tue, 31 Jan 2023 14:22:51 +0800
Subject: [PATCH] feat: solve type_c adb DFP mode

Signed-off-by: liangji <[email protected]>
---
 kernel/arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi
index 60d087f..75ddc7a 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi
@@ -770,6 +770,8 @@
 		pinctrl-0 = <&fusb0_int>;
 		int-n-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
 		vbus-5v-gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>;
+        fusb302,role = "ROLE_MODE_DRP";
+        fusb302,try_role = "ROLE_MODE_DFP";
 		status = "okay";
 	};
 
-- 
2.7.4

【RK3399 android10 nanopc 删除某些apk应用】

https://blog.csdn.net/A08118139/article/details/129979972?spm=1001.2014.3001.5501
删除com.android.quicksearchbox

  1. 在device/下 grep -rn quicksearchbox 发现有
  2. 在package/apps/下 grep -rn quicksearchbox 找到这个app,然后查看Android.bp 看看app 的name
  3. 在build/ 下grep -rn app的name,删掉

【RK3288 android6 4个摄像头固定映射】

https://blog.csdn.net/A08118139/article/details/129979963?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22129979963%22%2C%22source%22%3A%22A08118139%22%7D
kernel

From 03f90bb48715fe4da182d1ddbff884fe258f74cf Mon Sep 17 00:00:00 2001
From: liangji <[email protected]>
Date: Wed, 22 Feb 2023 15:32:09 +0800
Subject: [PATCH 1/2] feat: support unik cam usb number 7 8 9 10

Change-Id: I9465cfa6b9348bb7df85b4ae194eba7690a8ae2a
Signed-off-by: liangji <[email protected]>
---
 arch/arm/boot/dts/rk3288-tb_8846.dts |  4 ++--
 drivers/media/usb/uvc/uvc_driver.c   |  6 ++++++
 drivers/media/v4l2-core/v4l2-dev.c   | 17 +++++++++++++++++
 drivers/usb/core/hub.c               | 19 +++++++++++++++++++
 include/linux/usb.h                  |  1 +
 include/media/v4l2-dev.h             |  1 +
 6 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/rk3288-tb_8846.dts b/arch/arm/boot/dts/rk3288-tb_8846.dts
index c4fcd7d..d19b39f 100644
--- a/arch/arm/boot/dts/rk3288-tb_8846.dts
+++ b/arch/arm/boot/dts/rk3288-tb_8846.dts
@@ -509,7 +509,7 @@
 	status = "okay";
 
 	ilitek@41 {
-		//status = "disabled";
+		status = "disabled";
 		compatible = "tchip,ilitek";
 		reg = <0x41>;
 		ilitek,irq-gpio = <&gpio7 GPIO_A6 IRQ_TYPE_EDGE_FALLING>;
@@ -567,7 +567,7 @@
 	   timing4 : 10.1"LVDS1280x800;
 	   timing5 : 12.3"eDP1920x720;
 	*/
-	native-mode = <&timing0>;
+	native-mode = <&timing4>;
 };
 
 &rk_screen {
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index 8ca9769..2eaf433 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -1737,6 +1737,12 @@ static int uvc_register_video(struct uvc_device *dev,
 	stream->vdev = vdev;
 	video_set_drvdata(vdev, stream);
 
+    //keenon liangji add
+    vdev->hw_portnum = dev->udev->hw_portnum;
+    printk("vdev_hw_portnum = %d\n", vdev->hw_portnum);
+
+    //keenon liangji add end
+
 	ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
 	if (ret < 0) {
 		uvc_printk(KERN_ERR, "Failed to register video device (%d).\n",
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index ad53e63..931b7f8 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -844,6 +844,23 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
 
 	/* Pick a device node number */
 	mutex_lock(&videodev_lock);
+
+    //keenon liangji add
+
+    printk("dxq portnum=%d\n", vdev->hw_portnum);
+    if(vdev->vfl_type == VFL_TYPE_GRABBER) {
+        if(7 == vdev->hw_portnum) {
+            nr = 7;
+        }else if(8 == vdev->hw_portnum) {
+            nr = 8;
+        }else if(9 == vdev->hw_portnum) {
+            nr = 9;
+        }else if(10 == vdev->hw_portnum) {
+            nr = 10;
+        }
+    }
+    //keenon liangji add end
+
 	nr = devnode_find(vdev, nr == -1 ? 0 : nr, minor_cnt);
 	if (nr == minor_cnt)
 		nr = devnode_find(vdev, 0, minor_cnt);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 59f11c6..61586ef 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2148,6 +2148,25 @@ static void show_string(struct usb_device *udev, char *id, char *string)
 
 static void announce_device(struct usb_device *udev)
 {
+    //keenon liangji add
+    udev->hw_portnum=0;
+    //printk("kobject_name(&udev->dev->kobj)=%s\n", kobject_name(&(udev->dev.kobj)));
+    if(!strcmp("1-1.3", kobject_name(&(udev->dev.kobj)))){
+        udev->hw_portnum=7;
+    }else if(!strcmp("1-1.1", kobject_name(&(udev->dev.kobj)))){
+        udev->hw_portnum=10;
+    }
+    else if(!strcmp("1-1.4", kobject_name(&(udev->dev.kobj)))){
+        udev->hw_portnum=9;
+    }
+    else if(!strcmp("3-1", kobject_name(&(udev->dev.kobj)))){
+        udev->hw_portnum=8;
+    }
+
+
+
+    //printk("udev->hw_portnum=%d\n", udev->hw_portnum);
+    //keenon liangji add end
 	dev_info(&udev->dev, "New USB device found, idVendor=%04x, idProduct=%04x\n",
 		le16_to_cpu(udev->descriptor.idVendor),
 		le16_to_cpu(udev->descriptor.idProduct));
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 28bd3a8..95ae6f4 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -554,6 +554,7 @@ struct usb_device {
 
 	unsigned short bus_mA;
 	u8 portnum;
+    u8 hw_portnum;
 	u8 level;
 
 	unsigned can_submit:1;
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 95d1c91..8e7e7a0 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -126,6 +126,7 @@ struct video_device
 	struct list_head	fh_list; /* List of struct v4l2_fh */
 
 	int debug;			/* Activates debug level*/
+    int hw_portnum;    /*usb hw port*/
 
 	/* Video standard vars */
 	v4l2_std_id tvnorms;		/* Supported tv norms */
-- 
2.7.4

hardware

From e9f8a5d1c7f3873b2bb4abafbf4f3e5c984cf875 Mon Sep 17 00:00:00 2001
From: liangji <[email protected]>
Date: Wed, 22 Feb 2023 15:34:00 +0800
Subject: [PATCH] feat: support unik cam_layer

Change-Id: Iab5b9a81fd7716761bb83a31bf818aa56f5f07d7
Signed-off-by: liangji <[email protected]>
---
 rockchip/camera/CameraHal/CameraHal_Module.cpp | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/rockchip/camera/CameraHal/CameraHal_Module.cpp b/rockchip/camera/CameraHal/CameraHal_Module.cpp
index 4760f49..c2d2d0b 100755
--- a/rockchip/camera/CameraHal/CameraHal_Module.cpp
+++ b/rockchip/camera/CameraHal/CameraHal_Module.cpp
@@ -753,6 +753,11 @@ int camera_get_number_of_cameras(void)
             sprintf(cam_num, "%d", i);
             strcat(cam_sys,cam_num);
             strcat(cam_sys,"/index");
+
+            //keenon liangji add
+            camInfoTmp[cam_cnt].facing_info.facing = -1;
+            //keenon liangji add end
+
             FILE* ifp;
             ifp = fopen(cam_sys, "r");
             if (ifp == NULL){
@@ -775,7 +780,7 @@ int camera_get_number_of_cameras(void)
             if (fd < 0) {
                 LOGE("Open %s failed! strr: %s",cam_path,strerror(errno));
                 break;
-            } 
+            }
             LOGD("Open %s success!",cam_path);
 
             memset(&capability, 0, sizeof(struct v4l2_capability));
@@ -790,14 +795,19 @@ int camera_get_number_of_cameras(void)
             	rk_cam_total_info* pNewCamInfo = new rk_cam_total_info();
                 memset(camInfoTmp[cam_cnt].device_path,0x00, sizeof(camInfoTmp[cam_cnt].device_path));
                 strcat(camInfoTmp[cam_cnt].device_path,cam_path);
+                //keenon liangji add
+                camInfoTmp[cam_cnt].facing_info.facing = i;
+                //keenon liangji add end
                 memset(camInfoTmp[cam_cnt].fival_list,0x00, sizeof(camInfoTmp[cam_cnt].fival_list));
                 memcpy(camInfoTmp[cam_cnt].driver,capability.driver, sizeof(camInfoTmp[cam_cnt].driver));
                 camInfoTmp[cam_cnt].version = capability.version;
+                /*
                 if (strstr((char*)&capability.card[0], "front") != NULL) {
                     camInfoTmp[cam_cnt].facing_info.facing = CAMERA_FACING_FRONT;
                 } else {
                     camInfoTmp[cam_cnt].facing_info.facing = CAMERA_FACING_BACK;
-                }  
+                }
+                */
                 ptr = strstr((char*)&capability.card[0],"-");
                 if (ptr != NULL) {
                     ptr++;
@@ -975,6 +985,7 @@ int camera_get_number_of_cameras(void)
 				}
 				else//cif soc camera
 				{
+
 					int i=0;					 
 					int fps;
 					int crop_w, crop_h;
@@ -1123,6 +1134,7 @@ int camera_get_number_of_cameras(void)
     //memcpy(&gCamInfos[1], &camInfoTmp[1], sizeof(rk_cam_info_t));
     for(int i=0;i<CAMERAS_SUPPORT_MAX;i++){
         memcpy(&gCamInfos[i], &camInfoTmp[i], sizeof(rk_cam_info_t));
+
     }
 
 
@@ -1326,6 +1338,9 @@ int camera_get_camera_info(int camera_id, struct camera_info *info)
         fp = -1;
     }
 
+    //keenon liangji add
+    info->facing = gCamInfos[camera_id].facing_info.facing;
+    //keenon liangji add end
     info->facing = gCamInfos[camera_id].facing_info.facing;
     if (strstr(process_name,"com.skype.rover")) {
         info->orientation = (info->facing == CAMERA_FACING_BACK)? CONFIG_CAMERA_BACK_ORIENTATION_SKYPE : CONFIG_CAMERA_FRONT_ORIENTATION_SKYPE;       
@@ -1335,9 +1350,12 @@ int camera_get_camera_info(int camera_id, struct camera_info *info)
 #else
     info->facing = gCamInfos[camera_id].facing_info.facing;
     info->orientation = gCamInfos[camera_id].facing_info.orientation;       
+    //keenon liangji add
+    info->facing = gCamInfos[camera_id].facing_info.facing;
+    //keenon liangji add end
+
 #endif
 end:
-    LOGD("%s(%d): camera_%d facing(%d), orientation(%d)",__FUNCTION__,__LINE__,camera_id,info->facing,info->orientation);
     return rv;
 }
 #if CONFIG_AUTO_DETECT_FRAMERATE 
-- 
2.7.4


framework/base

From 07167c5056f586b92942c72f0ea59db529a64559 Mon Sep 17 00:00:00 2001
From: liangji <[email protected]>
Date: Wed, 22 Feb 2023 15:36:00 +0800
Subject: [PATCH 1/3] feat: support get cam_layer of unik

Change-Id: I5ef475f716666764c25796e9f60fb9377d360b2a
Signed-off-by: liangji <[email protected]>
---
 api/current.txt                                    |  1 +
 api/system-current.txt                             |  1 +
 .../android/hardware/camera2/CameraManager.java    | 50 ++++++++++++++++++++++
 3 files changed, 52 insertions(+)

diff --git a/api/current.txt b/api/current.txt
index 541794a..21f187a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -13358,6 +13358,7 @@ package android.hardware.camera2 {
   public final class CameraManager {
     method public android.hardware.camera2.CameraCharacteristics getCameraCharacteristics(java.lang.String) throws android.hardware.camera2.CameraAccessException;
     method public java.lang.String[] getCameraIdList() throws android.hardware.camera2.CameraAccessException;
+    method public int getCameraInfo(int) throws android.hardware.camera2.CameraAccessException;
     method public void openCamera(java.lang.String, android.hardware.camera2.CameraDevice.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public void registerAvailabilityCallback(android.hardware.camera2.CameraManager.AvailabilityCallback, android.os.Handler);
     method public void registerTorchCallback(android.hardware.camera2.CameraManager.TorchCallback, android.os.Handler);
diff --git a/api/system-current.txt b/api/system-current.txt
index 7c4e0de..9f77759 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -13700,6 +13700,7 @@ package android.hardware.camera2 {
   public final class CameraManager {
     method public android.hardware.camera2.CameraCharacteristics getCameraCharacteristics(java.lang.String) throws android.hardware.camera2.CameraAccessException;
     method public java.lang.String[] getCameraIdList() throws android.hardware.camera2.CameraAccessException;
+    method public int getCameraInfo(int) throws android.hardware.camera2.CameraAccessException;
     method public void openCamera(java.lang.String, android.hardware.camera2.CameraDevice.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public void registerAvailabilityCallback(android.hardware.camera2.CameraManager.AvailabilityCallback, android.os.Handler);
     method public void registerTorchCallback(android.hardware.camera2.CameraManager.TorchCallback, android.os.Handler);
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 1fcfaca..b21e085 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -188,6 +188,51 @@ public final class CameraManager {
     }
 
     /**
+     * keenon liangji add getCameraInfo()
+     * parameters is 0, 1, 2, 3
+     *
+     */
+    @RequiresPermission(android.Manifest.permission.CAMERA)
+    public int getCameraInfo(@NonNull int id)
+            throws CameraAccessException {
+        //keenon liangji add
+        int cam_layer = 0;
+        ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
+        if (cameraService == null) {
+            throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
+            "Camera service is currently unavailable");
+        }
+        try{
+            // Legacy backwards compatibility path; build static info from the camera
+            // parameters
+            String[] outParameters = new String[1];
+
+            cameraService.getLegacyParameters(id, /*out*/outParameters);
+            String parameters = outParameters[0];
+
+            CameraInfo info = new CameraInfo();
+            cameraService.getCameraInfo(id, /*out*/info);
+
+            cam_layer = info.info.facing;
+
+            // Normal path: Get the camera characteristics directly from the camera service
+
+
+        } catch (CameraRuntimeException e) {
+            throw e.asChecked();
+        } catch (RemoteException e) {
+            // Camera service died - act as if the camera was disconnected
+            throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
+                "Camera service is currently unavailable", e);
+        }
+
+        return cam_layer;
+
+    }
+
+
+
+    /**
      * Remove a previously-added callback; the callback will no longer receive torch mode status
      * callbacks.
      *
@@ -292,6 +337,7 @@ public final class CameraManager {
             throws CameraAccessException {
         CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
         CameraDevice device = null;
+
         try {
 
             synchronized (mLock) {
@@ -318,6 +364,7 @@ public final class CameraManager {
                                 CameraAccessException.CAMERA_DISCONNECTED,
                                 "Camera service is currently unavailable");
                         }
+
                         cameraService.connectDevice(callbacks, id,
                                 mContext.getOpPackageName(), USE_CALLING_UID, holder);
                         cameraUser = ICameraDeviceUser.Stub.asInterface(holder.getBinder());
@@ -371,6 +418,7 @@ public final class CameraManager {
         } catch (CameraRuntimeException e) {
             throw e.asChecked();
         }
+
         return device;
     }
 
@@ -607,6 +655,7 @@ public final class CameraManager {
      * <p>In case of errors connecting to the camera service, will return an empty list.</p>
      */
     private ArrayList<String> getOrCreateDeviceIdListLocked() throws CameraAccessException {
+
         if (mDeviceIdList == null) {
             int numCameras = 0;
             ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
@@ -663,6 +712,7 @@ public final class CameraManager {
             }
             mDeviceIdList = deviceIdList;
         }
+
         return mDeviceIdList;
     }
 
-- 
2.7.4


From eb6ab6fedb3404f1e2ee977d26caab0f0f27ed03 Mon Sep 17 00:00:00 2001
From: liangji <[email protected]>
Date: Fri, 24 Feb 2023 11:12:11 +0800
Subject: [PATCH 3/3] improvement: update api for get remap for camera

Change-Id: Id662e7164ac51091a8336e2af0f7ea6f78a93340
Signed-off-by: liangji <[email protected]>
---
 api/current.txt                                    |  3 +-
 api/system-current.txt                             |  3 +-
 .../android/hardware/camera2/CameraManager.java    | 52 +++++++++++++++++++++-
 3 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/api/current.txt b/api/current.txt
index eb080b0..19b35f7 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -13358,7 +13358,8 @@ package android.hardware.camera2 {
   public final class CameraManager {
     method public android.hardware.camera2.CameraCharacteristics getCameraCharacteristics(java.lang.String) throws android.hardware.camera2.CameraAccessException;
     method public java.lang.String[] getCameraIdList() throws android.hardware.camera2.CameraAccessException;
-    method public int getCameraInfo(int) throws android.hardware.camera2.CameraAccessException;
+    method public android.util.ArrayMap<java.lang.Integer, java.lang.Integer> getCameraIdReMap() throws android.hardware.camera2.CameraAccessException;
+    method public int getCameraInfo(java.lang.String) throws android.hardware.camera2.CameraAccessException;
     method public void openCamera(java.lang.String, android.hardware.camera2.CameraDevice.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public void registerAvailabilityCallback(android.hardware.camera2.CameraManager.AvailabilityCallback, android.os.Handler);
     method public void registerTorchCallback(android.hardware.camera2.CameraManager.TorchCallback, android.os.Handler);
diff --git a/api/system-current.txt b/api/system-current.txt
index 84fb497..09fcae3 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -13700,7 +13700,8 @@ package android.hardware.camera2 {
   public final class CameraManager {
     method public android.hardware.camera2.CameraCharacteristics getCameraCharacteristics(java.lang.String) throws android.hardware.camera2.CameraAccessException;
     method public java.lang.String[] getCameraIdList() throws android.hardware.camera2.CameraAccessException;
-    method public int getCameraInfo(int) throws android.hardware.camera2.CameraAccessException;
+    method public android.util.ArrayMap<java.lang.Integer, java.lang.Integer> getCameraIdReMap() throws android.hardware.camera2.CameraAccessException;
+    method public int getCameraInfo(java.lang.String) throws android.hardware.camera2.CameraAccessException;
     method public void openCamera(java.lang.String, android.hardware.camera2.CameraDevice.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public void registerAvailabilityCallback(android.hardware.camera2.CameraManager.AvailabilityCallback, android.os.Handler);
     method public void registerTorchCallback(android.hardware.camera2.CameraManager.TorchCallback, android.os.Handler);
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index b21e085..89bf3aa 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -187,16 +187,55 @@ public final class CameraManager {
         CameraManagerGlobal.get().registerTorchCallback(callback, handler);
     }
 
+
+    /*
+     * keenon liangji add getCameraIdReMap()
+     *
+     */
+    @RequiresPermission(android.Manifest.permission.CAMERA)
+    public ArrayMap<Integer, Integer> getCameraIdReMap()
+            throws CameraAccessException {
+
+        int ret = 0;
+        ArrayMap<Integer, Integer> map = new ArrayMap<Integer, Integer>();
+        Log.w(TAG, "liangji getCameraIdReMap");
+        String[] camlist = getCameraIdList();
+
+        for (String id : camlist) {
+            int id_int;
+            try{
+                id_int = Integer.parseInt(id);
+            }
+            catch(NumberFormatException e){
+                id_int = 0;
+            }
+
+            Log.w(TAG, "liangji getCameraIdReMap add id = "+ id +" id_int = "+ id_int);
+            map.put(id_int, getCameraInfo(id));
+        }
+
+        return map;
+    }
+
+
     /**
      * keenon liangji add getCameraInfo()
      * parameters is 0, 1, 2, 3
      *
      */
     @RequiresPermission(android.Manifest.permission.CAMERA)
-    public int getCameraInfo(@NonNull int id)
+    public int getCameraInfo(@NonNull String cameraId)
             throws CameraAccessException {
         //keenon liangji add
         int cam_layer = 0;
+        int id;
+        try{
+            id = Integer.parseInt(cameraId);
+        }
+        catch(NumberFormatException e){
+            id = 0;
+        }
+
         ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
         if (cameraService == null) {
             throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
@@ -338,6 +377,7 @@ public final class CameraManager {
         CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
         CameraDevice device = null;
 
+        Log.w(TAG, "liangji openCameraDeviceUserAsync");
         try {
 
             synchronized (mLock) {
@@ -419,6 +459,15 @@ public final class CameraManager {
             throw e.asChecked();
         }
 
+        //keenon liangji add
+        Log.w(TAG, "liangji getCameraIdReMap in openCamera ");
+
+        ArrayMap<Integer, Integer> map = getCameraIdReMap();
+        System.out.println("0:" + map.get("0"));
+        Log.w(TAG, "liangji getCameraIdReMap in openCamera over and map size = "+ map.size());
+
+        //Log.w(TAG, "liangji getCameraIdList "+ temp[0] + ":" + temp[1]);
+        //keenon liangji end
         return device;
     }
 
@@ -656,6 +705,7 @@ public final class CameraManager {
      */
     private ArrayList<String> getOrCreateDeviceIdListLocked() throws CameraAccessException {
 
+        Log.w(TAG, "liangji getCameraIdList");
         if (mDeviceIdList == null) {
             int numCameras = 0;
             ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
-- 
2.7.4


【RK3288 android6 快捷按键gpio 时间上报】

https://blog.csdn.net/A08118139/article/details/129979951?spm=1001.2014.3001.5502
kernel

From bef1793dcbb264dea78c6c4758db1a2d27ed1427 Mon Sep 17 00:00:00 2001
From: liangji <[email protected]>
Date: Fri, 10 Mar 2023 14:36:44 +0800
Subject: [PATCH 2/2] feat(key): support key input

Change-Id: I599ac6e9d587d875ebb1c1ef428064fd1c618a86
Signed-off-by: liangji <[email protected]>
---
 arch/arm/boot/dts/rk3288-tb_8846.dts |  6 ++++
 drivers/input/keyboard/rk_keys.c     | 58 ++++++++++++++++++++++++++++++++++++
 include/uapi/linux/input.h           |  4 +++
 3 files changed, 68 insertions(+)

diff --git a/arch/arm/boot/dts/rk3288-tb_8846.dts b/arch/arm/boot/dts/rk3288-tb_8846.dts
index c4fcd7d..f368048 100644
--- a/arch/arm/boot/dts/rk3288-tb_8846.dts
+++ b/arch/arm/boot/dts/rk3288-tb_8846.dts
@@ -639,6 +639,12 @@
 			label = "recovery";
 			rockchip,adc_value = <4>;
 		};
+        liangji-key {
+            gpios = <&gpio7 GPIO_A1 GPIO_ACTIVE_HIGH>;
+            linux,code = <249>;
+            label = "liangji";
+            gpio-key,wakeup;
+        };
 		/*
 		menu-key {
 			linux,code = <59>;
diff --git a/drivers/input/keyboard/rk_keys.c b/drivers/input/keyboard/rk_keys.c
index 1071b54..a8ea878 100755
--- a/drivers/input/keyboard/rk_keys.c
+++ b/drivers/input/keyboard/rk_keys.c
@@ -36,6 +36,11 @@
 #include 
 #include 
 
+//keenon liangji add
+#include 
+#include 
+//keenon liangji end
+
 #define EMPTY_ADVALUE			950
 #define DRIFT_ADVALUE			70
 #define INVALID_ADVALUE			-1
@@ -53,6 +58,38 @@
 #define ADC_SAMPLE_JIFFIES	(100 / (MSEC_PER_SEC / HZ))	/* 100ms */
 #define WAKE_LOCK_JIFFIES	(1 * HZ)			/* 1s */
 
+//keenon liangji add 
+static struct timer_list test_timer;
+struct input_dev *input_global;
+bool flag_key = true;
+
+void timer_test_callback(unsigned long data)
+{
+    flag_key = true;
+    mod_timer(&test_timer, jiffies + msecs_to_jiffies(500));
+}
+
+static int __init timer_init(void)
+{
+    int ret;
+    pr_err("liangji timer test begin\n");
+    setup_timer(&test_timer, timer_test_callback, 0);
+    pr_err("liangji Setup timer to print in 3000ms (%ld)\n", jiffies);
+
+    ret = mod_timer(&test_timer, jiffies + msecs_to_jiffies(3000));
+    if(ret){
+        pr_err("liangji Timer start failed\n");
+        return ret;
+    }
+
+    return 0;
+}
+
+static void __exit timer_exit(void) {
+    del_timer(&test_timer);
+}
+//keenon liangji end
+
 enum rk_key_type {
 	TYPE_GPIO = 1,
 	TYPE_ADC
@@ -148,6 +185,21 @@ static irqreturn_t keys_isr(int irq, void *dev_id)
 
 	BUG_ON(irq != gpio_to_irq(button->gpio));
 
+    //keenon liangji add 
+    int irq_status = gpio_get_value(button->gpio);
+    if(flag_key == true)
+    {
+        flag_key = false;
+        pr_err("liangji send input event\n");
+        if(1==irq_status){
+            input_event(input, EV_KEY, button->code, 1-button->state);
+            input_sync(input);
+            udelay(50);
+            pr_err("liangji irq_status == 1 , button->state = %d\n", button->state);
+        }
+    }
+    //keenon liangji end
+
 	if (button->wakeup && pdata->in_suspend) {
 		button->state = 1;
 		key_dbg(pdata,
@@ -382,6 +434,12 @@ static int keys_probe(struct platform_device *pdev)
 	wake_lock_init(&ddata->wake_lock, WAKE_LOCK_SUSPEND, input->name);
 	device_init_wakeup(dev, wakeup);
 
+    //keenon liangji add
+    pr_err("liangji module_init(timer_init)\n");
+    module_init(timer_init);
+    module_exit(timer_exit);
+    //keenon liangji end
+
 	for (i = 0; i < ddata->nbuttons; i++) {
 		struct rk_keys_button *button = &ddata->button[i];
 
diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h
index a86f530..c08a5d8 100644
--- a/include/uapi/linux/input.h
+++ b/include/uapi/linux/input.h
@@ -473,6 +473,10 @@ struct input_keymap_entry {
 
 #define KEY_MICMUTE		248	/* Mute / unmute the microphone */
 
+//keenon liangji add 
+#define KEY_LIANGJI    249
+//keenon liangji end
+
 /* Code 255 is reserved for special needs of AT keyboard driver */
 
 #define BTN_MISC		0x100
-- 
2.7.4


framework

From c15d5be1b780a29a8e97e260d929ca0f7ae32837 Mon Sep 17 00:00:00 2001
From: liangji <[email protected]>
Date: Wed, 22 Feb 2023 16:48:01 +0800
Subject: [PATCH] feat: support key input event for unik

Change-Id: Idcd4bf9651793efc20ac9e38c0455a927801e8d6
Signed-off-by: liangji <[email protected]>
---
 native/include/android/keycodes.h       | 7 ++++++-
 native/include/input/InputEventLabels.h | 1 +
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/native/include/android/keycodes.h b/native/include/android/keycodes.h
index e391dc9..035fc40 100644
--- a/native/include/android/keycodes.h
+++ b/native/include/android/keycodes.h
@@ -728,7 +728,12 @@ enum {
     AKEYCODE_TV_KEYMOUSE_RIGHT = 281,
     AKEYCODE_TV_KEYMOUSE_UP = 282,
     AKEYCODE_TV_KEYMOUSE_DOWN = 283,
-    AKEYCODE_TV_KEYMOUSE_MODE_SWITCH = 284
+    AKEYCODE_TV_KEYMOUSE_MODE_SWITCH = 284,
+
+    //keenon liangji add
+    AKEYCODE_HAND_LEFT = 300
+    //keenon liangj end
+
 
     // NOTE: If you add a new keycode here you must also add it to several other files.
     //       Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
diff --git a/native/include/input/InputEventLabels.h b/native/include/input/InputEventLabels.h
index bcce2d3..ddd94be 100644
--- a/native/include/input/InputEventLabels.h
+++ b/native/include/input/InputEventLabels.h
@@ -67,6 +67,7 @@ static const InputEventLabel KEYCODES[] = {
     DEFINE_KEYCODE(VOLUME_DOWN),
     DEFINE_KEYCODE(POWER),
     DEFINE_KEYCODE(CAMERA),
+    DEFINE_KEYCODE(HAND_LEFT),
     DEFINE_KEYCODE(CLEAR),
     DEFINE_KEYCODE(A),
     DEFINE_KEYCODE(B),
-- 
2.7.4


framework/base

From ce5bd52b7a751f7e6ce732f336b7b17251d532da Mon Sep 17 00:00:00 2001
From: liangji <[email protected]>
Date: Wed, 22 Feb 2023 18:42:38 +0800
Subject: [PATCH 2/3] feat: support key input event for unik

Change-Id: Idbb707d26a72a60a33180bdfd212f0a6de238fc1
Signed-off-by: liangji <[email protected]>
---
 api/current.txt                                                      | 1 +
 api/system-current.txt                                               | 1 +
 core/java/android/view/KeyEvent.java                                 | 3 +++
 core/res/res/values/attrs.xml                                        | 1 +
 data/keyboards/Generic.kl                                            | 3 +++
 services/core/java/com/android/server/policy/PhoneWindowManager.java | 5 +++++
 6 files changed, 14 insertions(+)

diff --git a/api/current.txt b/api/current.txt
index 21f187a..eb080b0 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -35260,6 +35260,7 @@ package android.view {
     field public static final int KEYCODE_GRAVE = 68; // 0x44
     field public static final int KEYCODE_GUIDE = 172; // 0xac
     field public static final int KEYCODE_H = 36; // 0x24
+    field public static final int KEYCODE_HAND_LEFT = 300; // 0x12c
     field public static final int KEYCODE_HEADSETHOOK = 79; // 0x4f
     field public static final int KEYCODE_HELP = 259; // 0x103
     field public static final int KEYCODE_HENKAN = 214; // 0xd6
diff --git a/api/system-current.txt b/api/system-current.txt
index 9f77759..84fb497 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -37552,6 +37552,7 @@ package android.view {
     field public static final int KEYCODE_GRAVE = 68; // 0x44
     field public static final int KEYCODE_GUIDE = 172; // 0xac
     field public static final int KEYCODE_H = 36; // 0x24
+    field public static final int KEYCODE_HAND_LEFT = 300; // 0x12c
     field public static final int KEYCODE_HEADSETHOOK = 79; // 0x4f
     field public static final int KEYCODE_HELP = 259; // 0x103
     field public static final int KEYCODE_HENKAN = 214; // 0xd6
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index ffbede4..7d12a4a 100755
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -795,6 +795,7 @@ public class KeyEvent extends InputEvent implements Parcelable {
     public static final int KEYCODE_TV_MEDIA_MULT_BACKWARD = 292;
     public static final int KEYCODE_TV_MEDIA_PLAY = 293;
     public static final int KEYCODE_TV_MEDIA_PAUSE = 294;
+    public static final int KEYCODE_HAND_LEFT = 300;
 //$_rbox_$_modify_$ end
 
     private static final int LAST_KEYCODE = KEYCODE_TV_MEDIA_PAUSE;
@@ -1837,6 +1838,7 @@ public class KeyEvent extends InputEvent implements Parcelable {
             case KeyEvent.KEYCODE_MEDIA_RECORD:
             case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
             case KeyEvent.KEYCODE_CAMERA:
+            case KeyEvent.KEYCODE_HAND_LEFT:
             case KeyEvent.KEYCODE_FOCUS:
             case KeyEvent.KEYCODE_SEARCH:
             case KeyEvent.KEYCODE_BRIGHTNESS_DOWN:
@@ -1855,6 +1857,7 @@ public class KeyEvent extends InputEvent implements Parcelable {
             case KeyEvent.KEYCODE_MENU:
             case KeyEvent.KEYCODE_WAKEUP:
             case KeyEvent.KEYCODE_PAIRING:
+            case KeyEvent.KEYCODE_HAND_LEFT:
                 return true;
         }
         return false;
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index b1fb725..f0af115 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1570,6 +1570,7 @@ i
         <enum name="KEYCODE_VOLUME_DOWN" value="25" />
         <enum name="KEYCODE_POWER" value="26" />
         <enum name="KEYCODE_CAMERA" value="27" />
+        <enum name="KEYCODE_HAND_LEFT" value="300" />
         <enum name="KEYCODE_CLEAR" value="28" />
         <enum name="KEYCODE_A" value="29" />
         <enum name="KEYCODE_B" value="30" />
diff --git a/data/keyboards/Generic.kl b/data/keyboards/Generic.kl
index f10ba96..3463ea3 100644
--- a/data/keyboards/Generic.kl
+++ b/data/keyboards/Generic.kl
@@ -439,3 +439,6 @@ led 0x07 MUTE
 led 0x08 MISC
 led 0x09 MAIL
 led 0x0a CHARGING
+
+
+key 249 HAND_LEFT
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 037c6c1..23e7fde 100755
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2682,6 +2682,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
         final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
         final boolean canceled = event.isCanceled();
 
+        Log.d(TAG, "liangji2 interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
+                + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed
+                + " canceled=" + canceled);
+
+
         if (DEBUG_INPUT) {
             Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
                     + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed
-- 
2.7.4


keyevent 事件第二次拦截放行

From 630425722697ceadd93c5a6bedee29613578464e Mon Sep 17 00:00:00 2001
From: liangji <[email protected]>
Date: Fri, 10 Mar 2023 15:20:24 +0800
Subject: [PATCH] improvement: set beforedispatching 0 to let input event go

Change-Id: Iaaf7f1a551ae3023daac41824d331522854edfb6
Signed-off-by: liangji <[email protected]>
---
 .../java/com/android/server/policy/PhoneWindowManager.java  | 13 ++++++++++---
 .../jni/com_android_server_input_InputManagerService.cpp    |  7 ++++++-
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 23e7fde..85df545 100755
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -151,7 +151,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
     static final String TAG = "WindowManager";
     static final boolean DEBUG = false;
     static final boolean localLOGV = false;
-    static final boolean DEBUG_INPUT = false;
+    static final boolean DEBUG_INPUT = true;
     static final boolean DEBUG_KEYGUARD = false;
     static final boolean DEBUG_LAYOUT = false;
     static final boolean DEBUG_STARTING_WINDOW = false;
@@ -2688,11 +2688,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
 
 
         if (DEBUG_INPUT) {
-            Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
+            Log.d(TAG, "jiajia PhoneWindowManager.java interceptKeyBeforeDispatching keyCode=" + keyCode + " down=" + down + " repeatCount="
                     + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed
                     + " canceled=" + canceled);
         }
 
+        if (keyCode == 300)
+        {
+            Log.d(TAG, "liangji3 let key go!");
+            return 0;
+        }
         // If we think we might have a volume down & power key chord on the way
         // but we're not sure, then tell the dispatcher to wait a little while and
         // try again later before dispatching.
@@ -3134,8 +3139,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                 }
 
                 if (initialDown) {
+                    Log.d(TAG, "liangji keyCode fallbackActions put");
                     mFallbackActions.put(keyCode, fallbackAction);
                 } else if (event.getAction() == KeyEvent.ACTION_UP) {
+                    Log.d(TAG, "liangji keyCode fallbackActions remove");
                     mFallbackActions.remove(keyCode);
                     fallbackAction.recycle();
                 }
@@ -4953,7 +4960,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                                                 mKeyguardDelegate.isShowing()));
 
         if (DEBUG_INPUT) {
-            Log.d(TAG, "interceptKeyTq keycode=" + keyCode
+            Log.d(TAG, "jiajia PhoneWindowManager.java interceptKeyBeforeQueueing interceptKeyTq keycode=" + keyCode
                     + " interactive=" + interactive + " keyguardActive=" + keyguardActive
                     + " policyFlags=" + Integer.toHexString(policyFlags));
         }
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 4f656dd..d126627 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -877,6 +877,8 @@ void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
     // - Ask the window manager what to do with normal events and trusted injected events.
     // - For normal events wake and brighten the screen if currently off or dim.
     bool interactive = mInteractive.load();
+    int jiajia_keycode = keyEvent->getKeyCode();
+    ALOGD("jiajia NativeInputManager::interceptKeyBeforeQueueing start keycode= %d", jiajia_keycode);
     if (interactive) {
         policyFlags |= POLICY_FLAG_INTERACTIVE;
     }
@@ -886,16 +888,19 @@ void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
         jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
         jint wmActions;
         if (keyEventObj) {
+            ALOGD("jiajia NativeInputManager::interceptKeyBeforeQueueing obtain key event object for interceptKeyBeforeQUeue");
             wmActions = env->CallIntMethod(mServiceObj,
                     gServiceClassInfo.interceptKeyBeforeQueueing,
                     keyEventObj, policyFlags);
+
+            ALOGD("jiajia NativeInputManager::interceptKeyBeforeQueueing get interceptKeyBeforeQUeueing return vmActions = %d", wmActions);
             if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
                 wmActions = 0;
             }
             android_view_KeyEvent_recycle(env, keyEventObj);
             env->DeleteLocalRef(keyEventObj);
         } else {
-            ALOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
+            ALOGE("jiajia Failed to obtain key event object for interceptKeyBeforeQueueing.");
             wmActions = 0;
         }
 
-- 
2.7.4


device/rockchip/common

From cab7ef471cb91614c9423e1504e0e2ca0f0a711a Mon Sep 17 00:00:00 2001
From: liangji <[email protected]>
Date: Wed, 22 Feb 2023 16:38:00 +0800
Subject: [PATCH] feat: support key input event for unik

Change-Id: I6a690747348276ade3c2ced935d6809ca691cf3c
Signed-off-by: liangji <[email protected]>
---
 rk29-keypad.kl | 1 +
 1 file changed, 1 insertion(+)

diff --git a/rk29-keypad.kl b/rk29-keypad.kl
index f603fd3..ce6c1f9 100755
--- a/rk29-keypad.kl
+++ b/rk29-keypad.kl
@@ -7,3 +7,4 @@ key 143   WAKEUP
 key 158   BACK
 key 212   CAMERA
 key 217   SEARCH
+key 249   HAND_LEFT
-- 
2.7.4

【RK3399 android10 nanopc 自定义第三方apk安装,权限弹窗解决】

https://blog.csdn.net/A08118139/article/details/129724894?spm=1001.2014.3001.5502

【ESP32 通知铃 boost_en引脚发送脉冲】

https://blog.csdn.net/A08118139/article/details/129725729?spm=1001.2014.3001.5502

【RK3288 Android10 内核移植】

https://blog.csdn.net/A08118139/article/details/129725743?spm=1001.2014.3001.5502

【RK3399 android10 nanopc 时间24小时制显示】

http://t.csdn.cn/1fVTC

【RK3399 android10 nanopc 设置gboard为默认输入法】

【ESP32 通知铃 指令进入休眠模式】

【RK3288 android6 neoway 4G模块适配】

【485 IO板 支持modbus】

链接

【RK3288 hdmi副屏旋转】

【x86 工控机 配置桥接口+默认dns+ssh登录】

【可编程电源脚本使用】

链接

【RK3288 android6 UNIK 新板卡支持】

链接

【RK3288 Android6 S100 设置默认旋屏后概率性恢复】

链接

【RK3399 Android10 二合一 W3s 支持GM8775C mipi转lvds 10.1寸屏幕适配】

链接

【RK3399 Android10 二合一 W3S 支持ilitek触摸驱动】

【RK3399 Android10 二合一 支持ov4689 mipi摄像头】

链接

【ESP32 调度模块问题排查】

链接

【RK3288 Android10 UNIK 声音忽大忽小问题排查】

链接

【RK3399 ubuntu 工控机外设管理usb_scan v1】

链接

【RK3288 Android6 T2pro 支持移远和有方4G模块切换】

【RK3288 Android10 C30 支持sim卡拔掉不弹窗,及热插拔】

【RK3399 Android10 二合一,外设管理服务】

【RK3288 Android6 网络转发,工控机反向访问PC机】

链接

你可能感兴趣的:(嵌入式记录,ubuntu,linux,arm开发)