first commit

This commit is contained in:
Your Name
2026-02-07 20:22:48 +08:00
commit 1b9711d5e4
2270 changed files with 805872 additions and 0 deletions

Binary file not shown.

View File

@@ -0,0 +1,44 @@
#!/bin/bash
killall brcm_patchram_plus1
echo 0 > /sys/class/rfkill/rfkill0/state
sleep 2
echo 1 > /sys/class/rfkill/rfkill0/state
sleep 2
COMPATIBLE=$(cat /proc/device-tree/compatible)
if [[ $(expr $COMPATIBLE : ".*rk3588") -ne 0 ]]; then
brcm_patchram_plus1 --bd_addr_rand --enable_hci --no2bytes --use_baudrate_for_download --tosleep 200000 --baudrate 1500000 --patchram /system/etc/firmware/ /dev/ttyS8 &
hciconfig hci0 up
sleep 1
elif [[ $(expr $COMPATIBLE : ".*rk3568") -ne 0 ]]; then
brcm_patchram_plus1 --bd_addr_rand --enable_hci --no2bytes --use_baudrate_for_download --tosleep 200000 --baudrate 1500000 --patchram /system/etc/firmware/ /dev/ttyS8 &
hciconfig hci0 up
sleep 1
elif [[ $(expr $COMPATIBLE : ".*rk3566") -ne 0 ]]; then
brcm_patchram_plus1 --bd_addr_rand --enable_hci --no2bytes --use_baudrate_for_download --tosleep 200000 --baudrate 1500000 --patchram /system/etc/firmware/ /dev/ttyS0 &
hciconfig hci0 up
sleep 1
elif [[ $(expr $COMPATIBLE : ".*rk3399") -ne 0 ]]; then
brcm_patchram_plus1 --bd_addr_rand --enable_hci --no2bytes --use_baudrate_for_download --tosleep 200000 --baudrate 1500000 --patchram /system/etc/firmware/ /dev/ttyS0 &
hciconfig hci0 up
sleep 1
elif [[ $(expr $COMPATIBLE : ".*rk3288") -ne 0 ]]; then
brcm_patchram_plus1 --bd_addr_rand --enable_hci --no2bytes --use_baudrate_for_download --tosleep 200000 --baudrate 1500000 --patchram /system/etc/firmware/ /dev/ttyS0 &
hciconfig hci0 up
sleep 1
elif [[ $(expr $COMPATIBLE : ".*rk3326") -ne 0 ]]; then
brcm_patchram_plus1 --bd_addr_rand --enable_hci --no2bytes --use_baudrate_for_download --tosleep 200000 --baudrate 1500000 --patchram /system/etc/firmware/ /dev/ttyS1 &
hciconfig hci0 up
sleep 1
elif [[ $(expr $COMPATIBLE : ".*px30") -ne 0 ]]; then
brcm_patchram_plus1 --bd_addr_rand --enable_hci --no2bytes --use_baudrate_for_download --tosleep 200000 --baudrate 1500000 --patchram /system/etc/firmware/ /dev/ttyS1 &
hciconfig hci0 up
sleep 1
else
brcm_patchram_plus1 --bd_addr_rand --enable_hci --no2bytes --use_baudrate_for_download --tosleep 200000 --baudrate 1500000 --patchram /system/etc/firmware/ /dev/ttyS0 &
hciconfig hci0 up
sleep 1
fi

View File

@@ -0,0 +1,40 @@
#!/bin/bash
source /etc/orangepi-release
es8388_card=$(aplay -l | grep "es8388" | cut -d ':' -f 1 | cut -d ' ' -f 2)
jack_num=$(tinymix -D ${es8388_card} | grep "Headphone Jack" | cut -c1-2)
[[ ${BOARD} != orangepi900 ]] && exit
if [[ $(tinymix -D ${es8388_card} $jack_num | cut -d ":" -f 2) == *On ]]; then
#for playback
tinymix -D ${es8388_card} 25 2
tinymix -D ${es8388_card} 27 2
#for capture
tinymix -D ${es8388_card} 35 0
tinymix -D ${es8388_card} 36 0
tinymix -D ${es8388_card} 37 0
else
#for playback
tinymix -D ${es8388_card} 25 0
tinymix -D ${es8388_card} 27 0
#for capture
tinymix -D ${es8388_card} 35 1
tinymix -D ${es8388_card} 36 1
tinymix -D ${es8388_card} 37 1
fi
tinymix -D ${es8388_card} 3 4
tinymix -D ${es8388_card} 4 2
tinymix -D ${es8388_card} 14 192
tinymix -D ${es8388_card} 16 4
tinymix -D ${es8388_card} 17 4
tinymix -D ${es8388_card} 23 30
tinymix -D ${es8388_card} 24 30

View File

@@ -0,0 +1,5 @@
#!/bin/sh
killall start_rknn.sh > /dev/null 2>&1
killall rknn_server > /dev/null 2>&1
start_rknn.sh &

Binary file not shown.

BIN
external/packages/bsp/rk3588/usr/bin/rknn_demo vendored Executable file

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,7 @@
#!/bin/sh
while true
do
sleep 1
rknn_server #>/dev/null 2>&1
done

View File

@@ -0,0 +1,25 @@
#! /bin/sh
sleep 1
dev_path=/sys$1
state=`cat ${dev_path}/state`
if [ "$state"x != "config"x ] ; then
UDC=`ls /sys/class/udc/| awk '{print $1}'`
echo $UDC > /sys/kernel/config/usb_gadget/rockchip/UDC
functions=`cat /sys/kernel/config/usb_gadget/rockchip/configs/b.1/strings/0x409/configuration`
# if no "_" string to "cut" command, it will set the full string to output.
# add "_" to string functions avoiding no "_" case
i=2
functions=_${functions}
tmp=`echo $functions | cut -d _ -f $i`
until [ -z "$tmp" ]; do
if [ "$tmp" == "mtp" ]; then
mtp-server&
break
fi
i=`expr $i + 1`
tmp=`echo $functions | cut -d _ -f $i`
done
fi

620
external/packages/bsp/rk3588/usr/bin/usbdevice vendored Executable file
View File

@@ -0,0 +1,620 @@
#!/bin/sh -e
# Uncomment below to see more logs
# set -x
# Load default env variables from profiles
. /etc/profile
LOG_FILE=/tmp/usbdevice.log
USB_FUNCS_FILE=/tmp/.usbdevice
alias usb_enable='touch $USB_FUNCS_FILE'
alias usb_disable='rm -f $USB_FUNCS_FILE'
alias usb_is_enabled='[ -f $USB_FUNCS_FILE ]'
alias usb_set_started='echo $USB_FUNCS > $USB_FUNCS_FILE'
usb_get_started()
{
usb_is_enabled || return 0
cat $USB_FUNCS_FILE
}
CONFIGFS_DIR=/sys/kernel/config
USB_GROUP=rockchip
USB_STRINGS_ATTR=strings/0x409
USB_GADGET_DIR=$CONFIGFS_DIR/usb_gadget/$USB_GROUP
USB_GADGET_STRINGS_DIR=$USB_GADGET_DIR/$USB_STRINGS_ATTR
USB_FUNCTIONS_DIR=$USB_GADGET_DIR/functions
USB_CONFIGS_DIR=$USB_GADGET_DIR/configs/b.1
USB_CONFIGS_STRINGS_DIR=$USB_CONFIGS_DIR/$USB_STRINGS_ATTR
# Make sure that we own this session (pid equals sid)
if ! ps x -o cmd,pid,sid | grep -wq "$$$"; then
setsid $0 $@
exit $?
fi
# ---- helper functions
usb_msg()
{
logger -t $(basename $0) "[$$]: $@"
echo "[$(date +"%F %T")] $@"
}
usb_pid()
{
case $1 in
ums) echo 0x0000;;
mtp) echo 0x0001;;
uvc) echo 0x0005;;
adb) echo 0x0006;;
adb_mtp) echo 0x0011;;
adb_ums) echo 0x0018;;
adb_uvc) echo 0x0015;;
ntb_uvc) echo 0x0017;;
acm) echo 0x1005;;
*) echo 0x0019;;
esac
}
usb_instances()
{
for func in $@; do
VAR=$(echo $func | tr 'a-z' 'A-Z')_INSTANCES
eval echo "\${$VAR:-$func.gs0}"
done
}
usb_run_stage()
{
for f in $1_pre_$2_hook $1_$2 $1_post_$2_hook; do
type $f >/dev/null 2>/dev/null || continue
usb_msg "Run stage: $f"
eval $f || break
done
}
usb_wait_files()
{
for i in `seq 200`;do
fuser -s $@ 2>/dev/null && break
sleep .01
done
}
usb_release_files()
{
for i in `seq 200`;do
fuser -s -k $@ 2>/dev/null || break
sleep .01
done
}
# usage: usb_mount <src> <mountpoint> <options>
usb_mount()
{
mkdir -p $2
mountpoint -q $2 || mount $@
}
usb_umount()
{
mountpoint -q $1 || return 0
usb_release_files -m $1
umount $1
}
usb_symlink()
{
mkdir -p $1
[ -e $2 ] || ln -s $1 $2
}
usb_try_symlink()
{
usb_symlink $@ &>/dev/null || true
}
usb_write()
{
if echo "x$1" | grep -q "^x-"; then
OPTS=$1
shift
fi
FILE=$1
shift
if [ -r $FILE ] && [ "$(cat $FILE)" = "$@" ]; then
return 0
fi
echo $OPTS "$@" > $FILE
}
usb_try_write()
{
usb_write $@ &>/dev/null || true
}
usb_start_daemon()
{
NAME=$(echo $1 | sed "s#^[^ ]*/\([^ ]*\).*#\1#")
TAG_FILE=/tmp/.usb_$NAME
# Enable spawn
touch $TAG_FILE
# Already started
[ -z "$(usb_get_started)" ] || return 0
# Start and spawn background daemon
{
exec 3<&-
cd /
while usb_is_enabled; do
# Don't spawn after stopped
[ ! -f $TAG_FILE ] ||
start-stop-daemon -Sqx $@ || true
sleep .5
done
}&
}
usb_stop_daemon()
{
NAME=$(echo $1 | sed "s#^[^ ]*/\([^ ]*\).*#\1#")
TAG_FILE=/tmp/.usb_$NAME
# Stop and disable spawn
rm -f $TAG_FILE
start-stop-daemon -Kqox $@
}
usb_load_config()
{
USB_CONFIG_FILE=$(find /etc/ -name .usb_config | head -n 1)
[ -n "$USB_CONFIG_FILE" -a -r $USB_CONFIG_FILE ] || return 0
ums_parse()
{
grep "\<$1=" $USB_CONFIG_FILE | cut -d'=' -f2
}
UMS_FILE=$(ums_parse ums_block)
UMS_SIZE=$(ums_parse ums_block_size || echo 0)M
UMS_FSTYPE=$(ums_parse ums_block_type)
UMS_MOUNT=$([ "$(ums_parse ums_block_auto_mount)" != on ]; echo $?)
UMS_RO=$([ "$(ums_parse ums_block_ro)" != on ]; echo $?)
USB_FUNCS=$(grep "usb_.*_en" $USB_CONFIG_FILE | cut -d'_' -f2 | xargs)
}
# ---- adb
ADB_INSTANCES=${ADB_INSTANCES:-ffs.adb}
adb_prepare()
{
usb_mount adb /dev/usb-ffs/adb -o uid=2000,gid=2000 -t functionfs
usb_start_daemon /usr/bin/adbd
usb_wait_files -m /dev/usb-ffs/adb
}
adb_stop()
{
usb_stop_daemon /usr/bin/adbd
}
# ---- ntb
NTB_INSTANCES=${NTB_INSTANCES:-ffs.ntb}
ntb_prepare()
{
usb_mount ntb /dev/usb-ffs/ntb -o uid=2000,gid=2000 -t functionfs
}
# ---- uac1
uac1_prepare()
{
for f in $(find . -name "*_feature_unit"); do
echo 1 >$f
done
}
# ---- uac2
uac2_prepare()
{
uac1_prepare
}
# ---- mtp
mtp_prepare()
{
echo "MTP" > os_desc/interface.MTP/compatible_id
echo 1 > $USB_GADGET_DIR/os_desc/use
}
mtp_start()
{
usb_start_daemon /usr/bin/mtp-server
usb_wait_files /dev/mtp_usb
}
mtp_stop()
{
usb_stop_daemon /usr/bin/mtp-server
usb_release_files /dev/mtp_usb
echo 0 > $USB_GADGET_DIR/os_desc/use
}
# ---- acm
ACM_INSTANCES=${ACM_INSTANCES:-acm.gs6}
# ---- rndis
# Nothing special
# ---- uvc
UVC_INSTANCES=${UVC_INSTANCES:-uvc.gs6}
uvc_add_yuyv()
{
WIDTH=$(echo $1 | cut -d'x' -f1)
HEIGHT=$(echo $1 | cut -d'x' -f2)
DIR=${HEIGHT}p
[ ! -d $DIR ] || return 0
mkdir -p $DIR
echo $WIDTH > $DIR/wWidth
echo $HEIGHT > $DIR/wHeight
echo 333333 > $DIR/dwDefaultFrameInterval
echo $((WIDTH * HEIGHT * 20)) > $DIR/dwMinBitRate
echo $((WIDTH * HEIGHT * 20)) > $DIR/dwMaxBitRate
echo $((WIDTH * HEIGHT * 2)) > $DIR/dwMaxVideoFrameBufferSize
echo -e "333333\n666666\n1000000\n2000000" > $DIR/dwFrameInterval
}
uvc_add_mjpeg()
{
WIDTH=$(echo $1 | cut -d'x' -f1)
HEIGHT=$(echo $1 | cut -d'x' -f2)
DIR=${HEIGHT}p
[ ! -d $DIR ] || return 0
mkdir -p $DIR
echo $WIDTH > $DIR/wWidth
echo $HEIGHT > $DIR/wHeight
echo 333333 > $DIR/dwDefaultFrameInterval
echo $((WIDTH * HEIGHT * 20)) > $DIR/dwMinBitRate
echo $((WIDTH * HEIGHT * 20)) > $DIR/dwMaxBitRate
echo $((WIDTH * HEIGHT * 2)) > $DIR/dwMaxVideoFrameBufferSize
echo -e "333333\n666666\n1000000\n2000000" > $DIR/dwFrameInterval
}
uvc_add_h264()
{
WIDTH=$(echo $1 | cut -d'x' -f1)
HEIGHT=$(echo $1 | cut -d'x' -f2)
DIR=${HEIGHT}p
[ ! -d $DIR ] || return 0
mkdir -p $DIR
echo $WIDTH > $DIR/wWidth
echo $HEIGHT > $DIR/wHeight
echo 333333 > $DIR/dwDefaultFrameInterval
echo $((WIDTH * HEIGHT * 10)) > $DIR/dwMinBitRate
echo $((WIDTH * HEIGHT * 10)) > $DIR/dwMaxBitRate
echo -e "333333\n666666\n1000000\n2000000" > $DIR/dwFrameInterval
}
uvc_support_resolutions()
{
case ${1:-yuyv} in
yuyv) echo "640x480 1280x720";;
mjpeg) echo "640x480 1280x720 1920x1080 2560x1440 2592x1944";;
h264) echo "640x480 1280x720 1920x1080";;
esac
}
uvc_prepare()
{
UVC_DIR=$(pwd)
usb_symlink $UVC_DIR/control/header/h $UVC_DIR/control/class/fs/h
usb_symlink $UVC_DIR/control/header/h $UVC_DIR/control/class/ss/h
usb_symlink $UVC_DIR/streaming/header/h $UVC_DIR/streaming/class/fs/h
usb_symlink $UVC_DIR/streaming/header/h $UVC_DIR/streaming/class/hs/h
usb_symlink $UVC_DIR/streaming/header/h $UVC_DIR/streaming/class/ss/h
UVC_YUYV_RES=$(uvc_support_resolutions yuyv)
if [ -n "$UVC_YUYV_RES" ]; then
usb_try_symlink $UVC_DIR/streaming/uncompressed/u \
$UVC_DIR/streaming/header/h/u
cd $UVC_DIR/streaming/uncompressed/u
for res in $UVC_YUYV_RES; do
uvc_add_yuyv $res
done
fi
UVC_MJPEG_RES=$(uvc_support_resolutions mjpeg)
if [ -n "$UVC_MJPEG_RES" ]; then
usb_try_symlink $UVC_DIR/streaming/mjpeg/m \
$UVC_DIR/streaming/header/h/m
cd $UVC_DIR/streaming/mjpeg/m
for res in $UVC_MJPEG_RES; do
uvc_add_mjpeg $res
done
fi
UVC_H264_RES=$(uvc_support_resolutions h264)
if [ -n "$UVC_H264_RES" ]; then
usb_try_symlink $UVC_DIR/streaming/framebased/f \
$UVC_DIR/streaming/header/h/f
cd $UVC_DIR/streaming/framebased/f
for res in $UVC_H264_RES; do
uvc_add_h264 $res
done
usb_try_write -ne guidFormat "\\x48\\x32\\x36\\x34\\x00\\x00\\x10\\x00\\x80\\x00\\x00\\xaa\\x00\\x38\\x9b\\x71"
fi
}
# TODO: Start UVC daemon in uvc_start
# TODO: Stop UVC daemon in uvc_stop
# ---- hid
HID_INSTANCES=${HID_INSTANCES:-hid.usb0}
hid_prepare()
{
echo 1 > protocol
echo 1 > subclass
echo 8 > report_length
echo -ne "\\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0" \
> report_desc
}
# ---- ums
UMS_INSTANCES=${UMS_INSTANCES:-mass_storage.0}
ums_prepare()
{
if [ ! -f $UMS_FILE ]; then
usb_msg "Formating $UMS_FILE($UMS_SIZE) to $UMS_FSTYPE"
truncate -s $UMS_SIZE $UMS_FILE
mkfs.$UMS_FSTYPE $UMS_FILE || \
usb_msg "Failed to format $UMS_FILE to $UMS_FSTYPE"
fi
}
ums_stop()
{
echo > lun.0/file
usb_umount $UMS_MOUNTPOINT
[ "$UMS_MOUNT" -eq 1 ] || return 0
# Try auto fstype firstly
usb_mount $UMS_FILE $UMS_MOUNTPOINT -o sync 2>/dev/null || \
usb_mount $UMS_FILE $UMS_MOUNTPOINT -o sync -t $UMS_FSTYPE
}
ums_start()
{
case "$USB_STATE" in
CONFIGURED)
if [ "$(cat lun.0/ro)" != "$UMS_RO" ]; then
echo > lun.0/file
echo $UMS_RO > lun.0/ro
fi
if ! grep -wq $UMS_FILE lun.0/file; then
usb_umount $UMS_MOUNTPOINT
echo $UMS_FILE > lun.0/file
fi
;;
DISCONNECTED)
ums_stop
;;
esac
}
# ---- global
usb_init()
{
usb_msg "Initializing"
echo 0x2207 > idVendor
echo 0x0310 > bcdDevice
echo 0x0200 > bcdUSB
mkdir -p $USB_GADGET_STRINGS_DIR
SERIAL=$(grep Serial /proc/cpuinfo | cut -d':' -f2)
echo ${SERIAL:-0123456789ABCDEF} > $USB_GADGET_STRINGS_DIR/serialnumber
echo $USB_GROUP > $USB_GADGET_STRINGS_DIR/manufacturer
echo "rk3xxx" > $USB_GADGET_STRINGS_DIR/product
mkdir -p $USB_CONFIGS_DIR
echo 500 > $USB_CONFIGS_DIR/MaxPower
echo 0x1 > os_desc/b_vendor_code
echo MSFT100 > os_desc/qw_sign
ln -s $USB_CONFIGS_DIR os_desc/
mkdir -p $USB_CONFIGS_STRINGS_DIR
}
usb_funcs_grep()
{
echo $USB_FUNCS | xargs -n 1 | sort | uniq | grep $@ || true
}
usb_funcs_sort()
{
{
for func in $@; do
usb_funcs_grep -E $func
done
usb_funcs_grep -vE $(echo $@ | tr ' ' '|')
} | uniq | xargs
}
usb_prepare()
{
usb_load_config
# Allow function/variable overriding
[ -d /etc/usbdevice.d ] && . /etc/usbdevice.d/*
UMS_FILE=${UMS_FILE:-/userdata/ums_shared.img}
UMS_SIZE=${UMS_SIZE:-256M}
UMS_FSTYPE=${UMS_FSTYPE:-vfat}
UMS_MOUNT=${UMS_MOUNT:-0}
UMS_MOUNTPOINT=${UMS_MOUNTPOINT:-/mnt/ums}
UMS_RO=${UMS_RO:-0}
# Put RNDIS & UAC & UVC at first (required by kernel)
USB_FUNCS=$(usb_funcs_sort rndis uac uvc)
if [ ! -d $USB_GADGET_DIR ]; then
mountpoint -q $CONFIGFS_DIR || \
mount -t configfs none $CONFIGFS_DIR
mkdir -p $USB_GADGET_DIR
cd $USB_GADGET_DIR
# Global initialize
usb_run_stage usb init
fi
USB_STATE=$(cat /sys/class/android_usb/android0/state)
USB_UDC=$(ls /sys/class/udc/ | head -n 1)
# Parse started USB functions
OLD_FUNCS=$(usb_get_started)
# Stop old USB functions when USB functions changed
if [ -n "$OLD_FUNCS" ] && [ "$OLD_FUNCS" != "$USB_FUNCS" ]; then
usb_msg "Functions changed $OLD_FUNCS -> $USB_FUNCS"
usb_stop
fi
}
usb_start()
{
usb_msg "Starting functions: $USB_FUNCS"
echo $USB_FUNCS | tr ' ' '_' > $USB_CONFIGS_STRINGS_DIR/configuration
for func in $USB_FUNCS; do
for instance in $(usb_instances $func); do
usb_msg "Preparing instance: $instance"
if ! mkdir -p $USB_FUNCTIONS_DIR/$instance 2>/dev/null; then
usb_msg "Failed to create instance: $instance"
continue
fi
cd $USB_FUNCTIONS_DIR/$instance &>/dev/null || continue
usb_run_stage $func prepare
# Make symlink after prepared (required by UVC)
usb_symlink $USB_FUNCTIONS_DIR/$instance \
$USB_CONFIGS_DIR/f-$instance
done
done
usb_write $USB_GADGET_DIR/UDC $USB_UDC
for func in $USB_FUNCS; do
for instance in $(usb_instances $func); do
cd $USB_FUNCTIONS_DIR/$instance &>/dev/null || continue
usb_msg "Starting instance: $instance"
usb_run_stage $func start
done
done
# Store started functions
usb_set_started
}
usb_stop()
{
if [ -n "$OLD_FUNCS" ]; then
usb_msg "Stopping functions: $OLD_FUNCS"
fi
usb_write $USB_GADGET_DIR/UDC ""
for func in $USB_FUNCS; do
for instance in $(usb_instances $func); do
cd $USB_FUNCTIONS_DIR/$instance &>/dev/null || continue
usb_msg "Stopping instance: $instance"
usb_run_stage $func stop
done
done
rm -f $USB_CONFIGS_DIR/f-*
# Clear functions to avoid stopping them again
unset OLD_FUNCS
}
usb_restart()
{
usb_run_stage usb stop
usb_run_stage usb start
}
ACTION=${1:-update}
if [ "$ACTION" = update ]; then
usb_is_enabled || exit 0
fi
# Lock it
exec 3<$0
flock -x 3
echo "Starting $0 ${ACTION}, log saved to $LOG_FILE"
# Redirect outputs to log file
exec >>$LOG_FILE 2>&1
usb_msg "Handling ${ACTION} request"
usb_run_stage usb prepare
case "$ACTION" in
start|update)
usb_enable
usb_run_stage usb start
;;
stop)
usb_disable
usb_run_stage usb stop
;;
restart)
usb_enable
usb_run_stage usb restart
;;
*)
echo "Usage: usbdevice [start|stop|restart|update]" >&2
;;
esac
usb_msg "Done $ACTION request"
echo
# Unlock it
flock -u 3

View File

@@ -0,0 +1,271 @@
#ifndef _RKLLM_H_
#define _RKLLM_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* @typedef LLMHandle
* @brief A handle used to manage and interact with the large language model.
*/
typedef void* LLMHandle;
/**
* @enum LLMCallState
* @brief Describes the possible states of an LLM call.
*/
typedef enum {
RKLLM_RUN_NORMAL = 0, /**< The LLM call is in a normal running state. */
RKLLM_RUN_WAITING = 1, /**< The LLM call is waiting for complete UTF-8 encoded character. */
RKLLM_RUN_FINISH = 2, /**< The LLM call has finished execution. */
RKLLM_RUN_ERROR = 3, /**< An error occurred during the LLM call. */
RKLLM_RUN_GET_LAST_HIDDEN_LAYER = 4 /**< Retrieve the last hidden layer during inference. */
} LLMCallState;
/**
* @enum RKLLMInputType
* @brief Defines the types of inputs that can be fed into the LLM.
*/
typedef enum {
RKLLM_INPUT_PROMPT = 0, /**< Input is a text prompt. */
RKLLM_INPUT_TOKEN = 1, /**< Input is a sequence of tokens. */
RKLLM_INPUT_EMBED = 2, /**< Input is an embedding vector. */
RKLLM_INPUT_MULTIMODAL = 3, /**< Input is multimodal (e.g., text and image). */
} RKLLMInputType;
/**
* @enum RKLLMInferMode
* @brief Specifies the inference modes of the LLM.
*/
typedef enum {
RKLLM_INFER_GENERATE = 0, /**< The LLM generates text based on input. */
RKLLM_INFER_GET_LAST_HIDDEN_LAYER = 1, /**< The LLM retrieves the last hidden layer for further processing. */
} RKLLMInferMode;
/**
* @struct RKLLMExtendParam
* @brief The extend parameters for configuring an LLM instance.
*/
typedef struct {
int32_t base_domain_id; /**< base_domain_id */
uint8_t reserved[112]; /**< reserved */
} RKLLMExtendParam;
/**
* @struct RKLLMParam
* @brief Defines the parameters for configuring an LLM instance.
*/
typedef struct {
const char* model_path; /**< Path to the model file. */
int32_t max_context_len; /**< Maximum number of tokens in the context window. */
int32_t max_new_tokens; /**< Maximum number of new tokens to generate. */
int32_t top_k; /**< Top-K sampling parameter for token generation. */
float top_p; /**< Top-P (nucleus) sampling parameter. */
float temperature; /**< Sampling temperature, affecting the randomness of token selection. */
float repeat_penalty; /**< Penalty for repeating tokens in generation. */
float frequency_penalty; /**< Penalizes frequent tokens during generation. */
float presence_penalty; /**< Penalizes tokens based on their presence in the input. */
int32_t mirostat; /**< Mirostat sampling strategy flag (0 to disable). */
float mirostat_tau; /**< Tau parameter for Mirostat sampling. */
float mirostat_eta; /**< Eta parameter for Mirostat sampling. */
bool skip_special_token; /**< Whether to skip special tokens during generation. */
bool is_async; /**< Whether to run inference asynchronously. */
const char* img_start; /**< Starting position of an image in multimodal input. */
const char* img_end; /**< Ending position of an image in multimodal input. */
const char* img_content; /**< Pointer to the image content. */
RKLLMExtendParam extend_param; /**< Extend parameters. */
} RKLLMParam;
/**
* @struct RKLLMLoraAdapter
* @brief Defines parameters for a Lora adapter used in model fine-tuning.
*/
typedef struct {
const char* lora_adapter_path; /**< Path to the Lora adapter file. */
const char* lora_adapter_name; /**< Name of the Lora adapter. */
float scale; /**< Scaling factor for applying the Lora adapter. */
} RKLLMLoraAdapter;
/**
* @struct RKLLMEmbedInput
* @brief Represents an embedding input to the LLM.
*/
typedef struct {
float* embed; /**< Pointer to the embedding vector (of size n_tokens * n_embed). */
size_t n_tokens; /**< Number of tokens represented in the embedding. */
} RKLLMEmbedInput;
/**
* @struct RKLLMTokenInput
* @brief Represents token input to the LLM.
*/
typedef struct {
int32_t* input_ids; /**< Array of token IDs. */
size_t n_tokens; /**< Number of tokens in the input. */
} RKLLMTokenInput;
/**
* @struct RKLLMMultiModelInput
* @brief Represents multimodal input (e.g., text and image).
*/
typedef struct {
char* prompt; /**< Text prompt input. */
float* image_embed; /**< Embedding of the image (of size n_image_tokens * n_image_embed). */
size_t n_image_tokens; /**< Number of image tokens. */
} RKLLMMultiModelInput;
/**
* @struct RKLLMInput
* @brief Represents different types of input to the LLM via a union.
*/
typedef struct {
RKLLMInputType input_type; /**< Specifies the type of input provided (e.g., prompt, token, embed, multimodal). */
union {
const char* prompt_input; /**< Text prompt input if input_type is RKLLM_INPUT_PROMPT. */
RKLLMEmbedInput embed_input; /**< Embedding input if input_type is RKLLM_INPUT_EMBED. */
RKLLMTokenInput token_input; /**< Token input if input_type is RKLLM_INPUT_TOKEN. */
RKLLMMultiModelInput multimodal_input; /**< Multimodal input if input_type is RKLLM_INPUT_MULTIMODAL. */
};
} RKLLMInput;
/**
* @struct RKLLMLoraParam
* @brief Structure defining parameters for Lora adapters.
*/
typedef struct {
const char* lora_adapter_name; /**< Name of the Lora adapter. */
} RKLLMLoraParam;
/**
* @struct RKLLMPromptCacheParam
* @brief Structure to define parameters for caching prompts.
*/
typedef struct {
int save_prompt_cache; /**< Flag to indicate whether to save the prompt cache (0 = don't save, 1 = save). */
const char* prompt_cache_path; /**< Path to the prompt cache file. */
} RKLLMPromptCacheParam;
/**
* @struct RKLLMInferParam
* @brief Structure for defining parameters during inference.
*/
typedef struct {
RKLLMInferMode mode; /**< Inference mode (e.g., generate or get last hidden layer). */
RKLLMLoraParam* lora_params; /**< Pointer to Lora adapter parameters. */
RKLLMPromptCacheParam* prompt_cache_params; /**< Pointer to prompt cache parameters. */
} RKLLMInferParam;
/**
* @struct RKLLMResultLastHiddenLayer
* @brief Structure to hold the hidden states from the last layer.
*/
typedef struct {
const float* hidden_states; /**< Pointer to the hidden states (of size num_tokens * embd_size). */
int embd_size; /**< Size of the embedding vector. */
int num_tokens; /**< Number of tokens for which hidden states are stored. */
} RKLLMResultLastHiddenLayer;
/**
* @struct RKLLMResult
* @brief Structure to represent the result of LLM inference.
*/
typedef struct {
const char* text; /**< Generated text result. */
int32_t token_id; /**< ID of the generated token. */
RKLLMResultLastHiddenLayer last_hidden_layer; /**< Hidden states of the last layer (if requested). */
} RKLLMResult;
/**
* @typedef LLMResultCallback
* @brief Callback function to handle LLM results.
* @param result Pointer to the LLM result.
* @param userdata Pointer to user data for the callback.
* @param state State of the LLM call (e.g., finished, error).
*/
typedef void(*LLMResultCallback)(RKLLMResult* result, void* userdata, LLMCallState state);
/**
* @brief Creates a default RKLLMParam structure with preset values.
* @return A default RKLLMParam structure.
*/
RKLLMParam rkllm_createDefaultParam();
/**
* @brief Initializes the LLM with the given parameters.
* @param handle Pointer to the LLM handle.
* @param param Configuration parameters for the LLM.
* @param callback Callback function to handle LLM results.
* @return Status code (0 for success, non-zero for failure).
*/
int rkllm_init(LLMHandle* handle, RKLLMParam* param, LLMResultCallback callback);
/**
* @brief Loads a Lora adapter into the LLM.
* @param handle LLM handle.
* @param lora_adapter Pointer to the Lora adapter structure.
* @return Status code (0 for success, non-zero for failure).
*/
int rkllm_load_lora(LLMHandle handle, RKLLMLoraAdapter* lora_adapter);
/**
* @brief Loads a prompt cache from a file.
* @param handle LLM handle.
* @param prompt_cache_path Path to the prompt cache file.
* @return Status code (0 for success, non-zero for failure).
*/
int rkllm_load_prompt_cache(LLMHandle handle, const char* prompt_cache_path);
/**
* @brief Releases the prompt cache from memory.
* @param handle LLM handle.
* @return Status code (0 for success, non-zero for failure).
*/
int rkllm_release_prompt_cache(LLMHandle handle);
/**
* @brief Destroys the LLM instance and releases resources.
* @param handle LLM handle.
* @return Status code (0 for success, non-zero for failure).
*/
int rkllm_destroy(LLMHandle handle);
/**
* @brief Runs an LLM inference task synchronously.
* @param handle LLM handle.
* @param rkllm_input Input data for the LLM.
* @param rkllm_infer_params Parameters for the inference task.
* @param userdata Pointer to user data for the callback.
* @return Status code (0 for success, non-zero for failure).
*/
int rkllm_run(LLMHandle handle, RKLLMInput* rkllm_input, RKLLMInferParam* rkllm_infer_params, void* userdata);
/**
* @brief Runs an LLM inference task asynchronously.
* @param handle LLM handle.
* @param rkllm_input Input data for the LLM.
* @param rkllm_infer_params Parameters for the inference task.
* @param userdata Pointer to user data for the callback.
* @return Status code (0 for success, non-zero for failure).
*/
int rkllm_run_async(LLMHandle handle, RKLLMInput* rkllm_input, RKLLMInferParam* rkllm_infer_params, void* userdata);
/**
* @brief Aborts an ongoing LLM task.
* @param handle LLM handle.
* @return Status code (0 for success, non-zero for failure).
*/
int rkllm_abort(LLMHandle handle);
/**
* @brief Checks if an LLM task is currently running.
* @param handle LLM handle.
* @return Status code (0 if a task is running, non-zero for otherwise).
*/
int rkllm_is_running(LLMHandle handle);
#ifdef __cplusplus
}
#endif
#endif

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,5 @@
[Service]
ExecStartPre=/bin/sh -c 'exec /bin/sleep 10'
ExecStart=
ExecStart=-/sbin/agetty --noissue --autologin orangepi %I $TERM
Type=idle

View File

@@ -0,0 +1,5 @@
[Service]
ExecStartPre=/bin/sh -c 'exec /bin/sleep 10'
ExecStart=
ExecStart=-/sbin/agetty --noissue --autologin orangepi %I $TERM
Type=idle

View File

@@ -0,0 +1,12 @@
[Unit]
Description=Manage USB device functions
DefaultDependencies=no
After=local-fs.target
[Service]
Type=forking
ExecStart=/usr/bin/usbdevice start
ExecStop=/usr/bin/usbdevice stop
[Install]
WantedBy=sysinit.target

View File

@@ -0,0 +1,29 @@
# rockchip internal storage links: /dev/disk/by-partlabel and /dev/block/by-name
ACTION=="remove", GOTO="rk_internal_storage_end"
ENV{UDEV_DISABLE_ROCKCHIP_STORAGE_RULES_FLAG}=="1", GOTO="rk_internal_storage_end"
SUBSYSTEM!="block|mtd", GOTO="rk_internal_storage_end"
KERNEL!="mmcblk*[0-9]|rkflash*|rknand*|mtd*|nvme*", GOTO="rk_internal_storage_end"
# ignore partitions that span the entire disk
TEST=="whole_disk", GOTO="rk_internal_storage_end"
# for partitions import parent information
ENV{DEVTYPE}=="partition", IMPORT{parent}="ID_*"
# for rknand parameter partition name
ENV{DEVNAME}=="/dev/rknand*", ENV{DEVTYPE}=="disk", ENV{DEVPATH}=="/devices/virtual/block/rknand", ENV{ID_RKNAND_PART_NAME}=""
# for rkflash gpt partition name by-partlabel and /dev/block/by-name link
ENV{DEVTYPE}=="partition", ENV{PARTNAME}=="?*", SYMLINK+="disk/by-partlabel/$env{PARTNAME}", SYMLINK+="block/by-name/$env{PARTNAME}"
# for emmc gpt partition name /dev/block/by-name link
ENV{ID_PART_ENTRY_SCHEME}=="gpt", ENV{ID_PART_ENTRY_NAME}=="?*", SYMLINK+="block/by-name/$env{ID_PART_ENTRY_NAME}"
# for mtd partition name /dev/block/by-name link
ENV{DEVNAME}=="/dev/mtd*", ENV{DEVTYPE}=="mtd", ATTRS{name}=="?*", SYMLINK+="block/by-name/$attr{name}"
# for nvme partition name /dev/block/by-name link
ENV{DEVNAME}=="/dev/nvme*", ENV{DEVTYPE}=="disk", ATTRS{name}=="?*", SYMLINK+="block/by-name/$attr{name}"
LABEL="rk_internal_storage_end"

View File

@@ -0,0 +1 @@
SUBSYSTEM=="android_usb",ACTION=="change",RUN+="/usr/bin/usbdevice update"

View File

@@ -0,0 +1,29 @@
#!/bin/bash
if [[ -z $1 ]]; then
user=root
else
user=$1
fi
[[ -d /lib/systemd/system/getty@.service.d/ ]] && rm /lib/systemd/system/getty@.service.d/ -rf
[[ -f /lib/systemd/system/serial-getty@.service.d/override.conf ]] && rm /lib/systemd/system/serial-getty@.service.d/override.conf -f
[[ -d /etc/systemd/system/getty@.service.d/ ]] && rm /etc/systemd/system/getty@.service.d/ -rf
[[ -f /etc/systemd/system/serial-getty@.service.d/override.conf ]] && rm /etc/systemd/system/serial-getty@.service.d/override.conf -f
if [[ $1 == "-d" ]]; then
exit
fi
mkdir -p /etc/systemd/system/getty@.service.d/
mkdir -p /etc/systemd/system/serial-getty@.service.d/
cat <<-EOF > \
/etc/systemd/system/serial-getty@.service.d/override.conf
[Service]
ExecStartPre=/bin/sh -c 'exec /bin/sleep 10'
ExecStart=
ExecStart=-/sbin/agetty --noissue --autologin ${user} %I \$TERM
Type=idle
EOF
cp /etc/systemd/system/serial-getty@.service.d/override.conf \
/etc/systemd/system/getty@.service.d/override.conf

View File

@@ -0,0 +1,3 @@
#!/bin/bash
cat /proc/cpuinfo | grep "Serial"

View File

@@ -0,0 +1,20 @@
#!/bin/bash
sudo apt-get update
sudo apt-get install -y build-essential zlib1g-dev \
libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libsqlite3-dev \
libreadline-dev libffi-dev curl libbz2-dev
version=3.9.9
[[ -n $1 ]] && version=$1
# optimize build time with 100% CPU usage
CPUS=$(grep -c 'processor' /proc/cpuinfo)
CTHREADS="-j$((CPUS + CPUS/2))"
wget https://cdn.npmmirror.com/binaries/python/$version/Python-${version}.tgz
tar xvf Python-${version}.tgz
cd Python-${version}
./configure --enable-optimizations
make ${CTHREADS}
sudo make altinstall

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
#!/bin/bash
if [[ -z $1 ]]; then
user=root
else
user=$1
fi
sudo sed -i '/autologin-user=/d' /etc/lightdm/lightdm.conf.d/22-orangepi-autologin.conf
sudo echo autologin-user=${user} >> /etc/lightdm/lightdm.conf.d/22-orangepi-autologin.conf
sudo sed -i 's/root/anything/' /etc/pam.d/lightdm-autologin

View File

@@ -0,0 +1,5 @@
#!/bin/bash
sudo sed -i \
"s/autologin-user=.*/#&/" \
/etc/lightdm/lightdm.conf.d/22-orangepi-autologin.conf

View File

@@ -0,0 +1,77 @@
#!/bin/bash -x
export DISPLAY=${DISPLAY:-:0}
function prepare_env() {
# Try to figure out XAUTHORITY and DISPLAY
for pid in $(pgrep X 2>/dev/null || \
ls /proc|grep -ow "[0-9]*"|sort -rn); do
PROC_DIR=/proc/$pid
# Filter out non-X processes
readlink $PROC_DIR/exe|grep -qwE "X$|Xorg$" || continue
# Parse auth file and display from cmd args
export XAUTHORITY=$(cat $PROC_DIR/cmdline|tr '\0' '\n'| \
grep -w "\-auth" -A 1|tail -1)
export DISPLAY=$(cat $PROC_DIR/cmdline|tr '\0' '\n'| \
grep -w "^:.*" || echo ":0")
logger -t $0 "Found auth: $XAUTHORITY for dpy: $DISPLAY"
return
done
}
function xrandr_wrapper() {
xrandr --screen ${SCREEN:-0} $@
}
if ! xdpyinfo &>/dev/null; then
# Try to setup env
prepare_env
if ! xdpyinfo &>/dev/null; then
# Try to switch to an authorized user
for XUSER in root $(users);do
sudo -u $XUSER xdpyinfo &>/dev/null || continue
logger -t $0 "Switch to user: $XUSER"
sudo -u $XUSER $0; exit 0
done
logger -t $0 "Unable to contact Xserver!"
exit 0
fi
fi
TMP=$(mktemp)
SCREENS=$(xdpyinfo|grep screens|cut -d':' -f2)
for SCREEN in $(seq 0 ${SCREENS:-0}); do
# Get monitors and current mode info
xrandr_wrapper 2>&1|grep -oE "^.*connected|^.*\*"|tee $TMP
# Result:
# eDP-1 connected
# 1536x2048 59.99*
# DP-1 disconnected
# HDMI-1 connected
# 1920x1080 60.00*
#
# "*" means valid current mode.
# Make sure every connected monitors been enabled with a valid mode.
for MONITOR in $(grep -w connected $TMP|cut -d' ' -f1); do
# Find monitors without a valid current mode
if ! grep -w $MONITOR $TMP -A 1|grep "\*"; then
# Ether disabled or wrongly configured
xrandr_wrapper --output $MONITOR --auto
logger -t $0 "Output $MONITOR enabled."
fi
done
done
rm -rf $TMP
exit 0

View File

@@ -0,0 +1,4 @@
#!/bin/bash
sudo systemctl enable docker.service
sudo systemctl start docker.service

View File

@@ -0,0 +1,8 @@
#!/bin/bash
mmc_dev=$(ls -d -1 /dev/mmcblk* | grep -w 'mmcblk[0-9]' | cut -d '/' -f3)
sed -i "s/^rootdev=.*/rootdev=\/dev\/${mmc_dev}p2/" /boot/orangepiEnv.txt
sed -i '/boot/d' /etc/fstab
echo "/dev/${mmc_dev}p1 /boot vfat defaults 0 2" >> /etc/fstab
echo "Done"

View File

@@ -0,0 +1,9 @@
#!/bin/bash
while true; do
gpu_load=$(cat /sys/devices/platform/fb000000.gpu/devfreq/fb000000.gpu/load | cut -d "@" -f 1)
echo $(date "+%H:%M:%S") : GPU load is : ${gpu_load}%
sleep 1
done

View File

@@ -0,0 +1,4 @@
#!/bin/bash
wget -O install.sh \
http://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh

View File

@@ -0,0 +1,17 @@
#!/bin/bash
distributor_id=$(lsb_release -is)
distributor_id=${distributor_id,}
sudo apt-get remove -y docker docker-engine docker-ce docker.io
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg2 software-properties-common
curl -fsSL https://repo.huaweicloud.com/docker-ce/linux/${distributor_id}/gpg | sudo apt-key add -
echo "deb [arch=$(dpkg --print-architecture)] https://repo.huaweicloud.com/docker-ce/linux/${distributor_id} $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
sudo groupadd docker
sudo usermod -aG docker $USER

View File

@@ -0,0 +1,19 @@
#!/bin/bash
release=$(lsb_release -cs)
sudo apt update
if [[ $release =~ focal|bionic|buster ]]; then
sudo apt-get -y install qt5-default qttools5-dev-tools qtbase5-doc-html qt5-assistant qt5-doc
elif [[ $release =~ bullseye|bookworm|jammy ]]; then
sudo apt-get -y install qttools5-dev-tools qtbase5-doc-html qt5-assistant qt5-doc qt5-qmake qt5-qmake-bin
else
echo "Unsupported system!"
exit
fi
sudo apt-get -y install qtcreator qmlscene gdb qtdeclarative5-dev qtbase5-examples cmake
sudo chown orangepi:orangepi /usr/lib/aarch64-linux-gnu/qt5/examples -R
qmake -v

View File

@@ -0,0 +1,74 @@
#!/bin/bash
#mirror_url=http://mirrors.ustc.edu.cn
mirror_url=https://repo.huaweicloud.com
if [[ -n $1 && $1 =~ ros1|ros2 ]]; then
version=$1
else
echo "usage: install_ros.sh ros1/ros2"
exit
fi
release=$(lsb_release -cs)
if [[ $version == "ros1" && $release =~ focal ]]; then
[[ -f /etc/apt/sources.list.d/ros-latest.list ]] && sudo rm /etc/apt/sources.list.d/ros-latest.list
sudo sh -c "echo deb ${mirror_url}/ros/ubuntu $(lsb_release -sc) main > /etc/apt/sources.list.d/ros1.list"
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
sudo apt update
sudo apt install -y ros-noetic-desktop-full
sudo sh -c 'echo "source /opt/ros/noetic/setup.bash" >> /root/.bashrc'
echo "source /opt/ros/noetic/setup.bash" >> /home/orangepi/.bashrc
sudo apt install -y python3-rosdep python3-rosinstall python3-rosinstall-generator python3-wstool build-essential
sudo sh -c 'echo "151.101.84.133 raw.githubusercontent.com" >> /etc/hosts'
source /opt/ros/noetic/setup.bash
sudo rosdep init
rosdep update
exit
fi
if [[ $version == "ros2" && $release =~ focal ]]; then
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
echo "deb [arch=$(dpkg --print-architecture)] ${mirror_url}/ros2/ubuntu $(source /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list
sudo apt update
sudo apt install -y ros-galactic-desktop
sudo apt install -y ros-dev-tools
sudo sh -c 'echo "source /opt/ros/galactic/setup.bash" >> /root/.bashrc'
echo "source /opt/ros/galactic/setup.bash" >> /home/orangepi/.bashrc
source /opt/ros/galactic/setup.bash
ros2 -h
exit
fi
if [[ $version == "ros2" && $release =~ jammy ]]; then
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
echo "deb [arch=$(dpkg --print-architecture)] ${mirror_url}/ros2/ubuntu $(source /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list
sudo apt update
sudo apt install -y ros-humble-desktop
sudo apt install -y ros-dev-tools
sudo sh -c 'echo "source /opt/ros/humble/setup.bash" >> /root/.bashrc'
echo "source /opt/ros/humble/setup.bash" >> /home/orangepi/.bashrc
source /opt/ros/humble/setup.bash
ros2 -h
exit
fi
echo "Unsupported System!"

BIN
external/packages/bsp/rk3588/usr/local/bin/io vendored Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,4 @@
#!/bin/bash
sudo rm /etc/ssh/ssh_host_*
sudo dpkg-reconfigure openssh-server

View File

@@ -0,0 +1,4 @@
#!/bin/bash
sudo bash -c "echo device > /sys/kernel/debug/usb/fc000000.usb/mode"
sudo systemctl restart usbdevice

View File

@@ -0,0 +1,37 @@
#!/bin/bash
if [[ -n $1 && $1 =~ left|right|inverted|none ]]; then
type=$1
else
echo "usage: set_lcd_rotate.sh [left|right|inverted|none]"
exit
fi
case $1 in
left)
rotate=3
matrix="0 -1 1 1 0 0 0 0 1"
;;
right)
rotate=1
matrix="0 1 0 -1 0 1 0 0 1"
;;
inverted)
rotate=2
matrix="-1 0 1 0 -1 1 0 0 1"
;;
none)
rotate=0
matrix="1 0 0 0 1 0 0 0 1"
;;
esac
sudo sed -i '/TransformationMatrix/d' /usr/share/X11/xorg.conf.d/40-libinput.conf
sudo sed -i "/libinput touchscreen catchall/a Option \"TransformationMatrix\" \"${matrix}\"" /usr/share/X11/xorg.conf.d/40-libinput.conf
sudo sed -i '/extraargs=fbcon=rotate/d' /boot/orangepiEnv.txt
sudo bash -c "echo extraargs=fbcon=rotate:${rotate} >> /boot/orangepiEnv.txt"
sudo sed -i 's/bootlogo=true/bootlogo=false/g' /boot/orangepiEnv.txt
sudo sync
sudo reboot

View File

@@ -0,0 +1,9 @@
#!/bin/bash
sudo swapoff -a
sudo dd if=/dev/zero of=/swapfile bs=1G count=8
sudo chmod 0600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
sudo sed -i '/swapfile/d' /etc/fstab
sudo bash -c 'echo "/swapfile swap swap sw 0 0" >> /etc/fstab'

View File

@@ -0,0 +1,21 @@
#!/bin/bash
[[ -d ~/.vnc ]] && rm -rf ~/.vnc
vncserver
vncserver -kill :1
mv ~/.vnc/xstartup ~/.vnc/xstartup.bak
cat <<-EOF > \
~/.vnc/xstartup
#!/bin/bash
xrdb $HOME/.Xresources
startxfce4 &
EOF
chmod +x ~/.vnc/xstartup
vncserver
sudo chown orangepi:root .Xauthority
sync

Binary file not shown.

View File

@@ -0,0 +1,38 @@
#!/bin/bash
export DISPLAY=:0.0
#export GST_DEBUG=*:5
#export GST_DEBUG_FILE=/tmp/2.txt
echo "Start MIPI CSI Camera Preview!"
export XDG_RUNTIME_DIR=/run/user/1000
patterns="rkisp0-vir0 rkisp0-vir1 rkisp0-vir2 rkisp1-vir0 rkisp1-vir1 rkisp1-vir2"
devices_info=$(v4l2-ctl --list-devices)
#devices_id=("/dev/video44" "/dev/video53" "/dev/video62" "/dev/video71")
for pattern in $patterns; do
devices_id+=("$(echo "$devices_info" | awk -v pattern="$pattern" '$0 ~ pattern {getline; print $NF}')")
done
for device_id in "${devices_id[@]}"; do
if [[ -c "$device_id" ]]; then
gst-launch-1.0 v4l2src device=$device_id io-mode=4 ! \
video/x-raw,format=NV12,width=720,height=576,framerate=15/1 ! xvimagesink > /dev/null 2>&1 &
fi
done
echo "[Ctrl + C] exit"
while true
do
sleep 10
done
trap 'onCtrlC' INT
function onCtrlC () {
echo 'Ctrl+C is captured'
killall gst-launch-1.0
exit 0
}

View File

@@ -0,0 +1,11 @@
#!/bin/bash
export DISPLAY=:0.0
#export GST_DEBUG=*:5
#export GST_DEBUG_FILE=/tmp/2.txt
# xv vo
while true
do
mpv --hwdec=rkmpp --vd-lavc-software-fallback=no --vo=xv /usr/local/test.mp4
done

View File

@@ -0,0 +1,14 @@
#!/bin/bash
export DISPLAY=:0.0
if [[ -z $1 ]]; then
video=/usr/local/test.mp4
else
video=$1
fi
while true
do
gst-play-1.0 $video --videosink=xvimagesink
done

View File

@@ -0,0 +1,63 @@
#!/bin/bash
if [[ -n $1 && $1 =~ main|headset ]]; then
type=$1
else
echo "usage: test_record.sh main/headset"
exit
fi
source /etc/orangepi-release
card=$(aplay -l | grep "es8388" | cut -d ':' -f 1 | cut -d ' ' -f 2)
hdmi0_card=$(aplay -l | grep "hdmi0" | cut -d ':' -f 1 | cut -d ' ' -f 2)
if [[ ${BOARD} == orangepi5ultra ]]; then
hdmi1_card=$(aplay -l | grep "hdmi1" | cut -d ':' -f 1 | cut -d ' ' -f 2)
fi
if [[ $type == "main" ]]; then
amixer -c $card cset name='ALC Capture Max PGA' 4 >/dev/null
amixer -c $card cset name='ALC Capture Min PGA' 2 >/dev/null
amixer -c $card cset name='Capture Digital Volume' 192 >/dev/null
amixer -c $card cset name='Left Channel Capture Volume' 4 >/dev/null
amixer -c $card cset name='Right Channel Capture Volume' 4 >/dev/null
if [[ ${BOARD} == orangepi900 ]]; then
amixer -c $card cset name='Left Line Mux' 'Line 2L' >/dev/null
amixer -c $card cset name='Right Line Mux' 'Line 2R' >/dev/null
amixer -c $card cset name='Left Mixer Left Playback Switch' 'on' >/dev/null
else
amixer -c $card cset name='Left PGA Mux' 'Line 2L' >/dev/null
amixer -c $card cset name='Right PGA Mux' 'Line 2R' >/dev/null
amixer -c $card cset name='Differential Mux' 'Line 2' >/dev/null
fi
else
amixer -c $card cset name='ALC Capture Max PGA' 2 >/dev/null
amixer -c $card cset name='ALC Capture Min PGA' 1 >/dev/null
amixer -c $card cset name='Capture Digital Volume' 192 >/dev/null
amixer -c $card cset name='Left Channel Capture Volume' 4 >/dev/null
amixer -c $card cset name='Right Channel Capture Volume' 4 >/dev/null
if [[ ${BOARD} == orangepi900 ]]; then
amixer -c $card cset name='Left Line Mux' 'Line 1L' >/dev/null
amixer -c $card cset name='Right Line Mux' 'Line 1R' >/dev/null
amixer -c $card cset name='Left Mixer Left Playback Switch' 'off' >/dev/null
else
amixer -c $card cset name='Left PGA Mux' 'Line 1L' >/dev/null
amixer -c $card cset name='Right PGA Mux' 'Line 1R' >/dev/null
amixer -c $card cset name='Differential Mux' 'Line 1' >/dev/null
fi
fi
echo "Start recording: /tmp/test.wav"
arecord -D hw:${card},0 -d 5 -f cd -t wav /tmp/test.wav
echo "Start playing"
aplay /tmp/test.wav -D hw:${card},0
if [[ ${BOARD} == orangepi5ultra ]]; then
aplay /tmp/test.wav -D hw:${hdmi1_card},0
else
aplay /tmp/test.wav -D hw:${hdmi0_card},0
fi

View File

@@ -0,0 +1,7 @@
#!/bin/sh
echo "Start RKNN_DEMO Camera Preview!"
echo performance | tee $(find /sys/ -name *governor)
sudo service lightdm stop
/usr/bin/npu_transfer_proxy&
rknn_demo

View File

@@ -0,0 +1,29 @@
#!/bin/bash
if [[ -f /opt/ros/noetic/setup.bash ]]; then
source /opt/ros/noetic/setup.bash
roscore &
sleep 5
rosrun turtlesim turtlesim_node &
rosrun turtlesim turtle_teleop_key
fi
if [[ -f /opt/ros/galactic/setup.bash ]]; then
source /opt/ros/galactic/setup.bash
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener
fi
if [[ -f /opt/ros/humble/setup.bash ]]; then
source /opt/ros/humble/setup.bash
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_py listener
fi

View File

@@ -0,0 +1,13 @@
#!/bin/sh
export DISPLAY=:0.0
#export GST_DEBUG=*:5
#export GST_DEBUG_FILE=/tmp/2.txt
# server:
# vlc v4l2:// :v4l2-dev=/dev/video0 :v4l2-width=640 \
# :v4l2-height=480 --sout="#transcode{vcodec=h264,vb=800,scale=1,\
# acodec=mp4a,ab=128,channels=2,samplerate=44100}:rtp{sdp=rtsp://:8554/}" -I dummy
gst-launch-1.0 rtspsrc location=rtsp://192.168.31.163:8554/ ! \
! rtph264depay ! h264parse ! mppvideodec ! rkximagesink sync=false

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,3 @@
#!/bin/bash
echo host > /sys/kernel/debug/usb/fc000000.usb/mode

View File

@@ -0,0 +1,5 @@
#!/bin/bash
sudo bash -c "echo 0x100 > /sys/module/rk_vcodec/parameters/mpp_dev_debug"
sudo dmesg -c > /dev/null
dmesg -w

View File

@@ -0,0 +1,31 @@
# configuration for HDMI connection which just expose the
# audio out device
<confdir:pcm/hdmi.conf>
HDMI-OUT.pcm.hdmi.0 {
@args [ CARD DEVICE CTLINDEX AES0 AES1 AES2 AES3 ]
@args.CARD {
type string
}
@args.DEVICE {
type integer
}
@args.CTLINDEX {
type integer
}
@args.AES0 {
type integer
}
@args.AES1 {
type integer
}
@args.AES2 {
type integer
}
@args.AES3 {
type integer
}
type hw
card $CARD
}

View File

@@ -0,0 +1,65 @@
#
# Define aliases for various drivers
#
YMF724 cards.YMF744
YMF724F cards.YMF744
YMF740 cards.YMF744
YMF740C cards.YMF744
YMF754 cards.YMF744
CMIPCI cards.CMI8338
CMI8738 cards.CMI8338
CMI8738-SWIEC cards.CMI8338-SWIEC
CMI8738-MC4 cards.CMI8738-MC6
'E-mu APS' cards.EMU10K1
'GUS MAX' cards.GUS
'GUS ACE' cards.GUS
'GUS Extreme' cards.GUS
'AMD InterWave' cards.GUS
'Dynasonic 3-D' cards.GUS
'InterWave STB' cards.GUS
au8810 cards.AU8810
au8820 cards.AU8820
au8830 cards.AU8830
Prodigy71 cards.Aureon71
Prodigy71LT cards.Aureon71
Prodigy71HIFI cards.Aureon71
Aureon71Univ cards.Aureon71
VIA82XX-MODEM cards.ICH-MODEM
'MPU-401 UART' cards.MPU-401
'VX222/Old' cards.VX222
'VX222/v2' cards.VX222
'VX222/Mic' cards.VX222
'CMI8330/C3D' cards.CMI8330
'SB AWE' cards.SBAWE
'SB Pro' cards.SBPro
'PMac Burgundy' cards.PMac
'PMac DACA' cards.PMac
'PMac Tumbler' cards.PMac
'PMac Snapper' cards.PMac
'PMac Screamer' cards.PMac
'PMac AWACS' cards.PMac
'PMac Toonie' cards.PMacToonie
AppleOnbdAudio cards.PMacToonie
'USB US-X2Y' cards.US-X2Y
'Serial MIDI' cards.SerialMIDI
'Prodif Plus' cards.ProdifPlus
ESM1 cards.ES1968
ES1978 cards.ES1968
Allegro cards.Maestro3
Canyon3D-2 cards.Maestro3
Azalia cards.HDA-Intel
aaci-pl041 cards.AACI
AV66 cards.CMI8788
AV100 cards.CMI8788
AV200 cards.CMI8788
CMI8786 cards.CMI8788
CMI8787 cards.CMI8788
pistachio cards.pistachio-card
VC4-HDMI cards.vc4-hdmi
rockchip-hdmi0 cards.HDMI-OUT
<confdir:ctl/default.conf>
<confdir:pcm/default.conf>
<confdir:pcm/dmix.conf>
<confdir:pcm/dsnoop.conf>

View File

@@ -0,0 +1,17 @@
Use Case Configuration files
----------------------------
Library directories:
platforms/
codecs/
dsps/
Those directories are not inspected for the list of
available UCM configurations. They contain files
included from other UCMs.
Syntax, value names
-------------------
https://git.alsa-project.org/?p=alsa-lib.git;a=blob;f=include/use-case.h

View File

@@ -0,0 +1,23 @@
# Usecase for device HDMI0/Display Port stereo playback on rockchip platforms
# For Audio in I2S mode
SectionDevice."DP0" {
Comment "DP Port"
Value {
PlaybackPriority 500
PlaybackPCM "hw:${CardId}"
If.1 {
Condition {
Type ControlExists
Control "iface=CARD,name='rockchip-dp0 Jack'"
}
True {
JackControl "rockchip-dp0 Jack"
}
False {
JackControl "rockchip-dp0 Jack"
}
}
}
}

View File

@@ -0,0 +1,8 @@
Syntax 2
Comment "Rockchip DP card"
SectionUseCase."HDMI" {
File "Hdmi.conf"
Comment "DP Port"
}

View File

@@ -0,0 +1,116 @@
SectionVerb {
Value {
MinBufferLevel "512"
}
EnableSequence [
cset "name='Speaker Switch' off"
cset "name='Headphone Switch' off"
cset "name='Headset Mic Switch' off"
cset "name='Main Mic Switch' off"
cset "name='Speaker Switch' off"
cset "name='Headphone Switch' off"
cset "name='Headset Mic Switch' off"
cset "name='Main Mic Switch' off"
cset "name='PCM Volume' 192"
cset "name='Output 1 Playback Volume' 27"
cset "name='Output 2 Playback Volume' 27"
cset "name='Capture Digital Volume' 192"
cset "name='Left Channel Capture Volume' 3"
cset "name='Right Channel Capture Volume' 3"
cset "name='Left Mixer Left Playback Switch' on"
cset "name='Right Mixer Right Playback Switch' on"
cset "name='Capture Mute' off"
cset "name='Right PGA Mux' DifferentialR"
cset "name='Left PGA Mux' DifferentialL"
]
}
SectionDevice."Speaker" {
Comment "Speaker"
ConflictingDevice [
"Headphones"
]
Value {
PlaybackPriority 100
PlaybackPCM "hw:${CardId}"
}
EnableSequence [
cset "name='Speaker Switch' on"
]
DisableSequence [
cset "name='Speaker Switch' off"
]
}
SectionDevice."Mic" {
Comment "Internal Microphone"
ConflictingDevice [
"Headset"
]
Value {
CapturePriority 100
CapturePCM "hw:${CardId}"
}
EnableSequence [
cset "name='Differential Mux' Line 2"
cset "name='Main Mic Switch' on"
]
DisableSequence [
cset "name='Main Mic Switch' off"
]
}
SectionDevice."Headphones" {
Comment "Headphones"
ConflictingDevice [
"Speaker"
]
Value {
PlaybackPriority 200
PlaybackPCM "hw:${CardId}"
JackControl "Headphone Jack"
JackHWMute "Speaker"
}
EnableSequence [
cset "name='Headphone Switch' on"
]
DisableSequence [
cset "name='Headphone Switch' off"
]
}
SectionDevice."Headset" {
Comment "Headset Microphone"
ConflictingDevice [
"Mic"
]
Value {
CapturePriority 200
CapturePCM "hw:${CardId}"
JackControl "Headset Mic Jack"
JackHWMute "Mic"
}
EnableSequence [
cset "name='Differential Mux' Line 1"
cset "name='Headset Mic Switch' on"
]
DisableSequence [
cset "name='Headset Mic Switch' off"
]
}

View File

@@ -0,0 +1,8 @@
Syntax 2
Comment "Rockchip ES8388 card"
SectionUseCase."HiFi" {
File "HiFi.conf"
Comment "Default"
}

View File

@@ -0,0 +1,23 @@
# Usecase for device HDMI0/Display Port stereo playback on rockchip platforms
# For Audio in I2S mode
SectionDevice."HDMI0" {
Comment "HDMI"
Value {
PlaybackPriority 300
PlaybackPCM "hw:${CardId}"
If.1 {
Condition {
Type ControlExists
Control "iface=CARD,name='rockchip-hdmi0 Jack'"
}
True {
#JackControl "rockchip-hdmi0 Jack"
}
False {
#JackControl "rockchip-hdmi0 Jack"
}
}
}
}

View File

@@ -0,0 +1,8 @@
Syntax 2
Comment "Rockchip HDMI card"
SectionUseCase."HDMI" {
File "Hdmi.conf"
Comment "HDMI"
}

View File

@@ -0,0 +1,135 @@
#
# This is the toplevel file included from the alsa-lib.
#
# It allows to add extra lookups for the old kernels or so.
#
# You may specify the directory (relative to the toplevel) and
# the master configuration file which defines the verbs.
#
#
# Syntax version is reset for the master configuration file.
#
Syntax 3
Define.V1 "" # non-empty string to enable ucm v1 paths
Define.V2Module yes # empty string to disable
Define.V2Name yes # empty string to disable
If.driver {
Condition {
Type String
Empty "${CardNumber}"
}
True {
#
# The probed path for no-hw-card:
#
# ucm2/${OpenName}/${OpenName}.conf
#
UseCasePath {
legacy {
Directory "${OpenName}"
File "${OpenName}.conf"
}
}
}
False {
#
# The probed path when hw-card is found:
#
# ucm2/${KernelModule}/${KernelModule}.conf
# ucm2/${CardDriver}/${CardLongName}.conf
# ucm2/${CardDriver}/${CardDriver}.conf
#
If.V2Module {
Condition {
Type String
Empty "${var:V2Module}"
}
False {
Define.KernelModulePath "class/sound/card${CardNumber}/device/driver"
Define.KernelModule "${sys:$KernelModulePath}"
UseCasePath.module {
Directory "module"
File "${var:KernelModule}.conf"
}
}
}
If.V2Name {
Condition {
Type String
Empty "${var:V2Name}"
}
False.UseCasePath {
longname {
Directory "${CardDriver}"
File "${CardLongName}.conf"
}
driver {
Directory "${CardDriver}"
File "${CardDriver}.conf"
}
}
}
}
}
If.V1 {
Condition {
Type String
Empty "${var:V1}"
}
False.If.v1_driver {
Condition {
Type String
Empty "${CardNumber}"
}
True {
#
# The probed path for no-hw-card:
#
# ucm/${OpenName}/${OpenName}.conf
#
UseCasePath.v1_legacy {
Version 1
Directory "${OpenName}"
File "${OpenName}.conf"
}
}
False {
#
# The ucm v1 probed path when hw-card is found:
#
# ucm/${CardLongName}/${CardLongName}.conf
# ucm/${CardName}/${CardName}.conf or \
# ucm/${OpenName}/${OpenName}.conf
#
UseCasePath.v1_longname {
Version 1
Directory "${CardLongName}"
File "${CardLongName}.conf"
}
If.v1_hw {
Condition {
Type String
Haystack "${OpenName}"
Needle "hw:"
}
True.UseCasePath.v1_cardnamme {
Version 1
Directory "${CardName}"
File "${CardName}.conf"
}
False.UseCasePath.v1_openname {
Version 1
Directory "${OpenName}"
File "${OpenName}.conf"
}
}
}
}
}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,31 @@
# This file is part of PulseAudio.
#
# PulseAudio is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation; either version 2.1 of the
# License, or (at your option) any later version.
#
# PulseAudio is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
; For devices where a 'Headset Mic' or 'Headset Mic Boost' element exists
;
; See analog-output.conf.common for an explanation on the directives
[General]
priority = 88
description-key = analog-input-microphone-headset
[Element Capture]
switch = mute
volume = merge
override-map.1 = all
override-map.2 = all-left,all-right
.include analog-input-mic.conf.common

View File

@@ -0,0 +1,9 @@
[General]
description = analog-output-headphones
priority = 59
[Properties]
device.icon_name = rockchip-headphones
[Jack Headphone]
required = any

View File

@@ -0,0 +1,10 @@
[General]
description = HDMI / DisplayPort1
priority = 59
eld-device = 0
[Properties]
device.icon_name = rockchip-hdmi0
[Jack rockchip,hdmi0]
required = any

View File

@@ -0,0 +1,10 @@
[General]
description = HDMI / DisplayPort2
priority = 59
eld-device = 0
[Properties]
device.icon_name = rockchip-hdmi1
[Jack rockchip,hdmi1]
required = any

View File

@@ -0,0 +1,43 @@
# This file is part of PulseAudio.
#
# PulseAudio is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation; either version 2.1 of the
# License, or (at your option) any later version.
#
# PulseAudio is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
; This profile forces a speaker port even if we have no way of identifying it.
; See default.conf for explanations.
[General]
auto-profiles = yes
[Mapping hdmi-stereo]
description = Digital Stereo (HDMI)
device-strings = hw:%f
paths-output = hdmi-output-rockchip-1
channel-map = left,right
priority = 8
direction = output
description = Digital Stereo (HDMI 2)
device-strings = hw:%f
paths-output = hdmi-output-rockchip-2
channel-map = left,right
priority = 21
direction = output
; An example for defining multiple-sink profiles
#[Profile output:analog-stereo+output:iec958-stereo+input:analog-stereo]
#description = Foobar
#output-mappings = analog-stereo iec958-stereo
#input-mappings = analog-stereo

View File

@@ -0,0 +1,33 @@
# This file is part of PulseAudio.
#
# PulseAudio is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation; either version 2.1 of the
# License, or (at your option) any later version.
#
# PulseAudio is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
; This profile forces a speaker port even if we have no way of identifying it.
; See default.conf for explanations.
[General]
auto-profiles = yes
[Mapping analog-stereo]
device-strings = hw:%f
channel-map = left,right
paths-output = analog-output-headphones-rockchip
paths-input = analog-input-headset-mic-rockchip
priority = 5
; An example for defining multiple-sink profiles
#[Profile output:analog-stereo+output:iec958-stereo+input:analog-stereo]
#description = Foobar
#output-mappings = analog-stereo iec958-stereo
#input-mappings = analog-stereo

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,91 @@
???
person
bicycle
car
motorcycle
airplane
bus
train
truck
boat
traffic light
fire hydrant
???
stop sign
parking meter
bench
bird
cat
dog
horse
sheep
cow
elephant
bear
zebra
giraffe
???
backpack
umbrella
???
???
handbag
tie
suitcase
frisbee
skis
snowboard
sports ball
kite
baseball bat
baseball glove
skateboard
surfboard
tennis racket
bottle
???
wine glass
cup
fork
knife
spoon
bowl
banana
apple
sandwich
orange
broccoli
carrot
hot dog
pizza
donut
cake
chair
couch
potted plant
bed
???
dining table
???
???
toilet
???
tv
laptop
mouse
remote
keyboard
cell phone
microwave
oven
toaster
sink
refrigerator
???
book
clock
vase
scissors
teddy bear
hair drier
toothbrush

Binary file not shown.