codecheck_use_record

Step 1: Integrate CodeChecker into your build system

source ~/codechecker/venv/bin/activate
(CodeChecker venv) guoqiang@sun:~/depth_magic_ws/deptrum/build$ make clean
(CodeChecker venv) guoqiang@sun:~/depth_magic_ws/deptrum/build$ codechecker log --build "make depth_magic" --output ./compile_commands.json

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SSXzKo4g-1628490199204)(/home/guoqiang/.config/Typora/typora-user-images/image-20210808234253131.png)]

(CodeChecker venv) guoqiang@sun:~/depth_magic_ws/deptrum/build$ codechecker log --build "make depth_magic" --output ./compile_commands.json

Step 2: Analyze your code

Once the build is logged successfully and the compile_commands.json was created, you can analyze your project.

Step 3: Run the analysis

CodeChecker analyze ./compile_commands.json --enable sensitive --output ./reports

commond line

(CodeChecker venv) guoqiang@sun:~/depth_magic_ws/deptrum/build$ codechecker analyze ./compile_commands.json --enable sensitive --output ./reports

(CodeChecker venv) guoqiang@sun:~/depth_magic_ws/deptrum/build$ codechecker analyze ./compile_commands.json --enable sensitive --output ./reports

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nmrauKSl-1628490199206)(/home/guoqiang/.config/Typora/typora-user-images/image-20210809013628726.png)]

cause reports files
在这里插入图片描述

The ./reports directory is the “database” of CodeChecker that allows to manage further working steps.

Step 4: View the analysis results in the command line

(CodeChecker venv) guoqiang@sun:~/depth_magic_ws/deptrum/build$ codechecker parse ./reports/

在这里插入图片描述

Step 5: Hint: You can do the 1st and the 2nd step in one round by executing check

cd <repo root dir>/docs/examples
make clean
CodeChecker check --build "make" --output ./reports --clean \
    --enable sensitive

or to run on 22 threads both the compilation and the analysis:

CodeChecker check --jobs 22 --build "make clean ; make --jobs 22" \
    --output ./reports --clean --enable sensitive

step 6: Export the reports as static HTML files

You can visualize the results as static HTML by executing

(CodeChecker venv) guoqiang@sun:~/depth_magic_ws/deptrum/build$ codechecker parse -e html ./reports/ -o ./reports_html

result show:

google-build-using-namespace                    | STYLE    |                54
google-explicit-constructor                     | MEDIUM   |              1134
google-global-names-in-headers                  | STYLE    |                 3
google-runtime-int                              | LOW      |               695
google-runtime-references                       | STYLE    |              2006
misc-forwarding-reference-overload              | LOW      |                 8
misc-incorrect-roundings                        | HIGH     |                58
misc-macro-parentheses                          | MEDIUM   |               384
misc-misplaced-const                            | LOW      |                 9
misc-misplaced-widening-cast                    | HIGH     |                 7
misc-redundant-expression                       | MEDIUM   |                19
misc-sizeof-container                           | HIGH     |                 3
misc-sizeof-expression                          | HIGH     |                 5
misc-suspicious-enum-usage                      | HIGH     |                 4
misc-unconventional-assign-operator             | MEDIUM   |               174
misc-unused-using-decls                         | LOW      |                 1
modernize-deprecated-headers                    | LOW      |               106
modernize-replace-auto-ptr                      | LOW      |                 1
optin.cplusplus.VirtualCall                     | MEDIUM   |                 1
performance-faster-string-find                  | LOW      |                 5
performance-inefficient-string-concatenation    | LOW      |                 1
performance-inefficient-vector-operation        | LOW      |                 2
performance-move-const-arg                      | MEDIUM   |                 5
performance-move-constructor-init               | MEDIUM   |                 1
performance-noexcept-move-constructor           | MEDIUM   |                44
performance-type-promotion-in-math-fn           | LOW      |                 1
performance-unnecessary-copy-initialization     | LOW      |                 4
performance-unnecessary-value-param             | LOW      |               113
security.FloatLoopCounter                       | MEDIUM   |                 8
unix.API                                        | MEDIUM   |                 1
unix.Malloc                                     | MEDIUM   |                 1
------------------------------------------------------------------------------

----==== Severity Statistics ====----
----------------------------
Severity | Number of reports
----------------------------
HIGH     |               132
MEDIUM   |              2068
LOW      |              2332
STYLE    |              2063
----------------------------

To view statistics in a browser run:
> firefox ./reports_html/statistics.html

To view the results in a browser run:
> firefox ./reports_html/index.html
(CodeChecker venv) guoqiang@sun:~/depth_magic_ws/deptrum/build$

在这里插入图片描述

<!-- 货物信息 table 页面 --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="../../layui/css/layui.css"> <link rel="stylesheet" href="../../css/diy.css"> </head> <body> <div class="section1"> <!-- 内容主体区域 --> <div class="manu manu-btns" style="padding: 15px;"> <form class="layui-form" action=""> <div class="form-input-box-s layui-form-item"> <div class="input-box"> <label class="layui-form-label">仓库名称</label> <div class="layui-input-block block input-i"> <input type="text" name="title" required lay-verify="required" autocomplete="off" class="layui-input"> </div> </div> <div class="input-box"> <label class="layui-form-label">货物名称</label> <div class="layui-input-block block input-i"> <input type="text" name="title" required lay-verify="required" autocomplete="off" class="layui-input"> </div> </div> <div class="input-box"> <label class="layui-form-label">货物分类</label> <div class="layui-input-block block select"> <select name="interest" lay-filter="classification_of_goods" id="classification_of_goods"> <option value=""></option> </select> </div> </div> <div class="input-box"> <label class="layui-form-label">存放位置</label> <div class="layui-input-block block input-i"> <input type="text" name="title" required lay-verify="required" autocomplete="off" class="layui-input"> </div> </div> </div> </form> <div class="buts"> <button type="button" class="layui-btn layui-btn-normal" id="inquire"><span>查询</span></button> <button type="button" class="layui-btn layui-btn-normal" id="reset"><span>重置</span></button> <button type="button" class="layui-btn layui-btn-normal" id="delete" style="display: none"><span>删除</span></button> <button type="button" class="layui-btn layui-btn-normal" target="main_self_frame" id="add" style="display: none"><span>新增</span></button> </div> <div class="Customize-the-box"> <div class="circle"></div> <div class="circle"></div> <div class="card-inner"></div> </div> </div> <div class="table"> <table class="layui-hide" id="goods_information" lay-filter="goods_information"></table> <script type="text/html" id="toolbarDemo"> <div class="layui-btn-container"> {{# if(d.add_procurement_information>0){ }} <button class="layui-btn layui-btn-sm" lay-event="procurement_information">采购</button> {{# } }} {{# if(d.add_storage_record>0){ }} <button class="layui-btn layui-btn-sm" lay-event="storage_record">入库</button> {{# } }} {{# if(d.add_outbound_record>0){ }} <button class="layui-btn layui-btn-sm" lay-event="outbound_record">出库</button> {{# } }} {{# if(d.add_inventory_records>0){ }} <button class="layui-btn layui-btn-sm" lay-event="inventory_records">盘点</button> {{# } }} {{# if(d.add_price_adjustment_record>0){ }} <button class="layui-btn layui-btn-sm" lay-event="price_adjustment_record">调价</button> {{# } }} {{# if(d.detail_flag){ }} <button class="layui-btn layui-btn-sm" lay-event="detail">详情</button> {{# } }} </div> </script> </div> </div> </body> <script src="../../layui/layui.js"></script> <script src="../../js/index.js"></script> <script src="../../js/base.js"></script> <script src="../../js/axios.min.js"></script> <script> var BaseUrl = baseUrl() layui.use(['element', 'layer', 'laydate', 'util'], function () { var element = layui.element , layer = layui.layer , laydate = layui.laydate , util = layui.util , table = layui.table , $ = layui.$; let personInfo = JSON.parse(sessionStorage.personInfo) let user_group = personInfo.user_group let use_id = personInfo.user_id let url = BaseUrl + '/api/goods_information/get_list?like=0' let deletes = document.querySelector('#delete') let add = document.querySelector('#add') add.addEventListener('click', () => { layopen_add("./view_add.html") }) let sqlwhere let data_data = {size: 10, orderby: 'create_time desc'} let detail_flag = false; // 获取路径权限 async function get_list() { let {data: ren} = await axios.get(BaseUrl + '/api/auth/get_list', { params: { user_group: personInfo.user_group } }) } get_list() // 权限判断 /** * 获取路径对应操作权限 鉴权 * @param {String} action 操作名 */ function $check_action(path1, action = "get") { var o = $get_power(path1); if (o && o[action] != 0 && o[action] != false) { return true; } return false; } if ($check_action('/goods_information/table', 'del') || $check_action('/goods_information/view', 'del')) { deletes.style.display = "block" } if ($check_action('/goods_information/table', 'add') || $check_action('/goods_information/view', 'add')) { add.style.display = "block" } if ($check_action('/goods_information/view', 'get') || $check_action('/goods_information/view', 'set')) { detail_flag = true; } /** * 获取权限 * @param {String} path 路由路径 */ function $get_power(path) { var list_data = JSON.parse(sessionStorage.list_data) var list = list_data; var obj; for (var i = 0; i < list.length; i++) { var o = list[i]; if (o.path === path) { obj = o; break; } } return obj; } var path1 function getpath() { var list_data = JSON.parse(sessionStorage.list_data) for (var i = 0; i < list_data.length; i++) { var o = list_data[i]; if (o.path === "/goods_information/table") { console.log(o.path); path1 = o.path $get_power(o.path) } } } getpath() /** * 注册时是否有显示或操作字段的权限 * @param {String} action 操作名 * @param {String} field <span>查询</span>的字段 * @param {String} path 路径 */ function $check_register_field(action, field, path1) { var o = $get_power(path1); var auth; if (o && o[action] != 0 && o[action] != false) { auth = o["field_" + action]; } if (auth) { return auth.indexOf(field) !== -1; } return false; } /** * 是否有显示或操作字段的权限 * @param {String} action 操作名 * @param {String} field <span>查询</span>的字段 */ function $check_field(action, field, path1) { var o = $get_power(path1); var auth; if (o && o[action] != 0 && o[action] != false) { auth = o["field_" + action]; } if (auth) { return auth.indexOf(field) !== -1; } return false; } /** * 是否有显示或操作支付的权限 * @param {String} path 路径 */ function $check_pay(path) { let o = $get_power(path); if (o){ let option = JSON.parse(o.option); if (option.pay) return true } return false; } /** * 获取路径对应操作权限 鉴权 * @param {String} action 操作名 */ function $check_exam(path1, action = "get") { var o = $get_power(path1); if (o) { var option = JSON.parse(o.option); if (option[action]) return true } return false; } function $check_option(path,op) { var o = $get_power(path); if (o){ var option = JSON.parse(o.option); if (option[op]) return true } return false; } let token = sessionStorage.token || null table.render({ elem: '#goods_information' , toolbar: true , url: url , headers: { 'x-auth-token': token, 'Content-Type': 'application/json' } ,limits: [10] , page: { layout: ['limit', 'count', 'prev', 'page', 'next', 'skip'] //,curr: 5 , groups: 1 , first: false , last: false } , cols: [[ {type: 'checkbox', fixed: 'left'} , { field: 'warehouse_name', width: 180, title: '仓库名称', sort: true } , { field: 'goods_number', width: 180, title: '货物编号', sort: true } , { field: 'name_of_goods', width: 180, title: '货物名称', sort: true } , { field: 'classification_of_goods', width: 180, title: '货物分类', sort: true } , { field: 'goods_specifications', width: 180, title: '货物规格', sort: true } , { field: 'price_of_goods', width: 180, title: '货物价格', sort: true } , { field: 'inventory_of_goods', width: 180, title: '货物库存', sort: true } , { field: 'storage_location', width: 180, title: '存放位置', sort: true } , { field: 'description_of_the_goods', width: 180, title: '货物描述', sort: true } , { field: 'create_time', width : '20%', title : '新增时间', sort : true, templet : "<div>{{layui.util.toDateString(d.create_time, 'yyyy-MM-dd HH:mm:ss')}}</div>" } , { field: 'update_time', width : '20%', title : '更新时间', sort : true, templet : "<div>{{layui.util.toDateString(d.update_time, 'yyyy-MM-dd HH:mm:ss')}}</div>" } , { field: 'operate', title : '操作', sort : true, width : '20%', fixed : 'right', toolbar : "#toolbarDemo" } ]] , done: function (res, curr, count) { // 表格渲染完成之后的回调 if (res.count == null) { // 无数据时直接返回了 return; } if ($check_field('get', 'warehouse_name', path1)) { // console.log("显示") } else { $("[data-field='warehouse_name']").css('display', 'none'); } if ($check_field('get', 'goods_number', path1)) { // console.log("显示") } else { $("[data-field='goods_number']").css('display', 'none'); } if ($check_field('get', 'name_of_goods', path1)) { // console.log("显示") } else { $("[data-field='name_of_goods']").css('display', 'none'); } if ($check_field('get', 'classification_of_goods', path1)) { // console.log("显示") } else { $("[data-field='classification_of_goods']").css('display', 'none'); } if ($check_field('get', 'goods_specifications', path1)) { // console.log("显示") } else { $("[data-field='goods_specifications']").css('display', 'none'); } if ($check_field('get', 'price_of_goods', path1)) { // console.log("显示") } else { $("[data-field='price_of_goods']").css('display', 'none'); } if ($check_field('get', 'inventory_of_goods', path1)) { // console.log("显示") } else { $("[data-field='inventory_of_goods']").css('display', 'none'); } if ($check_field('get', 'storage_location', path1)) { // console.log("显示") } else { $("[data-field='storage_location']").css('display', 'none'); } if ($check_field('get', 'description_of_the_goods', path1)) { // console.log("显示") } else { $("[data-field='description_of_the_goods']").css('display', 'none'); } for (var i = 0; i < res.data.length; i++) { let limits = res.data[i].procurement_information_limit_times; let index = i if (limits > 0) { let params = { source_table: "goods_information", source_id: res.data[i].goods_information_id, source_user_id: use_id } axios.get(BaseUrl + '/api/procurement_information/count', { params }).then(count => { if (count) { if (count.data.result >= limits) { $('tr[data-index="' + index + '"] .layui-table-cell').find("[lay-event='procurement_information']").hide(); } } }) } } for (var i = 0; i < res.data.length; i++) { let limits = res.data[i].storage_record_limit_times; let index = i if (limits > 0) { let params = { source_table: "goods_information", source_id: res.data[i].goods_information_id, source_user_id: use_id } axios.get(BaseUrl + '/api/storage_record/count', { params }).then(count => { if (count) { if (count.data.result >= limits) { $('tr[data-index="' + index + '"] .layui-table-cell').find("[lay-event='storage_record']").hide(); } } }) } } for (var i = 0; i < res.data.length; i++) { let limits = res.data[i].outbound_record_limit_times; let index = i if (limits > 0) { let params = { source_table: "goods_information", source_id: res.data[i].goods_information_id, source_user_id: use_id } axios.get(BaseUrl + '/api/outbound_record/count', { params }).then(count => { if (count) { if (count.data.result >= limits) { $('tr[data-index="' + index + '"] .layui-table-cell').find("[lay-event='outbound_record']").hide(); } } }) } } for (var i = 0; i < res.data.length; i++) { let limits = res.data[i].inventory_records_limit_times; let index = i if (limits > 0) { let params = { source_table: "goods_information", source_id: res.data[i].goods_information_id, source_user_id: use_id } axios.get(BaseUrl + '/api/inventory_records/count', { params }).then(count => { if (count) { if (count.data.result >= limits) { $('tr[data-index="' + index + '"] .layui-table-cell').find("[lay-event='inventory_records']").hide(); } } }) } } for (var i = 0; i < res.data.length; i++) { let limits = res.data[i].price_adjustment_record_limit_times; let index = i if (limits > 0) { let params = { source_table: "goods_information", source_id: res.data[i].goods_information_id, source_user_id: use_id } axios.get(BaseUrl + '/api/price_adjustment_record/count', { params }).then(count => { if (count) { if (count.data.result >= limits) { $('tr[data-index="' + index + '"] .layui-table-cell').find("[lay-event='price_adjustment_record']").hide(); } } }) } } // 重新渲染 } , page: true, request : { limitName: 'size' } , response: { statusName: 'code', //规定返回/Back的状态码字段为code statusCode : 200 //规定成功的状态码为200 } , parseData: function (res) { // 跨表按钮 if ($check_action('/procurement_information/table', 'add') || $check_action('/procurement_information/view', 'add')) { for (var i = 0; i < res.result.list.length; i++) { res.result.list[i].add_procurement_information = 1 } } if ($check_action('/storage_record/table', 'add') || $check_action('/storage_record/view', 'add')) { for (var i = 0; i < res.result.list.length; i++) { res.result.list[i].add_storage_record = 1 } } if ($check_action('/outbound_record/table', 'add') || $check_action('/outbound_record/view', 'add')) { for (var i = 0; i < res.result.list.length; i++) { res.result.list[i].add_outbound_record = 1 } } if ($check_action('/inventory_records/table', 'add') || $check_action('/inventory_records/view', 'add')) { for (var i = 0; i < res.result.list.length; i++) { res.result.list[i].add_inventory_records = 1 } } if ($check_action('/price_adjustment_record/table', 'add') || $check_action('/price_adjustment_record/view', 'add')) { for (var i = 0; i < res.result.list.length; i++) { res.result.list[i].add_price_adjustment_record = 1 } } if ($check_pay('/goods_information/table')) { for (var i = 0; i < res.result.list.length; i++) { res.result.list[i].check_pay = true } } if ($check_action('/goods_information/view', 'set') || $check_action('/goods_information/view', 'get')) { for (var i = 0; i < res.result.list.length; i++) { res.result.list[i].detail_flag = detail_flag } } return { "code": 200, "msg": "", "count": res.result.count, "data": res.result.list } } , where: data_data }) ; table.on('tool(goods_information)', function (obj) { var data = obj.data; if (obj.event === 'detail') { // window.location.href = "./view_add.html?" + data.goods_information_id; layopen_dateil("./view_add.html?" + data.goods_information_id) } else if (obj.event === 'procurement_information'){ data.source_table = "goods_information" data.source_id = data.goods_information_id data.source_user_id = use_id sessionStorage.setItem('data', JSON.stringify(data)) //window.location.href = "../procurement_information/view_add.html?" layopen_dateil("../procurement_information/view_add.html?") } else if (obj.event === 'storage_record'){ data.source_table = "goods_information" data.source_id = data.goods_information_id data.source_user_id = use_id sessionStorage.setItem('data', JSON.stringify(data)) //window.location.href = "../storage_record/view_add.html?" layopen_dateil("../storage_record/view_add.html?") } else if (obj.event === 'outbound_record'){ data.source_table = "goods_information" data.source_id = data.goods_information_id data.source_user_id = use_id sessionStorage.setItem('data', JSON.stringify(data)) //window.location.href = "../outbound_record/view_add.html?" layopen_dateil("../outbound_record/view_add.html?") } else if (obj.event === 'inventory_records'){ data.source_table = "goods_information" data.source_id = data.goods_information_id data.source_user_id = use_id sessionStorage.setItem('data', JSON.stringify(data)) //window.location.href = "../inventory_records/view_add.html?" layopen_dateil("../inventory_records/view_add.html?") } else if (obj.event === 'price_adjustment_record'){ data.source_table = "goods_information" data.source_id = data.goods_information_id data.source_user_id = use_id sessionStorage.setItem('data', JSON.stringify(data)) //window.location.href = "../price_adjustment_record/view_add.html?" layopen_dateil("../price_adjustment_record/view_add.html?") } }); //下拉框 async function initss(url, id, ff) { // 拿到单选框的父级节点 var select = document.querySelector("#"+id) var op1 = document.createElement('option') select.appendChild(op1) // 收集数据 长度 var count // 收集数据 数组 var arr = [] let {data: res} = await axios.get(url) count = res.result.count arr = res.result.list for (var i = 0; i < arr.length; i++) { // 创建节点 var op = document.createElement('option') // 给节点赋值 op.innerHTML = arr[i][ff] op.value = arr[i][ff] // 新增/Add节点 select.appendChild(op) layui.form.render('select') } } initss(BaseUrl + '/api/classification_of_goods/get_list?', "classification_of_goods", "classification_of_goods") let classification_of_goods layui.form.on('select(classification_of_goods)', function (data) { request['classification_of_goods'] = data.elem[data.elem.selectedIndex].text }); // 请求参数: let request = { like: 0, size: 10, page: 1, 'warehouse_name': '', 'name_of_goods': '', 'classification_of_goods': '', 'storage_location': '', } if (user_group != "管理员") { request['orderby'] = 'create_time desc' if (sqlwhere){ request['sqlwhere'] = sqlwhere } } // <span>重置</span>/Reset参数 let resetName = data_data // 下拉框的<span>重置</span>/Reset参数 let resetSelect = [] //下拉框<span>重置</span>/Reset参数 fun('goods_information', BaseUrl + '/api/goods_information/del', 'goods_information_id', request, resetName, resetSelect ) }) </script> </html> 分析以上代码哪些是查询功能,不要自己写
06-04
#!/usr/bin/env python3 import numpy as np if not hasattr(np, 'float'): np.float = np.float32 from isaacgym import gymtorch from typing import Optional, Dict, Union, Mapping, Tuple, List, Any, Iterable from dataclasses import dataclass, InitVar, replace from pathlib import Path from copy import deepcopy from gym import spaces import tempfile import multiprocessing as mp import json import cv2 from functools import partial import numpy as np import torch as th import einops from torch.utils.tensorboard import SummaryWriter from pkm.models.common import (transfer, map_struct) # from pkm.models.rl.v4.rppo import ( # RecurrentPPO as PPO) from pkm.models.rl.v6.ppo import PPO from pkm.models.rl.generic_state_encoder import ( MLPStateEncoder) from pkm.models.rl.nets import ( VNet, PiNet, CategoricalPiNet, MLPFwdBwdDynLossNet ) # env + general wrappers # FIXME: ArmEnv _looks_ like a class, but it's # actually PushEnv + wrapper. from pkm.env.arm_env import (ArmEnv, ArmEnvConfig, OBS_BOUND_MAP, _identity_bound) from pkm.env.env.wrap.base import WrapperEnv from pkm.env.env.wrap.normalize_env import NormalizeEnv from pkm.env.env.wrap.monitor_env import MonitorEnv from pkm.env.env.wrap.adaptive_domain_tuner import MultiplyScalarAdaptiveDomainTuner from pkm.env.env.wrap.nvdr_camera_wrapper import NvdrCameraWrapper from pkm.env.env.wrap.popdict import PopDict from pkm.env.env.wrap.mvp_wrapper import MvpWrapper from pkm.env.env.wrap.normalize_img import NormalizeImg from pkm.env.env.wrap.tabulate_action import TabulateAction from pkm.env.env.wrap.nvdr_record_viewer import NvdrRecordViewer from pkm.env.env.wrap.nvdr_record_episode import NvdrRecordEpisode from pkm.env.util import set_seed from pkm.util.config import (ConfigBase, recursive_replace_map) from pkm.util.hydra_cli import hydra_cli from pkm.util.path import RunPath, ensure_directory from pkm.train.ckpt import last_ckpt, step_from_ckpt from pkm.train.hf_hub import (upload_ckpt, HfConfig, GroupConfig) from pkm.train.wandb import with_wandb, WandbConfig from pkm.train.util import ( assert_committed ) # domain-specific wrappers from envs.push_env_wrappers import ( AddGoalThreshFromPushTask ) from envs.cube_env_wrappers import ( AddObjectMass, AddPhysParams, AddPrevArmWrench, AddPrevAction, AddWrenchPenalty, AddObjectEmbedding, AddObjectKeypoint, AddObjectFullCloud, AddFingerFullCloud, AddApproxTouchFlag, AddTouchCount, AddSuccessAsObs, AddTrackingReward, QuatToDCM, QuatTo6D, RelGoal, Phase2Training, P2VembObs, ICPEmbObs, PNEmbObs ) # == drawing/debugging wrappers == from pkm.env.env.wrap.draw_bbox_kpt import DrawGoalBBoxKeypoint, DrawObjectBBoxKeypoint from pkm.env.env.wrap.draw_inertia_box import DrawInertiaBox from pkm.env.env.wrap.draw_clouds import DrawClouds from pkm.env.env.wrap.draw_patch_attn import DrawPatchAttention from envs.cube_env_wrappers import (DrawGoalPose, DrawObjPose, DrawTargetPose, DrawPosBound, DrawDebugLines) import nvtx from icecream import ic def to_pod(x: np.ndarray) -> List[float]: return [float(e) for e in x] @dataclass class PolicyConfig(ConfigBase): """ Actor-Critic policy configuration. """ actor: PiNet.Config = PiNet.Config() value: VNet.Config = VNet.Config() dim_state: InitVar[Optional[int]] = None dim_act: InitVar[Optional[int]] = None def __post_init__(self, dim_state: Optional[int] = None, dim_act: Optional[int] = None): if dim_state is not None: self.actor = replace(self.actor, dim_feat=dim_state) self.value = replace(self.value, dim_feat=dim_state) if dim_act is not None: self.actor = replace(self.actor, dim_act=dim_act) @dataclass class NetworkConfig(ConfigBase): """ Overall network configuration. """ state: MLPStateEncoder.Config = MLPStateEncoder.Config() policy: PolicyConfig = PolicyConfig() obs_space: InitVar[Union[int, Dict[str, int], None]] = None act_space: InitVar[Optional[int]] = None def __post_init__(self, obs_space=None, act_space=None): self.state = replace(self.state, obs_space=obs_space, act_space=act_space) try: if isinstance(act_space, Iterable) and len(act_space) == 1: act_space = act_space[0] policy = replace(self.policy, dim_state=self.state.state.dim_out, dim_act=act_space) self.policy = policy except AttributeError: pass @dataclass class Config(WandbConfig, HfConfig, GroupConfig, ConfigBase): # WandbConfig parts project: str = 'arm-ppo' use_wandb: bool = True # HfConfig (huggingface) parts hf_repo_id: Optional[str] = 'corn/corn-/arm' use_hfhub: bool = True # General experiment / logging force_commit: bool = False description: str = '' path: RunPath.Config = RunPath.Config(root='/tmp/pkm/ppo-arm/') env: ArmEnvConfig = ArmEnvConfig(which_robot='franka') agent: PPO.Config = PPO.Config() # State/Policy network configurations net: NetworkConfig = NetworkConfig() # Loading / continuing from prevous runs load_ckpt: Optional[str] = None transfer_ckpt: Optional[str] = None freeze_transferred: bool = True global_device: Optional[str] = None # VISION CONFIG use_camera: bool = False camera: NvdrCameraWrapper.Config = NvdrCameraWrapper.Config( use_depth=True, use_col=True, ctx_type='cuda', # == D435 config(?) == # aspect=8.0 / 5.0, # img_size=(480,848) # z_near for the physical camera # is actually pretty large! # z_near=0.195 # Horizontal Field of View 69.4 91.2 # Vertical Field of View 42.5 65.5 ) # Convert img into MVP-pretrained embeddings use_mvp: bool = False remove_state: bool = False remove_robot_state: bool = False remove_all_state: bool = False # Determines which inputs, even if they remain # in the observation dict, are not processed # by the state representation network. state_net_blocklist: Optional[List[str]] = None # FIXME: remove `hide_action`: # legacy config from train_ppo_hand.py hide_action: Optional[bool] = True add_object_mass: bool = False add_object_embedding: bool = False add_phys_params: bool = False add_keypoint: bool = False add_object_full_cloud: bool = False add_goal_full_cloud: bool = False add_finger_full_cloud: bool = False add_prev_wrench: bool = True add_prev_action: bool = True zero_out_prev_action: bool = False add_goal_thresh: bool = False add_wrench_penalty: bool = False wrench_penalty_coef: float = 1e-4 add_touch_flag: bool = False add_touch_count: bool = False min_touch_force: float = 5e-2 min_touch_speed: float = 1e-3 add_success: bool = False add_tracking_reward: bool = False # ==<CURRICULUM>== use_tune_init_pos: bool = False tune_init_pos_scale: MultiplyScalarAdaptiveDomainTuner.Config = MultiplyScalarAdaptiveDomainTuner.Config( step=1.05, easy=0.1, hard=1.0) use_tune_goal_radius: bool = False tune_goal_radius: MultiplyScalarAdaptiveDomainTuner.Config = MultiplyScalarAdaptiveDomainTuner.Config( step=0.95, easy=0.5, hard=0.05) use_tune_goal_speed: bool = False tune_goal_speed: MultiplyScalarAdaptiveDomainTuner.Config = MultiplyScalarAdaptiveDomainTuner.Config( step=0.95, easy=4.0, hard=0.1) use_tune_goal_angle: bool = False tune_goal_angle: MultiplyScalarAdaptiveDomainTuner.Config = MultiplyScalarAdaptiveDomainTuner.Config( step=0.95, easy=1.57, hard=0.05) use_tune_pot_gamma: bool = False tune_pot_gamma: MultiplyScalarAdaptiveDomainTuner.Config = MultiplyScalarAdaptiveDomainTuner.Config( step=0.999, easy=1.00, hard=0.99, step_down=1.001, metric='return', target_lower=0.0, target_upper=0.0) force_vel: Optional[float] = None force_rad: Optional[float] = None force_ang: Optional[float] = None # ==</CURRICULUM>== use_tabulate: bool = False tabulate: TabulateAction.Config = TabulateAction.Config( num_bin=3 ) use_norm: bool = True normalizer: NormalizeEnv.Config = NormalizeEnv.Config() # Convert some observations into # alternative forms... use_dcm: bool = False use_rel_goal: bool = False use_6d_rel_goal: bool = False use_monitor: bool = True monitor: MonitorEnv.Config = MonitorEnv.Config() # == camera config == use_nvdr_record_episode: bool = False nvdr_record_episode: NvdrRecordEpisode.Config = NvdrRecordEpisode.Config() use_nvdr_record_viewer: bool = False nvdr_record_viewer: NvdrRecordViewer.Config = NvdrRecordViewer.Config( img_size=(128, 128) ) normalize_img: bool = True img_mean: float = 0.4 img_std: float = 0.2 cloud_only: bool = False multiple_cameras: bool = False camera_eyes: Tuple[Any] = ( (-0.238, 0.388, 0.694), (-0.408, -0.328, 0.706) ) # == "special" training configs # add auxiliary dynamics netweork+loss add_dyn_aux: bool = False # automatic mixed-precision(FP16) training use_amp: bool = False # DataParallel training across multiple devices parallel: Optional[Tuple[int, ...]] = None # == periodic validation configs == sample_action: bool = False eval_period: int = -1 eval_step: int = 256 eval_num_env: int = 16 eval_record: bool = True eval_device: str = 'cuda:0' eval_track_per_obj_suc_rate: bool = False draw_debug_lines: bool = False draw_patch_attn: bool = False finalize: bool = False parallel: Optional[Tuple[int, ...]] = None is_phase2: bool = False phase2: Phase2Training.Config = Phase2Training.Config() use_p2v: bool = False use_icp_obs: bool = False use_pn_obs: bool = False p2v: P2VembObs.Config = P2VembObs.Config() icp_obs: ICPEmbObs.Config = ICPEmbObs.Config() pn_obs: PNEmbObs.Config = PNEmbObs.Config() def __post_init__(self): self.group = F'{self.machine}-{self.env_name}-{self.model_name}-{self.tag}' self.name = F'{self.group}-{self.env.seed:06d}' if not self.finalize: return # WARNING: VERY HAZARDOUS use_dr_on_setup = self.env.single_object_scene.use_dr_on_setup | self.is_phase2 use_dr = self.env.single_object_scene.use_dr | self.is_phase2 self.env = recursive_replace_map( self.env, {'franka.compute_wrench': self.add_prev_wrench, 'franka.add_control_noise': self.is_phase2, 'single_object_scene.use_dr_on_setup': use_dr_on_setup, 'single_object_scene.use_dr': use_dr, }) if self.global_device is not None: dev_id: int = int(str(self.global_device).split(':')[-1]) self.env = recursive_replace_map(self.env, { 'graphics_device_id': (dev_id if self.env.use_viewer else -1), 'compute_device_id': dev_id, 'th_device': self.global_device, }) self.agent = recursive_replace_map(self.agent, { 'device': self.global_device}) if self.force_vel is not None: self.use_tune_goal_speed = False self.env.task.max_speed = self.force_vel if self.force_rad is not None: self.use_tune_goal_radius = False self.env.task.goal_radius = self.force_rad if self.force_ang is not None: self.use_tune_goal_angle = False self.env.task.goal_angle = self.force_ang def setup(cfg: Config): # Maybe it's related to jit if cfg.global_device is not None: th.cuda.set_device(cfg.global_device) th.backends.cudnn.benchmark = True commit_hash = assert_committed(force_commit=cfg.force_commit) path = RunPath(cfg.path) print(F'run = {path.dir}') return path class AddTensorboardWriter(WrapperEnv): def __init__(self, env): super().__init__(env) self._writer = None def set_writer(self, w): self._writer = w @property def writer(self): return self._writer def load_env(cfg: Config, path, freeze_env: bool = False, **kwds): env = ArmEnv(cfg.env) env.setup() env.gym.prepare_sim(env.sim) env.refresh_tensors() env.reset() env = AddTensorboardWriter(env) obs_bound = None if cfg.use_norm: obs_bound = {} # Populate `obs_bound` with defaults # from `ArmEnv`. obs_bound['goal'] = OBS_BOUND_MAP.get(cfg.env.goal_type) obs_bound['object_state'] = OBS_BOUND_MAP.get( cfg.env.object_state_type) obs_bound['hand_state'] = OBS_BOUND_MAP.get(cfg.env.hand_state_type) obs_bound['robot_state'] = OBS_BOUND_MAP.get(cfg.env.robot_state_type) if cfg.normalizer.norm.stats is not None: obs_bound.update(deepcopy(cfg.normalizer.norm.stats)) print(obs_bound) def __update_obs_bound(key, value, obs_bound, overwrite: bool = True): if not cfg.use_norm: return if value is None: obs_bound.pop(key, None) if key in obs_bound: if overwrite: print(F'\t WARN: key = {key} already in obs_bound !') else: raise ValueError(F'key = {key} already in obs_bound !') obs_bound[key] = value update_obs_bound = partial(__update_obs_bound, obs_bound=obs_bound) if cfg.env.task.use_pose_goal: if cfg.add_goal_full_cloud: update_obs_bound('goal', OBS_BOUND_MAP.get('cloud')) else: update_obs_bound('goal', OBS_BOUND_MAP.get(cfg.env.goal_type)) # Crude check for mutual exclusion # Determines what type of privileged "state" information # the policy will receive, as observation. assert ( np.count_nonzero( [cfg.remove_state, cfg.remove_robot_state, cfg.remove_all_state]) <= 1) if cfg.remove_state: env = PopDict(env, ['object_state']) update_obs_bound('object_state', None) elif cfg.remove_robot_state: env = PopDict(env, ['hand_state']) update_obs_bound('hand_state', None) elif cfg.remove_all_state: env = PopDict(env, ['hand_state', 'object_state']) update_obs_bound('hand_state', None) update_obs_bound('object_state', None) if cfg.add_object_mass: env = AddObjectMass(env, 'object_mass') update_obs_bound('object_mass', OBS_BOUND_MAP.get('mass')) if cfg.add_phys_params: env = AddPhysParams(env, 'phys_params') update_obs_bound('phys_params', OBS_BOUND_MAP.get('phys_params')) if cfg.add_object_embedding: env = AddObjectEmbedding(env, 'object_embedding') update_obs_bound('object_embedding', OBS_BOUND_MAP.get('embedding')) if cfg.add_keypoint: env = AddObjectKeypoint(env, 'object_keypoint') update_obs_bound('object_keypoint', OBS_BOUND_MAP.get('keypoint')) if cfg.add_object_full_cloud: # mutually exclusive w.r.t. `use_cloud` # i.e. the partial point cloud coming from # the camera. # assert (cfg.camera.use_cloud is False) goal_key = None if cfg.add_goal_full_cloud: goal_key = 'goal' env = AddObjectFullCloud(env, 'cloud', goal_key=goal_key) update_obs_bound('cloud', OBS_BOUND_MAP.get('cloud')) if goal_key is not None: update_obs_bound(goal_key, OBS_BOUND_MAP.get('cloud')) if cfg.add_finger_full_cloud: env = AddFingerFullCloud(env, 'finger_cloud') update_obs_bound('finger_cloud', OBS_BOUND_MAP.get('cloud')) if cfg.add_goal_thresh: env = AddGoalThreshFromPushTask(env, key='goal_thresh', dim=3) update_obs_bound('goal_thresh', _identity_bound(3)) if cfg.add_prev_wrench: env = AddPrevArmWrench(env, 'previous_wrench') update_obs_bound('previous_wrench', OBS_BOUND_MAP.get('wrench')) if cfg.add_prev_action: env = AddPrevAction(env, 'previous_action', zero_out=cfg.zero_out_prev_action) update_obs_bound('previous_action', _identity_bound( env.observation_space['previous_action'].shape )) if cfg.add_wrench_penalty: env = AddWrenchPenalty(env, cfg.wrench_penalty_coef, key='env/wrench_cost') if cfg.add_touch_flag: env = AddApproxTouchFlag(env, key='touch', min_force=cfg.min_touch_force, min_speed=cfg.min_touch_speed) if cfg.add_touch_count: assert (cfg.add_touch_flag) env = AddTouchCount(env, key='touch_count') update_obs_bound('touch_count', _identity_bound( env.observation_space['touch_count'].shape )) if cfg.add_success: env = AddSuccessAsObs(env, key='success') update_obs_bound('success', _identity_bound(())) if cfg.use_camera: prev_space_keys = deepcopy(list(env.observation_space.keys())) env = NvdrCameraWrapper( env, cfg.camera ) for k in env.observation_space.keys(): if k in prev_space_keys: continue obs_shape = env.observation_space[k].shape # if k in cfg.normalizer.obs_shape: # obs_shape = cfg.normalizer.obs_shape[k] print(k, obs_shape) if 'cloud' in k: update_obs_bound(k, OBS_BOUND_MAP.get('cloud')) else: update_obs_bound(k, _identity_bound(obs_shape[-1:])) if cfg.multiple_cameras: camera = deepcopy(cfg.camera) camera = replace( camera, use_label=False ) for i, eye in enumerate(cfg.camera_eyes): cloud_key = f'partial_cloud_{i+1}' new_camera = replace( camera, eye=eye ) new_camera = replace( new_camera, key_cloud=cloud_key ) env = NvdrCameraWrapper( env, new_camera ) update_obs_bound(cloud_key, OBS_BOUND_MAP.get('cloud')) if cfg.normalize_img: env = NormalizeImg(env, cfg.img_mean, cfg.img_std, key='depth') # After normalization, it (should) map to (0.0, 1.0) update_obs_bound('depth', (0.0, 1.0)) if cfg.cloud_only: env = PopDict(env, ['depth', 'label']) update_obs_bound('depth', None) update_obs_bound('label', None) if cfg.use_mvp: assert (cfg.use_camera) env = MvpWrapper(env) raise ValueError( 'MVPWrapper does not currently configure a proper obs space.' ) if cfg.add_tracking_reward: env = AddTrackingReward(env, 1e-4) # == curriculum == if cfg.use_tune_init_pos: def get_init_pos_scale(): return env.scene._pos_scale def set_init_pos_scale(s: float): env.scene._pos_scale = s env = MultiplyScalarAdaptiveDomainTuner(cfg.tune_init_pos_scale, env, get_init_pos_scale, set_init_pos_scale, key='env/init_pos_scale') if cfg.use_tune_goal_radius: def get_goal_rad(): return env.task.goal_radius def set_goal_rad(s: float): env.task.goal_radius = s env = MultiplyScalarAdaptiveDomainTuner(cfg.tune_goal_radius, env, get_goal_rad, set_goal_rad, key='env/goal_radius') if cfg.use_tune_goal_speed: def get_goal_speed(): return env.task.max_speed def set_goal_speed(s: float): env.task.max_speed = s env = MultiplyScalarAdaptiveDomainTuner(cfg.tune_goal_speed, env, get_goal_speed, set_goal_speed, key='env/max_speed') if cfg.use_tune_goal_angle: def get_goal_ang(): return env.task.goal_angle def set_goal_ang(s: float): env.task.goal_angle = s env = MultiplyScalarAdaptiveDomainTuner(cfg.tune_goal_angle, env, get_goal_ang, set_goal_ang, key='env/goal_angle') if cfg.use_tune_pot_gamma: def get_pot_gamma(): return env.task.gamma def set_pot_gamma(s: float): env.task.gamma = s env = MultiplyScalarAdaptiveDomainTuner(cfg.tune_pot_gamma, env, get_pot_gamma, set_pot_gamma, key='env/pot_gamma') if cfg.use_tabulate: env = TabulateAction(cfg.tabulate, env) if cfg.use_dcm: env = QuatToDCM(env, { 'goal': 3, 'hand_state': 3, 'object_state': 3 }) raise ValueError( 'DCM (directional cosine matrix) conversions are ' 'currently disabled due to complex integration ' 'with obs_bound.') # Use relative goal between current object pose # and the goal pose, instead of absolute goal. if cfg.use_rel_goal: env = RelGoal(env, 'goal', use_6d=cfg.use_6d_rel_goal) if cfg.use_6d_rel_goal: update_obs_bound('goal', OBS_BOUND_MAP.get('relpose6d')) else: update_obs_bound('goal', OBS_BOUND_MAP.get('relpose')) if cfg.is_phase2: env = Phase2Training(cfg.phase2, env) # == DRAW, LOG, RECORD == if cfg.draw_debug_lines: check_viewer = kwds.pop('check_viewer', True) env = DrawDebugLines(DrawDebugLines.Config( draw_workspace=kwds.pop('draw_workspace', False), draw_wrench_target=kwds.pop('draw_wrench_target', False), draw_cube_action=kwds.pop('draw_hand_action', False) ), env, check_viewer=check_viewer) # NOTE: blocklist=0 indicates the table; # blocklist=2 indicates the robot. Basically, # only draw the inertia-box for the object. env = DrawInertiaBox(env, blocklist=[0, 2], check_viewer=check_viewer) env = DrawObjectBBoxKeypoint(env) env = DrawGoalBBoxKeypoint(env) env = DrawGoalPose(env, check_viewer=check_viewer) env = DrawObjPose(env, check_viewer=check_viewer) # Some alternative visualizations are available below; # [1] draw the goal as a "pose" frame axes # env = DrawTargetPose(env, # check_viewer=check_viewer) # [2] Draw franka EE boundary if cfg.env.franka.track_object: env = DrawPosBound(env, check_viewer=check_viewer) # [3] Draw input point cloud observations as spheres. # Should usually be prevented, so check_viewer=True # env = DrawClouds(env, check_viewer=True, stride=8, # cloud_key='partial_cloud', # or 'cloud' # style='ray') if cfg.draw_patch_attn: class PatchAttentionFromPPV5: """ Retrieve patchified point cloud and attention values from PointPatchV5FeatNet. """ def __init__(self): # self.__net = agent.state_net.feature_encoders['cloud'] self.__net = None def register(self, net): self.__net = net def __call__(self, obs): ravel_index = self.__net._patch_index.reshape( *obs['cloud'].shape[:-2], -1, 1) patch = th.take_along_dim( # B, N, D obs['cloud'], # B, (S, P), 1 ravel_index, dim=-2 ).reshape(*self.__net._patch_index.shape, obs['cloud'].shape[-1]) attn = self.__net._patch_attn # ic(attn) # Only include parts that correspond to # point patches # ic('pre',attn.shape) # attn = attn[..., 1:, :] attn = attn[..., :, 1:] # ic('post',attn.shape) # max among heads # attn = attn.max(dim=-2).values # head zero attn = attn[..., 2, :] return (patch, attn) env = DrawPatchAttention(env, PatchAttentionFromPPV5(), dilate=1.2, style='cloud') if cfg.use_nvdr_record_viewer: env = NvdrRecordViewer(cfg.nvdr_record_viewer, env, hide_arm=False) # == MONITOR PERFORMANCE == if cfg.use_monitor: env = MonitorEnv(cfg.monitor, env) # == Normalize environment == # normalization must come after # the monitoring code, since it # overwrites env statistics. if cfg.use_norm: cfg = recursive_replace_map(cfg, {'normalizer.norm.stats': obs_bound}) env = NormalizeEnv(cfg.normalizer, env, path) if cfg.load_ckpt is not None: ckpt_path = Path(cfg.load_ckpt) if ckpt_path.is_file(): # Try to select stats from matching timestep. step = ckpt_path.stem.split('-')[-1] def ckpt_key(ckpt_file): return (step in str(ckpt_file.stem).rsplit('-')[-1]) stat_dir = ckpt_path.parent / '../stat/' else: # Find the latest checkpoint. ckpt_key = step_from_ckpt stat_dir = ckpt_path / '../stat' if stat_dir.is_dir(): stat_ckpt = last_ckpt(stat_dir, key=ckpt_key) print(F'Also loading env stats from {stat_ckpt}') env.load(stat_ckpt, strict=False) # we'll freeze env stats by default, if loading from ckpt. if freeze_env: env.normalizer.eval() else: stat_ckpt = last_ckpt(cfg.load_ckpt + "_stat", key=ckpt_key) print(F'Also loading env stats from {stat_ckpt}') env.load(stat_ckpt, strict=False) if cfg.use_p2v: env = P2VembObs(env, cfg.p2v) env = PopDict(env, ['cloud']) update_obs_bound('cloud', None) if cfg.use_icp_obs: env = ICPEmbObs(env, cfg.icp_obs) env = PopDict(env, ['cloud']) update_obs_bound('cloud', None) if cfg.use_pn_obs: env = PNEmbObs(env, cfg.pn_obs) env = PopDict(env, ['cloud']) update_obs_bound('cloud', None) return cfg, env def load_agent(cfg, env, path, writer): device = env.device ic(cfg) # FIXME: We currently disable MLPStateEncoder from # receiving previous_action implicitly; it has to be # included in the observations explicitly. cfg.net.state.state.dim_act = 0 state_net = MLPStateEncoder.from_config(cfg.net.state) # Create policy/value networks. # FIXME: introspection into cfg.dim_out dim_state = state_net.state_aggregator.cfg.dim_out if isinstance(env.action_space, spaces.Discrete): actor_net = CategoricalPiNet(cfg.net.policy.actor).to(device) else: actor_net = PiNet(cfg.net.policy.actor).to(device) value_net = VNet(cfg.net.policy.value).to(device) # Add extra networks (Usually for regularization, # auxiliary losses, or learning extra models) extra_nets = None if cfg.add_dyn_aux: trans_net_cfg = MLPFwdBwdDynLossNet.Config( dim_state=dim_state, dim_act=cfg.net.policy.actor.dim_act, dim_hidden=(128,), ) trans_net = MLPFwdBwdDynLossNet(trans_net_cfg).to(device) extra_nets = {'trans_net': trans_net} agent = PPO( cfg.agent, env, state_net, actor_net, value_net, path, writer, extra_nets=extra_nets ).to(device) if cfg.transfer_ckpt is not None: ckpt = last_ckpt(cfg.transfer_ckpt, key=step_from_ckpt) xfer_dict = th.load(ckpt, map_location='cpu') keys = transfer(agent, xfer_dict['self'], freeze=cfg.freeze_transferred, substrs=[ # 'state_net.feature_encoders', # 'state_net.feature_aggregators' 'state_net' ], # prefix_map={ # 'state_net.feature_encoders.state': # 'state_net.feature_encoders.object_state', # 'state_net.feature_aggregators.state': # 'state_net.feature_aggregators.object_state', # }, verbose=True) print(keys) if cfg.load_ckpt is not None: ckpt: str = last_ckpt(cfg.load_ckpt, key=step_from_ckpt) print(F'Load agent from {ckpt}') agent.load(last_ckpt(cfg.load_ckpt, key=step_from_ckpt), strict=True) return agent def eval_agent_inner(cfg: Config, return_dict): # [1] Silence outputs during validation. import sys import os sys.stdout = open(os.devnull, 'w') sys.stderr = open(os.devnull, 'w') # [2] Import & run validation. from valid_ppo_arm import main return_dict.update(main(cfg)) def eval_agent(cfg: Config, env, agent: PPO): # subprocess.check_output('python3 valid_ppo_hand.py ++run=') manager = mp.Manager() return_dict = manager.dict() with tempfile.TemporaryDirectory() as tmpdir: # Save agent ckpt for validation. ckpt_dir = ensure_directory(F'{tmpdir}/ckpt') stat_dir = ensure_directory(F'{tmpdir}/stat') agent_ckpt = str(ckpt_dir / 'last.ckpt') env_ckpt = str(stat_dir / 'env-last.ckpt') env.save(env_ckpt) agent.save(agent_ckpt) # Override cfg. # FIXME: # Hardcoded target_domain coefs # shold potentially be # tune_goal_speed.hard... # etc. cfg = recursive_replace_map(cfg, { 'load_ckpt': str(ckpt_dir), 'force_vel': 0.1, 'force_rad': 0.05, 'force_ang': 0.1, 'env.num_env': cfg.eval_num_env, 'env.use_viewer': False, 'env.single_object_scene.num_object_types': ( cfg.env.single_object_scene.num_object_types), 'monitor.verbose': False, 'draw_debug_lines': True, 'use_nvdr_record_viewer': cfg.eval_record, 'nvdr_record_viewer.record_dir': F'{tmpdir}/record', 'env.task.mode': 'valid', 'env.single_object_scene.mode': 'valid', 'env.single_object_scene.num_valid_poses': 4, 'global_device': cfg.eval_device, 'eval_track_per_obj_suc_rate': True }) ctx = mp.get_context('spawn') # Run. proc = ctx.Process( target=eval_agent_inner, args=(cfg, return_dict), ) proc.start() proc.join() return_dict = dict(return_dict) if 'video' in return_dict: replaced = {} for k, v in return_dict['video'].items(): if isinstance(v, str): video_dir = v assert Path(video_dir).is_dir() filenames = sorted(Path(video_dir).glob('*.png')) rgb_images = [cv2.imread(str(x))[..., ::-1] for x in filenames] vid_array = np.stack(rgb_images, axis=0) v = th.as_tensor(vid_array[None]) v = einops.rearrange(v, 'n t h w c -> n t c h w') replaced[k] = v return_dict['video'] = replaced return return_dict @with_wandb def inner_main(cfg: Config, env, path): """ Basically it's the same as main(), but we commit the config _after_ finalizing. """ commit_hash = assert_committed(force_commit=cfg.force_commit) writer = SummaryWriter(path.tb_train) writer.add_text('meta/commit-hash', str(commit_hash), global_step=0) env.unwrap(target=AddTensorboardWriter).set_writer(writer) agent = load_agent(cfg, env, path, writer) # Enable DataParallel() for subset of modules. if (cfg.parallel is not None) and (th.cuda.device_count() > 1): count: int = th.cuda.device_count() device_ids = list(cfg.parallel) # FIXME: hardcoded DataParallel processing only for # `img` feature if 'img' in agent.state_net.feature_encoders: agent.state_net.feature_encoders['img'] = th.nn.DataParallel( agent.state_net.feature_encoders['img'], device_ids) ic(agent) def __eval(step: int): logs = eval_agent(cfg, env, agent) log_kwds = {'video': {'fps': 20.0}} # == generic log() == for log_type, log in logs.items(): for tag, value in log.items(): write = getattr(writer, F'add_{log_type}') write(tag, value, global_step=step, **log_kwds.get(log_type, {})) try: th.cuda.empty_cache() with th.cuda.amp.autocast(enabled=cfg.use_amp): for step in agent.learn(name=F'{cfg.name}@{path.dir}'): # Periodically run validation. if (cfg.eval_period > 0) and (step % cfg.eval_period) == 0: th.cuda.empty_cache() __eval(step) finally: # Dump final checkpoints. agent.save(path.ckpt / 'last.ckpt') if hasattr(env, 'save'): env.save(path.stat / 'env-last.ckpt') # Finally, upload the trained model to huggingface model hub. if cfg.use_hfhub and (cfg.hf_repo_id is not None): upload_ckpt( cfg.hf_repo_id, (path.ckpt / 'last.ckpt'), cfg.name) upload_ckpt( cfg.hf_repo_id, (path.stat / 'env-last.ckpt'), cfg.name + '_stat') @hydra_cli( config_path='../../src/pkm/data/cfg/', # config_path='/home/user/mambaforge/envs/genom/lib/python3.8/site-packages/pkm/data/cfg/', config_name='train_rl') def main(cfg: Config): ic.configureOutput(includeContext=True) cfg = recursive_replace_map(cfg, {'finalize': True}) # path, writer = setup(cfg) path = setup(cfg) seed = set_seed(cfg.env.seed) cfg, env = load_env(cfg, path) # Save object names... useful for debugging if True: with open(F'{path.stat}/obj_names.json', 'w') as fp: json.dump(env.scene.cur_names, fp) # Update `cfg` elements from `env`. obs_space = map_struct( env.observation_space, lambda src, _: src.shape, base_cls=spaces.Box, dict_cls=(Mapping, spaces.Dict) ) if cfg.state_net_blocklist is not None: for key in cfg.state_net_blocklist: obs_space.pop(key, None) dim_act = ( env.action_space.shape[0] if isinstance( env.action_space, spaces.Box) else env.action_space.n) cfg = replace(cfg, net=replace(cfg.net, obs_space=obs_space, act_space=dim_act, )) return inner_main(cfg, env, path) if __name__ == '__main__': main() 逐行分析我这里的代码,不要分析别的
08-27
#include "scp.h" #include <stdlib.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <stdio.h> #include <sys/stat.h> #include <netinet/in.h> #include <sys/file.h> #include <sys/select.h> #include <sys/time.h> #include <sys/types.h> #include <fcntl.h> // 主要头文件(包含 open() 的函数原型和标志常量) /**************************************************************************************************/ /* GLOBAL_VARIABLES */ /**************************************************************************************************/ scp_context *scp_contextp = NULL; /**************************************************************************************************/ /* DEFINES */ /**************************************************************************************************/ #if 1 //Archer const char ISP_FILE_PATH[] = "/etc/3g4g.gz"; const char TM_FILTER_APPS_FILE_PATH[] = "/tmp/tm-shn/list_pc_filter_apps.db.gz"; const char TM_SEC_RULES_FILE_PATH[] = "/tmp/tm-shn/list_security_rules.db.gz"; const char TM_SEC_WRS_CATS_FILE_PATH[] = "/tmp/tm-shn/list_security_wrs_cats.db.gz"; const char TM_APPBLOCKLIST_FILE_PATH[] = "/tmp/appblock/avira_applist.gz"; const char GUEST_NETWORK_PORTAL_LOGO_PATH_READ[] = "/www/tmp/portal_logo.png"; const char GUEST_NETWORK_PORTAL_BACK_PATH_READ[] = "/www/tmp/portal_back.jpg"; const char GUEST_NETWORK_PORTAL_LOGO_PATH_WRITE[] = "/tmp/guest_portal/portal_logo.png"; const char GUEST_NETWORK_PORTAL_BACK_PATH_WRITE[] = "/tmp/guest_portal/portal_back.jpg"; #else //Aginet const char USBDISK_VOICEMAIL_RECORD_PATH[] = "/var/usbdisk/usbvm/voicemail/record/"; const char USBDISK_VOICEMAIL_NOTIFY_PATH[] = "/var/usbdisk/usbvm/voicemail/voiceNotify/"; const char LARGEDATA_VOICEMAIL_RECORD_PATH[] = "/large_data/usbvm/voicemail/record/"; const char REGION_JSON_GZ_FILE[] = "/web/js/region.json.gz"; const char REGION_JSON_GZ_MD5_FILE[] = "/web/js/region.json.gz.MD5"; const char ISPPROFILE_GZ_JSON_FILE[] = "/web/js/ispprofile.json.gz"; const char ISPPROFILE_GZ_JSON_MD5_FILE[] = "/web/js/ispprofile.json.gz.MD5"; const char ISPLOGO_PNG_GZ_FILE[] = "/web/img/isplogo.png.gz"; const char ISPLOGO_PNG_GZ_MD5_FILE[] = "/web/img/isplogo.png.gz.MD5"; const char AGC_DATABUFF_ISPLOGO_PNG_GZ_FILE[] = "/var/tmp/AginetConfig/databuff/isplogo.png.gz"; const char AGC_DATABUFF_ISPLOGO_PNG_GZ_MD5_FILE[] = "/var/tmp/AginetConfig/databuff/isplogo.png.gz.MD5"; //test const char TESTFILE1[] = "/tmp/testfile1"; const char TESTFILE2[] = "/tmp/testfile2"; #endif typedef struct { const char *file_path; int options; } SCP_FILE_PERMISSION; #define OPT_READ (0x01) #define OPT_WRITE (0x02) #define OPT_DATE (0x04) #define OPT_INCLUDE(x, opt) (opt == (x & opt)) static SCP_FILE_PERMISSION file_permissions[] = { {USBDISK_VOICEMAIL_RECORD_PATH, OPT_READ | OPT_DATE}, {USBDISK_VOICEMAIL_NOTIFY_PATH, OPT_READ | OPT_DATE}, {LARGEDATA_VOICEMAIL_RECORD_PATH, OPT_READ | OPT_DATE}, {REGION_JSON_GZ_FILE, OPT_READ | OPT_DATE}, {REGION_JSON_GZ_MD5_FILE, OPT_READ | OPT_DATE}, {ISPPROFILE_GZ_JSON_FILE, OPT_READ | OPT_DATE}, {ISPPROFILE_GZ_JSON_MD5_FILE, OPT_READ | OPT_DATE}, {ISPLOGO_PNG_GZ_FILE, OPT_READ | OPT_DATE}, {ISPLOGO_PNG_GZ_MD5_FILE, OPT_READ | OPT_DATE}, {AGC_DATABUFF_ISPLOGO_PNG_GZ_FILE, OPT_READ | OPT_DATE}, {AGC_DATABUFF_ISPLOGO_PNG_GZ_MD5_FILE, OPT_READ | OPT_DATE}, {TESTFILE1, OPT_READ | OPT_WRITE | OPT_DATE}, {TESTFILE2, OPT_READ | OPT_WRITE | OPT_DATE}, }; /**************************************************************************************************/ /* LOCAL_FUNCTIONS */ /**************************************************************************************************/ static int check_file_permission(const char *fn, int type, int need_date) { int i = 0; for (i = 0; i < sizeof(file_permissions); i++) { if (0 == strcmp(fn, file_permissions[i].file_path)) { if ((SESSION_TYPE_SOURCE == type) && (!OPT_INCLUDE(file_permissions[i].options, OPT_READ))) { return -1; } if ((SESSION_TYPE_TARGET == type) && (!OPT_INCLUDE(file_permissions[i].options, OPT_WRITE))) { return -1; } if ((need_date && file_permissions) && (!OPT_INCLUDE(file_permissions[i].options, OPT_DATE))) { return -1; } return 0; } } return -1; } static void set_file_time(int fd, int atime, int mtime) { if (fd < 0) return; struct timespec tv[2] = { {0, UTIME_NOW}, //0: access {0, UTIME_NOW} //1: modify }; if (atime >= 0) { tv[0].tv_sec = atime; tv[0].tv_nsec = 0; } if (mtime >= 0) { tv[1].tv_sec = mtime; tv[1].tv_nsec = 0; } futimens(fd, tv); } static void hex2bin(const char *hex, unsigned char *bin, int hex_len) { int i = 0; int val = 0; if (hex_len & 1) hex_len--; memset(bin, 0, hex_len >> 1); for (i = 0; i < hex_len; i++) { switch (hex[i]) { case '0'...'9': val = hex[i] - '0'; break; case 'a'...'z': val = hex[i] - 'a' + 10; break; case 'A'...'Z': val = hex[i] - 'A' + 10; break; } bin[i >> 1] = (bin[i >> 1] << 4) + val; } } static void bin2hex(const unsigned char *bin, char *hex, int bin_len) { int i = 0; int val = 0; for (i = 0; i < bin_len; i++) { val = (bin[i] >> 4) & 0x0f; hex[i << 1] = val + ((val >= 10) ? ('A' - 10) : '0'); val = (bin[i]) & 0x0f; hex[(i << 1) + 1] = val + ((val >= 10) ? ('A' - 10) : '0'); } } static int calc_checksum(int fd, unsigned char *output, int size) { if (fd < 0 || NULL == output || size <= 0) return -1; unsigned char buf[SCP_PACKET_MAX_SIZE]; int read_len = SCP_PACKET_MAX_SIZE; int len = 0; off_t offset = lseek(fd, 0, SEEK_CUR); lseek(fd, 0, SEEK_SET); SHA256_CTX ctx; SHA256_Init(&ctx); do { if (size < read_len) read_len = size; len = scp_fd_read_direct(fd, buf, read_len); if (len <= 0) return -1; SHA256_Update(&ctx, buf, len); size -= len; } while (size > 0); SHA256_Final(output, &ctx); lseek(fd, offset, SEEK_SET); return 0; } /**************************************************************************************************/ /* PUBLIC_FUNCTIONS */ /**************************************************************************************************/ int scp_fd_write_direct(int fd, const char* buf, size_t size) { int len; int ret = size; if (fd < 0) { return 0; } for (;;) { len = write(fd, buf, size); if (len < 0) { if (EINTR == errno) { continue; } ret = -1; break; } else if (len == 0) { ret = 0; break; } else if ((size_t)len >= size) { break; } else { buf += len; size -= len; } } return ret; } int scp_fd_read_direct(int fd, char* buf, size_t size) { if (fd < 0) { return 0; } int len; int ret = size; fd_set fds; struct timeval tv; int retval; for (;;) { FD_ZERO(&fds); FD_SET(fd, &fds); tv.tv_sec = 1; tv.tv_usec = 0; retval = select(fd + 1, &fds, NULL, NULL, &tv); if (retval < 0) { if (EINTR == errno) { continue; } ret = -1; break; } else if (retval == 0) { ret = -1; break; } len = read(fd, buf, size); if (len < 0) { if (EINTR == errno) { continue; } ret = -1; break; } else if (len == 0) { ret = 0; break; } else if ((size_t)len >= size) { break; } else { buf += len; size -= len; } } return ret; } int scp_make_packet(unsigned char *buf, cJSON *control) { SCP_HEADER *scp_hdr = (SCP_HEADER *)buf; int ctrl_len = 0; char *control_str = NULL; control_str = cJSON_PrintUnformatted(control); SCPSDebug("scp_make_packet: %s", control_str); ctrl_len = strlen(control_str); scp_hdr->ctrl_len = htons(ctrl_len); memcpy(SCP_HEADER_GET_PAYLOAD(scp_hdr, 0), control_str, ctrl_len); free(control_str); SCPSDebug("make packet ctrl %d.", ctrl_len); for (; (ctrl_len & 0x03) != 0; ctrl_len++) *SCP_HEADER_GET_PAYLOAD(scp_hdr, ctrl_len) = '\0'; SCPSDebug("packet ctrl padding length %d.", ctrl_len); scp_hdr->data_len = 0; return ctrl_len + sizeof(SCP_HEADER); } #define CHECK_PARAM(param, obj_type) do { \ if (NULL == param) return SCP_ERROR_CODE_CONTROL_SECTION_NOT_FOUND; \ if (param->type != obj_type) { \ SCPSDebug("Get param %s %d, %d expected.", param->string, param->type, obj_type); \ return SCP_ERROR_CODE_CONTROL_VALUE_ILLEGAL; \ } \ } while(0) int scp_get_method(const unsigned char *buf, cJSON **control, int *id, int *type, int *val, cJSON **param_ret) { cJSON *root = NULL; cJSON *param = NULL; SCP_HEADER *scp_hdr = (SCP_HEADER *)buf; SCPSDebug("scp get json1: %s\n", SCP_HEADER_GET_PAYLOAD(scp_hdr, 0)); root = cJSON_Parse(SCP_HEADER_GET_PAYLOAD(scp_hdr, 0)); if (NULL == root) return SCP_ERROR_CODE_CONTROL_DECRYPT_FAILED; if (NULL != control) *control = root; //调用者自行删除root CHECK_PARAM(root, cJSON_Object); param = cJSON_GetObjectItem(root, "id"); CHECK_PARAM(param, cJSON_Number); if (0 >= param->valueint || SCP_MAX_ID < param->valueint) return SCP_ERROR_CODE_CONTROL_VALUE_ILLEGAL; *id = param->valueint; param = cJSON_GetObjectItem(root, "error_code"); if (param != NULL) { CHECK_PARAM(param, cJSON_Number); *val = param->valueint; *type = SCP_PACKET_TYPE_RESPONSE; if (NULL != param_ret) *param_ret = cJSON_GetObjectItem(root, "result"); return 0; } param = cJSON_GetObjectItem(root, "method"); if (param != NULL) { CHECK_PARAM(param, cJSON_String); if (0 == strncmp(param->valuestring, "read", SCP_METHOD_STR_LEN)) *val = SESSION_TYPE_SOURCE; else if (0 == strncmp(param->valuestring, "write", SCP_METHOD_STR_LEN)) *val = SESSION_TYPE_TARGET; else return SCP_ERROR_CODE_CONTROL_VALUE_ILLEGAL; *type = SCP_PACKET_TYPE_REQUEST; if (NULL != param_ret) *param_ret = cJSON_GetObjectItem(root, "params"); return 0; } param = cJSON_GetObjectItem(root, "data_offset"); if (param != NULL) { CHECK_PARAM(param, cJSON_Number); *val = param->valueint; *type = SCP_PACKET_TYPE_DATA; return 0; } return SCP_ERROR_CODE_CONTROL_SECTION_NOT_FOUND; } int send_file_data(scp_session *psession) { int ret = 0; int fd = -1; int file_size = 0; int state = 0; cJSON* control = NULL; cJSON* control_offset = NULL; //assert(psession != NULL); control = cJSON_CreateObject(); if (NULL == control) { ret = SCP_ERROR_CODE_SERVER_ERROR; goto send_data_session_end; } cJSON_AddNumberToObject(control, "id", psession->id); cJSON_AddNumberToObject(control, "data_offset", 0); control_offset = cJSON_GetObjectItem(control, "data_offset"); if (NULL == control) { ret = SCP_ERROR_CODE_SERVER_ERROR; goto send_data_session_end; } ctx_rdlock_session(SESSION_TYPE_SOURCE); fd = psession->fd; file_size = psession->file_size; ctx_unlock_session(SESSION_TYPE_SOURCE); //assert(fd >= 0); //assert(file_size >= 0); unsigned char buf[SCP_PACKET_MAX_SIZE]; SCP_HEADER *scp_hdr = (SCP_HEADER *)buf; unsigned char *buf_ctrl = SCP_HEADER_GET_PAYLOAD(scp_hdr, 0); int data_len = 0; int pkt_len = 0; int len = 0; int offset = 0; SCPSDebug("send_file_data start."); while (offset < file_size) { //设置数据报文控制信息 cJSON_SetIntValue(control_offset, offset); pkt_len = scp_make_packet(buf, control); //读取文件数据 data_len = (SCP_PACKET_MAX_SIZE - pkt_len); if (file_size - offset < data_len) data_len = file_size - offset; scp_hdr->data_len = htons(data_len); len = scp_fd_read_direct(fd, buf + pkt_len, data_len); if (len < data_len) { ret = SCP_ERROR_CODE_SERVER_ERROR; break; } SCPSDebug("fd = %d, make data pack %d %d.", fd, offset, data_len); //检查任务是否已被停止 ctx_lock_data_send(); while (scp_contextp->data_pack_num >= scp_contextp->data_speed_limit) { ctx_wait_data_send(); } scp_contextp->data_pack_num++; ctx_unlock_data_send(); //SCPSDebug("get condition."); ctx_rdlock_session(SESSION_TYPE_SOURCE); state = psession->state; ctx_unlock_session(SESSION_TYPE_SOURCE); if (SESSION_STATE_HALT == state) { SCPSDebug("get halt state."); break; } //SCPSDebug("send data."); if (ctx_send_request_func != NULL) { ctx_send_request_func(buf, pkt_len + data_len); } offset += data_len; } SCPSDebug("send data finish."); ctx_wrlock_session(SESSION_TYPE_SOURCE); clean_session(SESSION_TYPE_SOURCE, psession); ctx_unlock_session(SESSION_TYPE_SOURCE); send_data_session_end: if (NULL != control) { cJSON_Delete(control); } if (NULL != ctx_send_callback_func) { ctx_send_callback_func(); } return ret; } int recv_file_data(int id, const unsigned char *buf, int offset) { int ret = 0; int ses_index = -1; scp_session *psession = NULL; scp_target_session *pext = NULL; int data_len = 0; int len = 0; const unsigned char *buf_data; const SCP_HEADER *hdr = (SCP_HEADER *)buf; //assert(control != NULL) //assert(buf != NULL) SCPSDebug("recv_file_data start."); ctx_wrlock_session(SESSION_TYPE_TARGET); ses_index = match_session(SESSION_TYPE_TARGET, id); if (-1 == ses_index) goto error_recv_data; //匹配失败,不回复 psession = ctx_get_session(SESSION_TYPE_TARGET, ses_index); pext = ctx_get_target_extention(ses_index); if (offset != pext->offset) { ret = SCP_ERROR_CODE_FILE_CHECK_DATA_LOST; goto error_recv_data; } //SCPSDebug("offset check."); psession->expire = 0; data_len = ntohs(hdr->data_len); len = ntohs(hdr->ctrl_len); buf_data = SCP_HEADER_GET_PAYLOAD(hdr, SCP_PADDING_LENGTH(len)); if (data_len > 0) { //SCPSDebug("write data to file %d.", data_len); len = scp_fd_write_direct(psession->fd, buf_data, data_len); if (len < data_len) { ret = SCP_ERROR_CODE_SERVER_ERROR; goto error_recv_data; } SHA256_Update(&(pext->ctx), buf_data, data_len); } pext->offset += data_len; if (pext->offset >= psession->file_size) { SCPSDebug("get all data."); ret = SCP_ERROR_CODE_FILE_CHECK_PASS; if (pext->offset > 0) { unsigned char dgest[SCP_SHA_CHECKSUM_LEN] = {0}; SHA256_Final(dgest, &(pext->ctx)); if (memcmp(pext->checksum, dgest, SCP_SHA_CHECKSUM_LEN)) { //SCPSDebug("wrong checksum."); ret = SCP_ERROR_CODE_FILE_CHECK_CHECKSUM_FAIL; } } set_file_time(psession->fd, pext->time[0], pext->time[1]); } error_recv_data: if (ret != 0 && ses_index != -1) { //接收数据完成或失败,关闭session //接收文件失败时是否需要删除文件? clean_session(SESSION_TYPE_TARGET, psession); } ctx_unlock_session(SESSION_TYPE_TARGET); return ret; } int stop_send_file_data(int id) { int ses_index = -1; scp_session *psession = NULL; SCPSDebug("stop_send_file_data start."); ctx_wrlock_session(SESSION_TYPE_SOURCE); do { ses_index = match_session(SESSION_TYPE_SOURCE, id); if (-1 == ses_index) { break; } SCPSDebug("stop session %d.", ses_index); psession = ctx_get_session(SESSION_TYPE_SOURCE, ses_index); psession->state = SESSION_STATE_HALT; } while (1); ctx_unlock_session(SESSION_TYPE_SOURCE); return SCP_ERROR_CODE_ACCEPT; } int send_file_request(int id, cJSON *control, int *new_session, cJSON **new_status) { int ret = 0; int ses_index = -1; scp_session *psession = NULL; int fd = -1; cJSON *param = NULL, *param_options = NULL; char *filename = NULL; int max_size = 0; int set_date = 0; struct stat stat_i; param = cJSON_GetObjectItem(control, "filename"); CHECK_PARAM(param, cJSON_String); filename = param->valuestring; if (strlen(filename) > SCP_MAX_FILEPATH_LEN) { return SCP_ERROR_CODE_CONTROL_VALUE_ILLEGAL; } param_options = cJSON_GetObjectItem(control, "option"); if (NULL != param_options) { CHECK_PARAM(param_options, cJSON_Object); param = cJSON_GetObjectItem(param_options, "max_size"); if (NULL != param) { CHECK_PARAM(param, cJSON_Number); max_size = param->valueint; } param = cJSON_GetObjectItem(param_options, "send_date"); if (NULL != param) { CHECK_PARAM(param, cJSON_Number); set_date = 1; } } if (0 != check_file_permission(filename, SESSION_TYPE_SOURCE, set_date)) { return SCP_ERROR_CODE_OPERATION_NO_PERMISSION; } if (0 != stat(filename, &stat_i)) { if (ENOENT == errno) return SCP_ERROR_CODE_OPERATION_FILE_NOT_FOUND; else return SCP_ERROR_CODE_SERVER_ERROR; } if (max_size > 0 && stat_i.st_size > max_size) { return SCP_ERROR_CODE_OPERATION_FILE_OVER_SIZE; } SCPSDebug("generate file status."); //生成文件基本信息 char mode[5]; sprintf(mode, "%04o", stat_i.st_mode & 0x0fff); cJSON* status = cJSON_CreateObject(); cJSON_AddNumberToObject(status, "size", stat_i.st_size); cJSON_AddStringToObject(status, "permissions", mode); if (set_date) { cJSON* date = cJSON_CreateObject(); cJSON_AddNumberToObject(date, "change_time", stat_i.st_mtime); cJSON_AddNumberToObject(date, "access_time", stat_i.st_atime); cJSON_AddItemToObject(status, "date", date); } SCPSDebug("send_file_request start."); if (stat_i.st_size <= 0) { SCPSDebug("filesize 0."); cJSON_AddStringToObject(status, "checksum", "0000000000000000000000000000000000000000000000000000000000000000"); ses_index = -1; goto skip_session; } ctx_wrlock_session(SESSION_TYPE_SOURCE); ret = scp_open_file_read(&fd, filename); if (ret < 0) { goto error_send_request; } ret = create_session(SESSION_TYPE_SOURCE, id, fd, &ses_index); if (ret) { goto error_send_request; } psession = ctx_get_session(SESSION_TYPE_SOURCE, ses_index); if (stat_i.st_size > 0) { unsigned char checksum[SCP_SHA_CHECKSUM_LEN]; char checksum_HEX[SCP_SHA_CHECKSUM_STR_LEN + 1]; SCPSDebug("calculate checksum."); if (calc_checksum(fd, checksum, stat_i.st_size) < 0) { ret = SCP_ERROR_CODE_SERVER_ERROR; goto error_send_request; } bin2hex(checksum, checksum_HEX, SCP_SHA_CHECKSUM_LEN); checksum_HEX[SCP_SHA_CHECKSUM_STR_LEN] = '\0'; cJSON_AddStringToObject(status, "checksum", checksum_HEX); } psession->file_size = stat_i.st_size; SCPSDebug("file %s, size = %d\n", param->valuestring, psession->file_size); skip_session: //数据发送任务需要等发送完response包后再创建 *new_session = ses_index; *new_status = status; ctx_unlock_session(SESSION_TYPE_SOURCE); return SCP_ERROR_CODE_ACCEPT; error_send_request: if (fd >= 0) { scp_close_file(&fd); } if (0 != ses_index) { clean_session(SESSION_TYPE_SOURCE, psession); } ctx_unlock_session(SESSION_TYPE_SOURCE); return ret; } int recv_file_request(int id, cJSON* control) { int ret = 0; int ses_index = -1; scp_session *psession = NULL; scp_target_session *pext = NULL; int fd = -1; cJSON *param = NULL, *param_status = NULL, *param2 = NULL; char *filename = NULL; mode_t mode = 0; int set_date = 0; int size = 0; char *checksum = NULL; int atime = -1; int mtime = -1; //assert(control != NULL) param = cJSON_GetObjectItem(control, "filename"); CHECK_PARAM(param, cJSON_String); filename = param->valuestring; if (strlen(filename) > SCP_MAX_FILEPATH_LEN) { return SCP_ERROR_CODE_CONTROL_VALUE_ILLEGAL; } param_status = cJSON_GetObjectItem(control, "file_status"); CHECK_PARAM(param_status, cJSON_Object); param = cJSON_GetObjectItem(param_status, "date"); if (NULL != param) { //SCPSDebug("find date param."); CHECK_PARAM(param, cJSON_Object); param2 = cJSON_GetObjectItem(param, "access_time"); if (NULL != param2) { CHECK_PARAM(param2, cJSON_Number); atime = param2->valueint; } param2 = cJSON_GetObjectItem(param, "change_time"); if (NULL != param2) { CHECK_PARAM(param2, cJSON_Number); mtime = param2->valueint; } set_date = 1; } param = cJSON_GetObjectItem(param_status, "permissions"); if (NULL != param) { CHECK_PARAM(param, cJSON_String); sscanf(param->valuestring, "%o", &mode); } param = cJSON_GetObjectItem(param_status, "size"); CHECK_PARAM(param, cJSON_Number); size = param->valueint; // 文件大小为0时checksum无意义 if (size > 0) { param = cJSON_GetObjectItem(param_status, "checksum"); CHECK_PARAM(param, cJSON_String); checksum = param->valuestring; if (strlen(checksum) != SCP_SHA_CHECKSUM_STR_LEN) { return SCP_ERROR_CODE_CONTROL_VALUE_ILLEGAL; } } if (0 != check_file_permission(filename, SESSION_TYPE_TARGET, set_date)) { return SCP_ERROR_CODE_OPERATION_NO_PERMISSION; } SCPSDebug("recv_file_request start."); ctx_wrlock_session(SESSION_TYPE_TARGET); ret = scp_open_file_write(&fd, filename); if (ret) { goto error_recv_request; } if (0 != mode) fchmod(fd, mode); if (size <= 0) { SCPSDebug("filesize 0."); set_file_time(fd, atime, mtime); scp_close_file(&fd); goto skip_session; } ret = create_session(SESSION_TYPE_TARGET, id, fd, &ses_index); if (ret) { goto error_recv_request; } init_session_target(ses_index); // 设置文件基本信息 psession = ctx_get_session(SESSION_TYPE_TARGET, ses_index); pext = ctx_get_target_extention(ses_index); SCPSDebug("set file stat."); pext->time[0] = atime; pext->time[1] = mtime; psession->file_size = size; if (size > 0) { SCPSDebug("cache checksum."); hex2bin(checksum, (unsigned char *)pext->checksum, SCP_SHA_CHECKSUM_STR_LEN); } skip_session: ctx_unlock_session(SESSION_TYPE_TARGET); return SCP_ERROR_CODE_ACCEPT; error_recv_request: if (fd >= 0) { scp_close_file(&fd); } if (0 != ses_index) { clean_session(SESSION_TYPE_TARGET, psession); } ctx_unlock_session(SESSION_TYPE_TARGET); return ret; } int scp_open_file_read(int *fd, char *filename) { //assert(*fd < 0); SCPSDebug("open file %s read", filename); int new_fd = open(filename, O_RDONLY); if (new_fd < 0) return SCP_ERROR_CODE_OPERATION_FILE_NOT_FOUND; if (flock(new_fd, LOCK_SH | LOCK_NB)) { SCPSDebug("lock file %s failed.", filename); close(new_fd); return SCP_ERROR_CODE_OPERATION_FILE_IN_USE; } *fd = new_fd; return 0; } int scp_open_file_write(int *fd, char *filename) { //assert(*fd < 0); SCPSDebug("open file %s write", filename); int new_fd = -1; if (access(filename, F_OK) != -1) new_fd = open(filename, O_WRONLY | O_TRUNC); else new_fd = open(filename, O_WRONLY | O_CREAT); if (new_fd < 0) return SCP_ERROR_CODE_SERVER_ERROR; if (flock(new_fd, LOCK_EX | LOCK_NB)) { SCPSDebug("lock file %s failed.", filename); close(new_fd); return SCP_ERROR_CODE_OPERATION_FILE_IN_USE; } *fd = new_fd; return 0; } int scp_close_file(int *fd) { if (*fd < 0) return 0; flock(*fd, LOCK_UN); close(*fd); *fd = -1; return 0; } int init_session_target(int ses_index) { scp_contextp->target_ext[ses_index].offset = 0; SHA256_Init(&(scp_contextp->target_ext[ses_index].ctx)); return 0; } int create_session(int type, int id, int fd, int *res) { SCPSDebug("create session %d %d.", type, id); int len; int i = 0; int tar = -1; scp_session *psession; ctx_session_foreach(type, i, psession) { if (psession->state == SESSION_STATE_STOP && -1 == tar) tar = i; if (SESSION_TYPE_TARGET == type && psession->id == id) { //只有接收模式的id对重复是敏感的 return SCP_ERROR_CODE_CONTROL_VALUE_ILLEGAL; } } if (-1 == tar && i >= scp_contextp->session_max[type]) { if (scp_contextp->session_max[type] < SCP_MAX_SESSION_NUM) { scp_contextp->session_max[type]++; } else { SCPSDebug("session %d full.", type); return SCP_ERROR_CODE_SERVER_ERROR; } tar = i; } scp_contextp->session[type][tar] = (scp_session) { .id = id, .fd = fd, .file_size = 0, .state = SESSION_STATE_RUNNING, .expire = 0 }; SCPSDebug("new session %d %d.", type, tar); *res = tar; return 0; } int match_session(int type, int id) { int i = 0; scp_session *psession; ctx_session_foreach(type, i, psession) { if (psession->state != SESSION_STATE_RUNNING) continue; if (psession->id == id) { SCPSDebug("match session %d %d %d.", type, id, i); return i; } } SCPSDebug("session %d %d not found.", type, id); return -1; } int clean_session(int type, scp_session* psession) { //SCPSDebug("clean session %d %d.", type, psession->id); psession->state = SESSION_STATE_STOP; scp_close_file(&(psession->fd)); //target扩展信息没有动态申请内存,无需处理 while ((scp_contextp->session_max[type] > 0) && (SESSION_STATE_STOP == scp_contextp->session[type][scp_contextp->session_max[type] - 1].state)) scp_contextp->session_max[type]--; SCPSDebug("session %d %d cleaned, session max %d.", type, psession->id, scp_contextp->session_max[type]); return 0; } void init_session() { int i = 0; for (i = 0; i < SCP_MAX_SESSION_NUM; i++) { scp_contextp->session[SESSION_TYPE_SOURCE][i].state = SESSION_STATE_STOP; scp_contextp->session[SESSION_TYPE_TARGET][i].state = SESSION_STATE_STOP; } scp_contextp->session_max[SESSION_TYPE_SOURCE] = 0; scp_contextp->session_max[SESSION_TYPE_TARGET] = 0; pthread_rwlock_init(&(scp_contextp->sessionlock[SESSION_TYPE_SOURCE]), NULL); pthread_rwlock_init(&(scp_contextp->sessionlock[SESSION_TYPE_TARGET]), NULL); } void close_all_session() { int i = 0; scp_session *psession; SCPSDebug("clean all sessions."); ctx_wrlock_session(SESSION_TYPE_TARGET); ctx_session_foreach(SESSION_TYPE_TARGET, i, psession) { if (psession->state == SESSION_STATE_RUNNING) clean_session(SESSION_TYPE_TARGET, psession); } ctx_unlock_session(SESSION_TYPE_TARGET); // 发送会话需等任务自行结束 ctx_wrlock_session(SESSION_TYPE_SOURCE); ctx_session_foreach(SESSION_TYPE_SOURCE, i, psession) { if (psession->state == SESSION_STATE_RUNNING) psession->state = SESSION_STATE_HALT; } ctx_unlock_session(SESSION_TYPE_SOURCE); // 防止有任务卡在发包限速的位置 ctx_lock_data_send(); scp_contextp->data_speed_limit = SCP_MAX_SESSION_NUM; scp_contextp->data_pack_num = 0; ctx_active_data_send(); ctx_unlock_data_send(); usleep(100000); pthread_rwlock_destroy(&(scp_contextp->sessionlock[SESSION_TYPE_SOURCE])); pthread_rwlock_destroy(&(scp_contextp->sessionlock[SESSION_TYPE_TARGET])); } void scp_data_flush() { // 清空发包计数 ctx_lock_data_send(); scp_contextp->data_pack_num = 0; ctx_active_data_send(); ctx_unlock_data_send(); // 检查收包超时 int i = 0; scp_session *psession; ctx_wrlock_session(SESSION_TYPE_TARGET); ctx_session_foreach(SESSION_TYPE_TARGET, i, psession) { if (psession->state == SESSION_STATE_RUNNING) { psession->expire++; if (psession->expire >= SCP_DEFAULT_TIMEOUT) { SCPSDebug("target session %d timeout, id: %d.", psession->id); clean_session(SESSION_TYPE_TARGET, psession); } } } ctx_unlock_session(SESSION_TYPE_TARGET); } void scp_set_data_speed(int speed_limit) { ctx_lock_data_send(); scp_contextp->data_speed_limit = speed_limit; ctx_unlock_data_send(); } void scp_init( scp_context *context, p_scp_send_request sdp, p_scp_send_data_end_callback sdep) { if (NULL == context) { return; } scp_contextp = context; // 设置数据发送任务的回调函数,尤其是发包接口一定要统一 scp_contextp->send_func = sdp; scp_contextp->finish_func = sdep; // 数据发送限速模块 pthread_mutex_init(&(scp_contextp->speedlock), NULL); pthread_cond_init(&(scp_contextp->speedcond), NULL); scp_contextp->data_pack_num = 0; scp_contextp->data_speed_limit = SCP_DEFAULT_SPEED_LIMIT; } void scp_close() { close_all_session(); pthread_mutex_destroy(&(scp_contextp->speedlock)); pthread_cond_destroy(&(scp_contextp->speedcond)); }文件什么意思,尤其是这个部分static SCP_FILE_PERMISSION file_permissions[] = { {USBDISK_VOICEMAIL_RECORD_PATH, OPT_READ | OPT_DATE}, {USBDISK_VOICEMAIL_NOTIFY_PATH, OPT_READ | OPT_DATE}, {LARGEDATA_VOICEMAIL_RECORD_PATH, OPT_READ | OPT_DATE}, {REGION_JSON_GZ_FILE, OPT_READ | OPT_DATE}, {REGION_JSON_GZ_MD5_FILE, OPT_READ | OPT_DATE}, {ISPPROFILE_GZ_JSON_FILE, OPT_READ | OPT_DATE}, {ISPPROFILE_GZ_JSON_MD5_FILE, OPT_READ | OPT_DATE}, {ISPLOGO_PNG_GZ_FILE, OPT_READ | OPT_DATE}, {ISPLOGO_PNG_GZ_MD5_FILE, OPT_READ | OPT_DATE}, {AGC_DATABUFF_ISPLOGO_PNG_GZ_FILE, OPT_READ | OPT_DATE}, {AGC_DATABUFF_ISPLOGO_PNG_GZ_MD5_FILE, OPT_READ | OPT_DATE}, {TESTFILE1, OPT_READ | OPT_WRITE | OPT_DATE}, {TESTFILE2, OPT_READ | OPT_WRITE | OPT_DATE}, };
最新发布
12-02
中文分析FAILED: out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/LINKED/mwgifker.ko out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/LINKED/Module.symvers /bin/bash -c "(source out/var_export.sh && cd out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT && source /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/device/mediatek/build/tasks/env.sh;make -j \$(cat /proc/cpuinfo |grep processor|wc -l) -C /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/vendor/mediatek/tv/kernel/5.15_14 CC=/home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/prebuilts/clang/host/linux-x86/clang-r475365b/bin/clang ARCH=arm CROSS_COMPILE=/home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/prebuilts/mtk_toolchain/gcc-arm-linux-gnu-5.5.0-ubuntu/x86_64/bin/arm-linux-gnueabi- O=/home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/KERNEL_OBJ_5.15 LD=/home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/prebuilts/clang/host/linux-x86/clang-r475365b/bin/ld.lld M=/home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT LOCAL_PATH=/home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/vendor/mediatek/tv/misdk/stbmsapi/gif KBUILD_EXTRA_SYMBOLS=\"/home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/utpa2k.ko_intermediates/LINKED/Module.symvers\" src=/home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/vendor/mediatek/tv/misdk/stbmsapi/gif KBUILD_MODPOST_WARN=y LOCAL_MODULE=mwgifker.ko ) && (prebuilts/build-tools/linux-x86/bin/acp /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/mwgifker.ko out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/LINKED/mwgifker.ko ) && (prebuilts/build-tools/linux-x86/bin/acp /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/Module.symvers out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/LINKED/Module.symvers ) && (mkdir -p out/target/product/khandala/symbols/ko/ ) && (prebuilts/build-tools/linux-x86/bin/acp /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/mwgifker.ko out/target/product/khandala/symbols/ko/mwgifker.ko )" out/var_export.sh: line 62: export: `apollo-prod-2105 -DCUSTOMER=mediatek -DVERSION=t-apollo-mp-2105-refu-1640-001-306 -DCOMPANY=mediatek -DBUILD_CMD=default -DPRODUCT_SW_VERSION=0.1.0.0.M001 -DDATA_SEPARATION_PRO_ID_PATH=/vendor/project_id -DDATA_SEPARATION_PRO_ID_FILE=project_id.ini -DDATA_SEPARATION_DATAINDEX_PATH=/vendor/cusdata/config/dataIndex -DSUPPORT_FUSION_TTY -DUTOPIA_SUPPORT -DSYS_CB_RECORD_SUPPORT -DSYS_MTAL_RECORD_SUPPORT -DCONFIG_SUPPORT_OVL -DFUSION_DFB_SUPPORT -DAPP_MERGE_INTO_ONE_OSD -DMW_MERGE_INTO_ONE_OSD -DCC_MERGE_INTO_ONE_OSD -DAPP_OLED_SUPPORT -DMW_FUSION_TV_SUPPORT -DAPP_FUSION_USE_MI_SYS_PARSE_INI_FILE -DSUPPORT_FILESYSTEM_UPGRADE_PARTITION -DAPP_FUSION_APOLLO_FILE_PATH=/vendor/tvconfig/apollo -DAPP_FUSION_MI_FILE_PATH=/vendor/tvconfig/config -DAPOLLO_TO_LOGCAT=1 -DAPP_BLUE_LIGHT_SUPPORT -DAPP_HDR_SUPPORT -DAPP_LEGACY_UX_DISABLE_SUPPORT -DAPP_CUSTOMER_DEF_SOLE_HP_VOL -DAPP_SUPPORT_HEVC_10_BIT -DSYS_ANDROID_TV_TIF_SUPPORT -DCECNFY5VSTATUS -DMW_SVL_EVERY_NOTIFY -DMW_SUPPORT_2STC -DNDEBUG -DMW_SYM_SUPPORT -DSIG_TRACER_ENABLED -DCLI_LEVEL_VERBOSE -DEXT_DBG_DEV -DCLI_SUPPORT -DCC_WIFI_U2_SPEED_ON_U3PORT -DMW_DBG_SUPPORT_CHARS_COUNTER -DMW_DBG_CHARS_COUNT_DFT_ENABLE -DTIME_MEASUREMENT -DTMS_INIT_LEVEL_COMMON=TMS_LEVEL_OFF_LINE -DTIME_MEASUREMENT_DEFAULT_OFF -DCC_MTD_ENCRYPT_SUPPORT -DCC_MSDC_AES_SUPPORT -DMW_FAKE_THREAD -DAPP_FUSION_TV_SUPPORT -DMW_SUPPORT_DOLBY_VISION -DCC_SUPPORT_DOLBY_VISION -DAPP_SUPPORT_DOLBY_VISION -DDT_SUPPORT_MULTI_CLOCK -DDLM_USE_AES_MODE -DCC_DLM_V2 -DDLM_SHA_256 -DDLM_GCPU_SHA_256 -DDLM_USE_GCPU_AES -DUPGRADE_PARTITION_NO_FS -DDLM_USE_LARGE_BUFFER -DSYS_MTKTVAPI_SUPPORT -DSYS_QUIET_HOT_BOOT_SUPPORT -DMW_FAKE_THREAD -DSYS_MTK_STREAM_RPC_SUPPORT -DSYS_CMPB_RPC_SUPPORT -DSYS_MTK_DRM_RPC_SUPPORT -DMTK_DRM_SUPPORT -DHELIX_SUPPORT -DMODEL_NAME=kenai2020 -DCUST_MODEL=kenai2020 -DSERIAL_NUMBER=IDTV -DUSB_UPG_VERSION= -DDUAL_CHANNEL_SUPPORT -DSN_FLASH_USE_NAND -DREPLACE_EEPROM_WITH_EMMC -DSYS_EMMC_SUPPORT -DSYS_EMMC_SUPPORT -DSN_NAND_FLASH_2=block/platform/mstar_mci.0/by-name/cha -DSN_NAND_FLASH_4=block/platform/mstar_mci.0/by-name/chb -DSN_FLASH_PVR=block/platform/mstar_mci.0/by-name/schedpvr -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -DFM_EXT_FS_SUPPORT -D_CPU_LITTLE_ENDIAN_ -DLINUX_TURNKEY_SOLUTION -DSINGLE_PROCESS -DSYS_FAST_BOOT -DSYS_NETWORK_LAZY_INIT -DSYS_HOTKEY_WAKEUP_SUPPORT -DMW_HOTKEY_WAKEUP_SUPPORT -DLINUX_MEM_SOLUTION -DRPC_ENABLE -DHEADER_COMMON_H=inc/u_common.h -DSWI_CALLBACK -DKEY_FROM_DFB -DSVCTX_SPLIT_SUPPORT -DANA_TUNER_SUPPORT -DV4L_SUPPORT -DXML_SUPPORT -DINET_SUPPORT -DUSE_SMART_FILE -DMW_IPV6_SUPPORT -DSYS_IPV6_SUPPORT -DNETFLIX_SUPPORT -DCC_NETFLIX_CE3_SUPPORT -DANDROID_DLNA_SUPPORT -DANDROID_PULL_DLNA_SUPPORT -DMW_JPG_SUPPORT -DMW_BMP_SUPPORT -DMW_PNG_SUPPORT -DMW_GIF_SUPPORT -DMW_WEBP_SUPPORT -DMW_MP3_SUPPORT -DMW_CM_PLAYBACK_SUPPORT -DVIDEO_PLAYBACK_SUPPORT -DMW_MMP_VIDEO_SUPPORT -DMM_LAST_MEMORY_SUPPORT -DENABLE_MULTIMEDIA -DMW_TV_AV_BYPASS_SUPPORT -DTIME_SHIFT_SUPPORT -DTIME_SHIFT_ENCRYPTION -DMW_PVR_PAUSE_DONOT_STOP_STC -DMW_TV_AV_BYPASS_SUPPORT -DSYS_RECORD_SUPPORT -DMW_ENABLE_TRICK_REACH_VALID_RANGE_END_MSG -DAPP_NAV_REC_SUPPORT -DENABLE_DIVX_DRM -DCMPB_DASH_SUPPORT -DCMPB_OVER_MI_MM -DSUPPORT_RATING_PVR -DAPP_AM_NO_POWER_DOWN -DAPP_BACKGROUND_MANAGER_ENABLED -DSYS_SCHED_PVR_FLASH_SUPPORT -DFIRMWARE_UPGRADE -DAPP_UPG_SUPPORT -DAPP_NET_UPG_SUPPORT -DCC_OSD_USE_FBM -DSUPPORT_FLASH_PQ -DSUPPORT_FLASH_AQ -DADSP_BIN_SUPPORT -DCHIP_SPEC_SUPPORT -DLINUX_NAND_USE_SDM -DMW_ASH_DUALMONO_RECOVER -DDISABLE_BASIC_PART -DSYS_3RD_RO -DMW_MSS_SUPPORT -DAPP_FACT_SUPPORT -DCC_SECURE_BOOT_WO_RAMDISK -DANDROID -DIMGDRV_ANDROID -DANDROID_TOOLCHAIN -DANDROID_TWO_WORLDS -DDISABLE_TV_WORLD_NW_SETTING -DCC_NATIVE_CB2_NOTIFY -DCC_PDWNC_REBOOT_NOTIFY -DMW_SUPPORT_MTK_ANDROID_RM -DAPP_SUPPORT_MTK_ANDROID_RM -DAPP_SUPPORT_4K2K -DMW_SUPPORT_4K2K -DAPP_3D_PHOTO_SUPPORT -DMW_PHOTO_SHOW_ON_VDP -DAPP_SUPPORT_STR_CORE_OFF -DMW_SUPPORT_STR -DAPP_DOLBY_AUD_SUPPORT -DMW_DOLBY_AUD_SUPPORT -DAPP_DOLBY_AUD_SUPPORT_MS12B -DAPP_NAV_COMP_WW_ENABLE_CHECK_SUPPORT -DAPP_IF_MTAL_MULTIPROCESS_CALLBACK -DAPP_MPEG_NR_SUPPORT -DAPP_DI_SUPPORT -DAPP_GAME_MODE_SUPPORT -DAPP_MERGE_INTO_ONE_OSD -DMW_MERGE_INTO_ONE_OSD -DCC_MERGE_INTO_ONE_OSD -DAPP_MTK_MVIEW_SUPPORT -DFUSION_DFB_SUPPORT -DAPP_MENU_SUPPORT_DYNAMIC_LIFE_CYCLE -DAPP_IMG_UI -DAPP_537X_SUPPORT -DAPP_CFG_EEPROM_SUPPORT -DAPP_NAV_IPTS_LST -DAPP_NAV_IPTS_LST_BAR_ACTIVE -DAPP_NAV_IPTS_LST_BAR_DISABLE -DAPP_INPUT_SRC_HOTKEY -DAPP_EPG_ICON_MSG -DAPP_NAV_FRZ_SUPPORT -DAPP_NAV_MISC_COMP -DAPP_EPG_FULL_VIDEO -DAPP_MLM_S639_TO_LANGIDX_SUPPORT -DAPP_HV_POS_MODIFICATION_SUPPORT -DAPP_NAV_IPTS_DISABLE_XNG_CH_AS_FOCUS_AV -DAPP_SUPPORT_AM_DEFAULT_KEY_HANDLER -DAPP_5893_MHL_SUPPORT_PORT -DAPP_MENU_STORE_CH_LST_BY_AGENT -DAPP_SINGLE_COLOR_TEMP_PATH -DAPP_SPDIF_DELAY_SUPPORT -DAPP_NETWORK_SUPPORT -DAPP_NETWORK_WIFI_SUPPORT -DAPP_NETWORK_IPV6_SUPPORT -DAPP_MMP_VIDEO_PLAYBACK_ENABLE -DMMP_FB_RC_IS_ENABLE_VIDEO_FILTER -DMMP_FB_RC_IS_ENABLE_TEXT_FILTER -DAPP_NAV_REC_SUPPORT -DAPP_NAV_REC_TSHIFT_SUPPORT -DAPP_NAV_REC_DTV_TSHIFT_SUPPORT -DAPP_NAV_REC_SUPPORT -DAPP_NAV_REC_PVR_SUPPORT -DAPP_NAV_REC_DTV_PVR_SUPPORT -DAPP_MMP_PVR_SUPPORT -DAPP_REMINDER_UTIL_SUPPORT -DAPP_NAV_REC_PVR_SCH_SUPPORT -DAPP_SCHED_PVR_FLASH_SUPPORT -DAPP_VIDEO_FLIP_SUPPORT -DAPP_VIDEO_MIRROR_SUPPORT -DAPP_IMG_CENTER_SUPPORT -DAPP_NAV_USE_FRAME_AS_ROOT_WIDGET -DCONFIG_SUPPORT_OVL -DCC_FRAME_OFFSET -DCC_SOURCE_AUTO_DETECT -DFUSION_DFB_SUPPORT -DCC_MTD_SUPPORT_64_PARTITION -DCC_SUPPORT_AVB -DAPP_MERGE_INTO_ONE_OSD -DMW_MERGE_INTO_ONE_OSD -DCC_MERGE_INTO_ONE_OSD -DCC_SUPPORT_AB_UPDATE -DCC_SUPPORT_DTO -DCC_SUPPORT_DRAM_3GB -DCC_SUPPORT_DRAM_32BIT_SIZE -DPICACHU_SUPPORT -DCC_FBM_TWO_4K2K -DCC_SUPPORT_DOLBY_VISION -DCC_SUPPORT_SMI -DCC_SUPPORT_EMI -DCC_SUPPORT_M4U -DCC_DTVDRV_RUNTIME_PM -DCC_NO_BIM_INTR -DCC_SYM_SUPPORT -DSIG_TRACER_ENABLED -DCC_FBM_SUPPORT_SWDMX -DCC_KERNEL_HS400_SUPPORT -DCC_EMMC_HS400 -DCC_HDMI_2_0_HDCP_BIN -DCC_HDMI_2_0_SUPPORT -DCC_QUIET_HOT_BOOT_SUPPORT -DCC_BT_WAKEUP_SUPPORT -DCC_SUPPORT_CHIPID -DREPLACE_EEPROM_WITH_EMMC -DSYS_EMMC_SUPPORT -DCC_WIFI_WOWLAN_SUPPORT -DCC_WIFI_WOWLAN_LOW_ACTIVE -DCC_FBM_MAPPING_ONE_BY_ONE -DCC_VDEC_FBM_DYNAMIC_MAPPING -DCC_JPEG_FBM_DYNAMIC_MAPPING -DCC_UBOOT_MINIGUNZIP_SUPPORT -DCC_ENABLE_SEAMLESS_FOR_2D -DCC_ENABLE_SEAMLESS_FOR_MVC -DCC_SECURE_BOOT_WO_RAMDISK -DCC_SUPPORT_2STC -DDLM_USE_AES_MODE -DCC_DLM_V2 -DDLM_SHA_256 -DDLM_GCPU_SHA_256 -DDLM_USE_GCPU_AES -DUPGRADE_PARTITION_NO_FS -DDLM_USE_LARGE_BUFFER -DCC_ENABLE_SEAMLESS_FOR_MVC -DSYS_ANDROID_TV_TIF_SUPPORT -DCECNFY5VSTATUS -DMW_FAKE_THREAD -DCC_LOADER_LOGO_SUPPORT -DCC_SUPPORT_BL_DLYTIME_CUT -DCC_LOADER_LOGO_LONG_TIME -DCC_EMMC_UPGRADE_SUPPORT -DCC_SDMMC_EMMC_SUPPORT_USB_RECOVERY -DCC_MTD_ENCRYPT_SUPPORT -DCC_MSDC_AES_SUPPORT -DCC_UBOOT_QUIET_BOOT -DNDEBUG -DCC_KERNEL_NO_LOG -DOSAI_FOR_NUCLEUS -DLOADER_USB_UPGRADE -DAUTO_USB_UPGRADE_ENABLE=1 -DCC_DUALLOADER_SUPPORT -DCC_SUPPORT_STR -DCC_SUPPORT_STR_CORE_OFF -DCC_SUPPORT_STR_TEMP -DCC_SUPPORT_STR_DEBUG -DCC_STR_ONOFF_TEST_ENABLE -DTIME_MEASUREMENT -DLINUX_NAND_USE_SDM -DCC_NETFLIX_CMPB_SUPPORT -DNETFLIX_SUPPORT -DCC_NETFLIX_CE3_SUPPORT -DCC_FBM_TWO_FBP -DCC_SECOND_B2R_SUPPORT -DCC_SUPPORT_PRINT_MEM_INFO -DLINUX_TURNKEY_SOLUTION -DKEY_FROM_DFB -DSUPPORT_FLASH_PQ -DSUPPORT_FLASH_AQ -DADSP_BIN_SUPPORT -DCC_USE_2TB_EMMC -DCC_ENABLE_SKB -DCC_MSDC_ENABLE -DCC_EMMC_BOOT -DSN_FLASH_UBOOT_ENV=mmcblk0p3 -DTUNER_SUPPORT_MULTI_SYS_TV -DSUPPORT_MULTI_SYSTEM -DCC_H264_SUPPORT -DCC_IPV6_SUPPORT -DJPG_ENABLE -DCC_H264_SUPPORT -DENABLE_MULTIMEDIA -DTIME_SHIFT_SUPPORT -DSYS_RECORD_SUPPORT -DCC_AUD_MMP_FULL_SUPPORT -DCC_OSD_USE_FBM -DCHIP_SPEC_SUPPORT -DCC_DISABLE_BASIC_PART -DCC_FLIP_MIRROR_SUPPORT -DCC_FLIP_MIRROR_FROM_EEPROM -DCC_FLIP_ENABLE -DCC_FLIP_MIRROR_SUPPORT -DCC_FLIP_MIRROR_FROM_EEPROM -DCC_MIRROR_ENABLE -DCC_SUPPORT_4K2K -DCC_FBM_SUPPORT_4K2K -DSUPPORT_HDMI_YCBCR444 -DCC_4K2K_PHOTO_TO_VDO_BUFFER -DSUPPORT_3D_EXT_COMP_TRL=1 -DCC_VDEC_RM_SUPPORT -DCC_SUPPORT_VDEC_PREPARSE -DCC_SUPPORT_NPTV_SEAMLESS -DCC_SUPPORT_HDMI_FBOOTING -DCC_HDMI_ARC_SPDIF_CTRL -DCECNFY5VSTATUS -DCC_FBM_SUPPORT_DMXPID -DCC_3RD_RO -DANDROID -DCC_MIXSOUND_GAIN_NOT_SYNC_WITH_VOL -DCC_EMMC_ERASE_SIZE_ALIGNMENT_1M -DIMGDRV_ANDROID -DCC_ENABLE_ADECOMX -DCC_ENABLE_VDECOMX -DCC_ENABLE_VENCOMX -DVDEC_YUV_CVT_IMG -DCC_VOMX_TV_COEXIST -DCC_SECOND_B2R_SUPPORT -DCC_ENABLE_ADECOMX -DCC_SSIF_SUPPORT -DCC_3D_MM_DS_SUPPORT -DCC_SUPPORT_VSS -DCC_ENABLE_REBOOT_REASON -DANDROID_TOOLCHAIN -DCC_ANDROID_REBOOT -DCC_PDWNC_REBOOT_NOTIFY -DANDROID_TWO_WORLDS -DCC_ANDROID_TWO_WORLDS -DCC_SUPPORT_DYNAMIC_ENABLE_DFB_INPUTEVENT -DCC_SUPPORT_MTK_ANDROID_RM -DCC_SECURE_BOOT_V3 -DCC_SECURE_BOOT_SCRAMBLE -DCC_PRELOADER2_ENABLE -DCC_LOADER_VER_CHECK -DCC_MTAL_MULTIPROCESS_CALLBACK -DCC_SUPPORT_WIFI -DGAM_SUPPORT -DCC_FILMMAKER_MODE_SUPPORT -DENERGY_MODE_SUPPORT -DCC_SONYDEMOD_CXD2842 -DSONY_DEMOD_CRYSTAL_41M -DCC_EXTERNAL_DEMOD -DSUPPORT_USB30 -DCC_CONFIG_IRRX_COMMON_DRIVER_DTV -DDRV_IF_EU -DCC_NAV_DEMOD_DVBT -DCC_NAV_SCART -DUSE_ATD_IF_DEMOD -DCC_DVBT_SUPPORT -DCC_USE_MTAL -DCC_USB_SUPPORT_HUB -DCC_AUD_PWM_SAWLESS_PLL_EN -DCC_AUD_DVBT_SUPPORT -DCC_AUD_ENABLE_PLAY_MUTE_CONTROL -DCC_AUD_SILENCE_SUPPORT -DCC_MT5391_AUD_3_DECODER -DCC_MT5391_AUD_MW_AUTO_CTRL -DCC_AUD_4_DECODER_SUPPORT -DCC_AUD_DATASRAM -DCC_AUD_MIXSOUND_SUPPORT -DCC_AUD_HDMI_PARSER_2_0_SUPPORT -DCC_AUD_HDMI_PARSER_3_0_SUPPORT -DCC_AUD_SUPPORT_DUAL_DSP -DCC_AUD_DISABLE_2ND_DSP -DCC_AUD_DISABLE_2ND_DSP -DCC_AUD_ENLARGE_APROC_DRAM -DCC_AUD_ARM_SUPPORT -DCC_AUD_ARM11_SUPPORT -DCC_AUD_ARM_RENDER -DCC_AUD_RISCIEC_SUPPORT -DCC_AUD_RISCAOUT_SUPPORT -DCC_AUD_AOUT_128_SUPPORT -DCC_AUD_DSP_EU_MODEL -DCC_AUD_HP_DEPOP -DCC_AUD_RISCIEC_SUPPORT -DCC_AUD_RISCAOUT_SUPPORT -DCC_AUD_AOUT_128_SUPPORT -DCC_AUD_DOLBY_SUPPORT_MS12 -DCC_AUD_DOLBY_SUPPORT_MS12v2 -DCC_AUD_DOLBY_SUPPORT_MS12B -DCC_AUD_DOLBY_SUPPORT_DAPv2 -DCC_AUD_DOLBY_SUPPORT_MS12_RISCENC -DCC_AUD_CPUENC_SUPPORT -DCC_AUD_DOLBY_SUPPORT_DDC -DCC_AUD_DOLBY_SUPPORT_DDT -DCC_AUD_DTSM6 -DCC_AUD_NCSTOOL_SUPPORT -DCC_AUD_DSP_SUPPORT_MIXSOUND_MEMPLAY -DCC_AUD_DATA_UPLOAD_SUPPORT -DCC_AUD_SUPPORT_MS10 -DCC_AUD_SUPPORT_SPDIF_V20 -DCC_AUD_SUPPORT_NEW_TUNNEL_MODE -DCC_AUD_ENABLE_INTERNAL_LDO -DCC_SUPPORT_OD -DCC_PMIC_RICHTEK -DCC_ARM_GIC -DCC_ARM_TIMER -DNAV_CONFIG_FILE=config/nav_config_Oryx_m1v1.h -DCC_MT5893 -D_CPU_LITTLE_ENDIAN_ -DI1394_DRV_ONLY -DCC_SCPOS_EN -DCC_SRM_ON -DCC_53XX_SWDMX_V2 -Wall -Wno-format -DMT53XX_OSAI_MODULE -DMT53XX_FB_MODULE -DCC_DYNAMIC_POWER_ONOFF -DNDEBUG -Wno-unused-value -pipe -DONE_BINARY_REGION -DAPP_SEPARATE_INP_SRC_FOR_ATV_DTV -DCC_CI_PLUS_ECP_MI_SVP_SUPPORT -DCC_CI_PLUS_V20_SUPPORT -DCC_DVBT_SUPPORT -DCC_INTERNAL_CI -DCC_OPTEE_WITH_PVRKEY -DCC_PVR_PLAYBACK_USE_AESDMA -DCI_PLUS_IP_STRM_SUPPORT -DCI_PLUS_SUPPORT -DSYS_OAD_SUPPORT -DSYS_OVERRIDE_DISP_REGION_SUPPORT -DDVBT_CI_ENABLE': not a valid identifier Ubuntu OS=Ubuntu-18.04-x86_64 PATH=/home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/host/linux-x86/bin:/home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/vendor/mediatek/tv/tools/binary/open/build-tools:/home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/vendor/mediatek/tv/tools/binary/open/build-tools/1804:/home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/vendor/mediatek/tv/tools/binary/open/build-tools/1804/usr/bin:/mtkeda/dtv/cluster/odb:/home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/prebuilts/build-tools/path/linux-x86:/home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/.path ANDROID_BUILD_PATHS= ANDROID_TOP=/home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5 OS=Ubuntu-18.04-x86_64 make: Entering directory `/home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/vendor/mediatek/tv/kernel/5.15_14' make[1]: Entering directory `/home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/KERNEL_OBJ_5.15' CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/middleware/zlib/adler32.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/middleware/zlib/crc32.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/middleware/zlib/inffast.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/middleware/zlib/inflate.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/middleware/zlib/inftrees.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/middleware/zlib/uncompr.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/middleware/zlib/zutil.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/middleware/png/png.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/middleware/png/pngget.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/middleware/png/pngmem.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/middleware/png/pngread.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/middleware/png/pngrio.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/middleware/png/pngrtran.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/middleware/png/pngrutil.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/middleware/png/pngset.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/middleware/png/pngtrans.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/middleware/png/readpng.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/msapi_bmp_decoder.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/msapi_gif_decoder.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/msapi_png_decoder.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/msapi_stillimage_bm.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/msapi_stillimage_dataio_file.o CC [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/msapi_stillimage_dlmalloc.o /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/vendor/mediatek/tv/misdk/stbmsapi/gif/msapi_gif_decoder.c:388:9: warning: mixing declarations and code is a C99 extension [-Wdeclaration-after-statement] U8* ret = NULL; ^ /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/vendor/mediatek/tv/misdk/stbmsapi/gif/msapi_gif_decoder.c:1195:25: warning: mixing declarations and code is a C99 extension [-Wdeclaration-after-statement] U16 u16bgColor = RGB8888_TO_1555(((pstGIFInfo[u32ObjNum]->gif89.transparent != - 1) ? 0 : 1), ^ /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/vendor/mediatek/tv/misdk/stbmsapi/gif/msapi_gif_decoder.c:1230:29: warning: mixing declarations and code is a C99 extension [-Wdeclaration-after-statement] S32 rowstride_prev_prev_frame = 0; ^ /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/vendor/mediatek/tv/misdk/stbmsapi/gif/msapi_gif_decoder.c:1163:24: warning: mixing declarations and code is a C99 extension [-Wdeclaration-after-statement] GIF_FRAME* prev_frame; ^ /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/vendor/mediatek/tv/misdk/stbmsapi/gif/msapi_gif_decoder.c:1450:9: warning: mixing declarations and code is a C99 extension [-Wdeclaration-after-statement] S32 i; ^ /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/vendor/mediatek/tv/misdk/stbmsapi/gif/middleware/png/pngrutil.c:1825:10: warning: misleading indentation; statement is not part of the previous 'else' [-Wmisleading-indentation] Dapi_png_ptr->iwidth = (Dapi_png_ptr->width + Dapi_png_pass_inc[Dapi_png_ptr->pass] - 1 - Dapi_png_pass_start[Dapi_png_ptr->pass]) / ^ /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/vendor/mediatek/tv/misdk/stbmsapi/gif/middleware/png/pngrutil.c:1822:7: note: previous statement is here else ^ /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/vendor/mediatek/tv/misdk/stbmsapi/gif/msapi_gif_decoder.c:2252:10: warning: mixing declarations and code is a C99 extension [-Wdeclaration-after-statement] BOOL bPhase2; ^ /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/vendor/mediatek/tv/misdk/stbmsapi/gif/msapi_png_decoder.c:658:9: warning: mixing declarations and code is a C99 extension [-Wdeclaration-after-statement] U32 u32Remainder, u32Copied = 0;; ^ 1 warning generated. 1 warning generated. 6 warnings generated. LD [M] /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/mwgifker.o MODPOST /home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/Module.symvers FATAL: modpost: parse error in symbol dump file make[2]: *** [/home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/obj/KERNEL_MODULES/mwgifker.ko_intermediates/BUILT/Module.symvers] Error 1 make[1]: *** [modules] Error 2 make[1]: Leaving directory `/home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/out/target/product/khandala/KERNEL_OBJ_5.15' make: *** [__sub-make] Error 2 make: Leaving directory `/home/zhouzheng/MT9629_r2u_002/mtk_rls_ref5/vendor/mediatek/tv/kernel/5.15_14'
07-04
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大江东去浪淘尽千古风流人物

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值