?C_XBP解析

前些时候在研究uc/os-II在keil c中移植的时候,对C_XBP指针的使用方式总是不太清楚,只模糊感觉到其是指向当前任务的栈空间顶部的,但引起初始化的时候是指向RAM空间的最顶端加1的位置,这就让我迷糊了。我不知道C_XBP一开始指向那个位置有什么用处,也不清楚何时C_XBP开始指向当前任务的栈空间顶部的。因此花了一些时间去研究其初始化到OS运行的过程中C_XBP的变化。

首先在startup.a51中找到如下语句:
IF XBPSTACK <> 0
EXTRN DATA (?C_XBP)
                MOV     ?C_XBP,#HIGH XBPSTACKTOP
                MOV     ?C_XBP+1,#LOW XBPSTACKTOP
ENDIF
从前面的定义知道XBPSTACK定义为1,因此此处将首先对C_XBP进行赋值。因C_XBP定义为两字节的专用指针,因此在汇编中需要对C_XBP+1也赋值(因为在C编程中看来,地址为C_XBP+1的RAM其实是指针C_XBP的一部分,保存此指针的低8位)。从前面定义的XBPSTACKTOP可以知道,此处执行完后,{C_XBP}=0x80,{C_XBP+1}=0x00,即在C编程中看来,此时指针C_XBP是指向存储地址为0x8000的地方。初始化完成后进入main()函数。

然后来跟踪分析main()函数的执行情况。进入main()函数后,真正开始OS的语句是OSInit(),因此进入查看此函数的执行过程。在OSInit()函数中可以看到,前面都部分全部都是对任务控制块TCB等全局变量的初始化,并没有牵涉到指针C_XBP。在此初始化后,OSInit()函数会创建两个任务(一个是空闲任务,一个是统计任务,当然此处假设其使能是打开的),因此需要进去OSTaskCreate()函数中去查找了,在此函数中看到了OSSched(),哦耶,立马就清楚了。因为在以前的学习中知道,正是在OSSched()函数中调用宏定义OS_TASK_SW()(其实就是通过此宏定义来调用OSCtxSw(),此函数是移植中最重点的函数)来进行任务切换的,而对C_XBP的操作也是此初最先开始的。通过分析可知,在第一次进行任务切换时,OS首先将公共堆栈里的内容(从#stack到sp之间的内容)拷贝到C_XBP指针指向的地址下面的RAM空间,即此处相当于将公共堆栈里的内容拷贝到RAM空间的最高地址部分空间内(因为到目前为止C_XBP指针仍然是初始化时候的值,这其实是考虑到此处的RAM空间是最不可能被用到的,因此保存在此处比较安全,当然也是有被破坏的可能的),接着将C_XBP指向刚保存的数据的RAM底端位置。然后调用C_OSCtxSw()函数进入C编程环境中进行操作。

进入C_OSCtxSw()函数后首先执行的就是将C_XBP指针的值赋给OSTCBCur->OSTCBStkPtr。但从初始化过程来看,此处可能会存在问题,因为此时OSTCBCur指针指向的是0地址,即相当于是空指针,同样OSTCBStkPtr指针指向的也是0地址,我不知道此时给空指针赋值是什么用意,但我觉得稳妥的做法是应该在此处判断一下指针是否为空再进行赋值。另外一点疑惑就是,既然将C_XBP指针赋值给空指针,即代表其值将永远丢失,那为什么还要在前面保存相应的数值,那些可是永远也不会用到了啊(当然其实创建任务后确实也不需要再用到了)。

接下来就是将OSTCBCur指针指向最高优先级任务的任务控制块,同时C_XBP指针指向当前任务的堆栈顶端,然后就是调用LoadCtx()切换到当前任务中执行去了。在以后的任务切换过程中,C_XBP指针将始终指向当前任务的堆栈顶端。

至此,C_XBP指针的使用过程全部弄清楚了。这个过程虽然有点枯燥,但当缠在一起的结被解开的瞬间,感觉还是非常HIGH的,呵呵。


开始云台控制 接口功能 对设备进行开始云台控制,开始云台控制之后必须先调用停止云台控制接口才能进行其他操作,包括其他方向的云台转动 请求地址 https://open.ys7.com/api/lapp/device/ptz/start 请求方式 POST 子账户token请求所需最小权限 "Permission":"Ptz" "Resource":"Cam:序列号:通道号" 请求参数 参数名 类型 描述 是否必选 accessToken String 授权过程获取的access_token Y deviceSerial String 设备序列号,存在英文字母的设备序列号,字母需为大写 Y channelNo int 通道号 Y direction int 操作命令:0-上,1-下,2-左,3-右,4-左上,5-左下,6-右上,7-右下,8-物理放大,9-物理缩小,10-调整近焦距,11-调整远焦距,16-自动控制 Y speed int 云台速度:0-慢,1-适中,2-快,海康设备参数不可为0 Y HTTP请求报文 POST /api/lapp/device/ptz/start HTTP/1.1 Host: open.ys7.com Content-Type: application/x-www-form-urlencoded accessToken=at.4g01l53x0w22xbp30ov33q44app1ns9m&deviceSerial=502608888&channelNo=1&direction=2&speed=1 返回数据 { "code": "200", "msg": "操作成功!" } 返回码 返回码 返回消息 描述 200 操作成功 请求成功 10001 参数错误 参数为空或格式不正确 10002 accessToken异常或过期 重新获取accessToken 10005 appKey异常 appKey被冻结 20002 设备不存在 20006 网络异常 检查设备网络状况,稍后再试 20007 设备不在线 检查设备是否在线 20008 设备响应超时 操作过于频繁,稍后再试 20014 deviceSerial不合法 20032 该用户下通道不存在 该用户下通道不存在 49999 数据异常 接口调用异常 60000 设备不支持云台控制 60001 用户无云台控制权限 60002 设备云台旋转达到上限位 60003 设备云台旋转达到下限位 60004 设备云台旋转达到左限位 60005 设备云台旋转达到右限位 60006 云台当前操作失败 稍候再试 60009 正在调用预置点 60020 不支持该命令 确认设备是否支持该操作 停止云台控制 接口功能 设备停止云台控制 请求地址 https://open.ys7.com/api/lapp/device/ptz/stop 请求方式 POST 子账户token请求所需最小权限 "Permission":"Ptz" "Resource":"Cam:序列号:通道号" 请求参数 参数名 类型 描述 是否必选 accessToken String 授权过程获取的access_token Y deviceSerial String 设备序列号,存在英文字母的设备序列号,字母需为大写 Y channelNo int 通道号 Y direction int 操作命令:0-上,1-下,2-左,3-右,4-左上,5-左下,6-右上,7-右下,8-放大,9-缩小,10-近焦距,11-远焦距,16-自动控制 N 提示:建议停止云台接口带方向参数。 HTTP请求报文 POST /api/lapp/device/ptz/stop HTTP/1.1 Host: open.ys7.com Content-Type: application/x-www-form-urlencoded accessToken=at.25ne3gkr6fa7coh34ys0fl1h9hryc2kr&deviceSerial=568261888&channelNo=1&direction=1 返回数据 { "code": "200", "msg": "操作成功!" } 返回码 返回码 返回消息 描述 200 操作成功 请求成功 10001 参数错误 参数为空或格式不正确 10002 accessToken异常或过期 重新获取accessToken 10005 appKey异常 appKey被冻结 20002 设备不存在 20006 网络异常 检查设备网络状况,稍后再试 20007 设备不在线 检查设备是否在线 20008 设备响应超时 操作过于频繁,稍后再试 20014 deviceSerial不合法 20032 该用户下通道不存在 该用户下通道不存在 49999 数据异常 接口调用异常 60000 设备不支持云台控制 60001 用户无云台控制权限 60006 云台当前操作失败 稍候再试 60009 正在调用预置点 60020 不支持该命令 确认设备是否支持该操作 MainActivity.java:package com.videogo.ui.login; import android.content.res.Configuration; import android.content.pm.ActivityInfo; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import com.videogo.exception.BaseException; import com.videogo.exception.ErrorCode; import com.videogo.openapi.EZConstants; import com.videogo.openapi.EZOpenSDK; import com.videogo.openapi.EZPlayer; import ezviz.ezopensdk.R; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.LinearLayout; import android.widget.ImageButton; import android.widget.Toast; import android.view.MotionEvent; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, Handler.Callback { private static final String TAG = "EZPreview"; private static final int MSG_VIDEO_SIZE_CHANGED = 1; private static final int MSG_REALPLAY_PLAY_SUCCESS = 2001; private static final int MSG_REALPLAY_PLAY_FAIL = 2002; private static final int MSG_SHOW_STREAM_TYPE = 3001; // 新增消息类型 private static final int DIRECTION_UP = 0; private static final int DIRECTION_DOWN = 1; private static final int DIRECTION_LEFT = 2; private static final int DIRECTION_RIGHT = 3; private static final int DIRECTION_ZOOM_IN = 8; // 物理放大 private static final int DIRECTION_ZOOM_OUT = 9; // 物理缩小 private static final int SPEED_MEDIUM = 1; // 速度适中 private static final String PTZ_START_URL = "https://open.ys7.com/api/lapp/device/ptz/start"; private static final String PTZ_STOP_URL = "https://open.ys7.com/api/lapp/device/ptz/stop"; private boolean mIsSupportPTZ = false; // 设备是否支持云台 private ExecutorService mExecutorService; // 线程池 // 接收的参数键 private static final String KEY_APPKEY = "appkey"; private static final String KEY_SERIAL = "serial"; private static final String KEY_VERIFYCODE = "VerifyCode"; private static final String KEY_ACCESSTOKEN = "accessToken"; private static final String KEY_CAMERANO = "cameraNo"; private boolean mIsPlaying = false; private EZPlayer mEZPlayer; private SurfaceView mSurfaceView; private SurfaceHolder mSurfaceHolder; private ProgressBar mLiveProgressBar; private RelativeLayout mRlControl; private LinearLayout mLlHc; private ImageButton mIbRotate2; // 从Intent中获取的参数 private String mAppKey; private String mDeviceSerial; private String mVerifyCode; private String mAccessToken; private int mCameraNo = 0; // 默认通道号0 private Handler mHandler; private boolean mP2PEnabled = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activitymain); mHandler = new Handler(this); // 1. 从Intent中获取参数 extractParametersFromIntent(); // 2. 初始化UI initUI(); initOrientationSensitiveViews(); View fanHui = findViewById(R.id.back); fanHui.setOnClickListener(v -> finish()); // 3. 初始化SDK并创建播放器 initSDKAndCreatePlayer(); } private void initOrientationSensitiveViews() { mLiveProgressBar = findViewById(R.id.liveProgressBar); mRlControl = findViewById(R.id.rl_control); mLlHc = findViewById(R.id.ll_hc); mIbRotate2 = findViewById(R.id.ib_rotate2); // 初始状态显示加载 if (mLiveProgressBar != null) { mLiveProgressBar.setVisibility(View.VISIBLE); } // 初始根据方向更新UI updateLayoutByOrientation(); // 创建线程池 mExecutorService = Executors.newFixedThreadPool(2); // 4. 初始化云台控制按钮 initPTZButtons(); } private void initPTZButtons() { // 竖屏布局的按钮 setupPTZButton(R.id.ptz_left_btn, DIRECTION_LEFT); setupPTZButton(R.id.ptz_right_btn, DIRECTION_RIGHT); setupPTZButton(R.id.ptz_top_btn, DIRECTION_UP); setupPTZButton(R.id.ptz_bottom_btn, DIRECTION_DOWN); setupPTZButton(R.id.zoom_add, DIRECTION_ZOOM_IN); // 物理放大 setupPTZButton(R.id.zoom_reduce, DIRECTION_ZOOM_OUT); // 物理缩小 // 横屏布局的按钮 setupPTZButton(R.id.ptz_left_btn2, DIRECTION_LEFT); setupPTZButton(R.id.ptz_right_btn2, DIRECTION_RIGHT); setupPTZButton(R.id.ptz_top_btn2, DIRECTION_UP); setupPTZButton(R.id.ptz_bottom_btn2, DIRECTION_DOWN); setupPTZButton(R.id.zoom_add2, DIRECTION_ZOOM_IN); setupPTZButton(R.id.zoom_reduce2, DIRECTION_ZOOM_OUT); } private void setupPTZButton(int buttonId, final int direction) { ImageButton button = findViewById(buttonId); if (button != null) { button.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (!mIsSupportPTZ) { Toast.makeText(MainActivity.this, "设备不支持云台控制", Toast.LENGTH_SHORT).show(); return true; } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // 按下时开始云台动作 controlPTZ(direction, SPEED_MEDIUM, true); return true; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: // 松开时停止云台动作 controlPTZ(direction, SPEED_MEDIUM, false); return true; } return false; } }); } } // 云台控制方法 private void controlPTZ(final int direction, final int speed, final boolean isStart) { mExecutorService.execute(new Runnable() { @Override public void run() { try { String urlStr = isStart ? PTZ_START_URL : PTZ_STOP_URL; URL url = new URL(urlStr); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.setDoOutput(true); // 构建POST数据 String postData = "accessToken=" + mAccessToken + "&deviceSerial=" + mDeviceSerial + "&channelNo=" + mCameraNo; if (isStart) { postData += "&direction=" + direction + "&speed=" + speed; } else { // 停止时带上方向参数(建议) postData += "&direction=" + direction; } // 发送请求 OutputStream os = conn.getOutputStream(); os.write(postData.getBytes("UTF-8")); os.flush(); os.close(); // 获取响应 int responseCode = conn.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { Log.d(TAG, "PTZ control successful: " + (isStart ? "Start" : "Stop") + " | Direction: " + direction); } else { Log.e(TAG, "PTZ control failed. Response code: " + responseCode); runOnUiThread(() -> Toast.makeText(MainActivity.this, "云台控制失败", Toast.LENGTH_SHORT).show()); } conn.disconnect(); } catch (Exception e) { Log.e(TAG, "PTZ control error", e); runOnUiThread(() -> Toast.makeText(MainActivity.this, "云台控制出错", Toast.LENGTH_SHORT).show()); } } }); } @Override public void onConfigurationChanged(@NonNull Configuration newConfig) { super.onConfigurationChanged(newConfig); // 方向变化时重新初始化视图 initOrientationSensitiveViews(); updateLayoutByOrientation(); } @Override protected void onResume() { super.onResume(); if (mLiveProgressBar != null) { if (mIsPlaying) { mLiveProgressBar.setVisibility(View.GONE); } else { mLiveProgressBar.setVisibility(View.VISIBLE); } } } private void updateLayoutByOrientation() { int orientation = getResources().getConfiguration().orientation; if (orientation == Configuration.ORIENTATION_PORTRAIT) { // 竖屏模式 mRlControl.setVisibility(View.VISIBLE); mLlHc.setVisibility(View.GONE); mIbRotate2.setVisibility(View.GONE); } else { // 横屏模式 mRlControl.setVisibility(View.GONE); mLlHc.setVisibility(View.VISIBLE); mIbRotate2.setVisibility(View.VISIBLE); } } /** * 从Intent中提取传递的参数 */ private void extractParametersFromIntent() { Bundle extras = getIntent().getExtras(); if (extras != null) { mAppKey = extras.getString(KEY_APPKEY, ""); mDeviceSerial = extras.getString(KEY_SERIAL, ""); mVerifyCode = extras.getString(KEY_VERIFYCODE, ""); mAccessToken = extras.getString(KEY_ACCESSTOKEN, ""); mCameraNo = extras.getInt(KEY_CAMERANO, 0); Log.d(TAG, "Received parameters:"); Log.d(TAG, "AppKey: " + mAppKey); Log.d(TAG, "DeviceSerial: " + mDeviceSerial); Log.d(TAG, "VerifyCode: " + mVerifyCode); Log.d(TAG, "AccessToken: " + mAccessToken); Log.d(TAG, "CameraNo: " + mCameraNo); } else { Log.e(TAG, "No parameters received from intent"); // 如果没有参数,可以显示错误信息并退出 finish(); } } /** * 初始化UI组件 */ private void initUI() { mSurfaceView = findViewById(R.id.realplay_sv); if (mSurfaceView != null) { mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.addCallback(this); } else { Log.e(TAG, "SurfaceView not found with ID realplay_sv"); } } /** * 初始化SDK并创建播放器 */ private void initSDKAndCreatePlayer() { try { // 1. 初始化SDK EZOpenSDK.initLib(getApplication(), mAppKey); EZOpenSDK.getInstance().setAccessToken(mAccessToken); // +++ 开启P2P取流方式 +++ EZOpenSDK.enableP2P(true); // 开启P2P取流 Log.d(TAG, "P2P取流已启用"); mP2PEnabled = true; // 2. 创建播放器 createPlayer(); } catch (Exception e) { Log.e(TAG, "SDK初始化失败", e); Toast.makeText(this, "SDK初始化失败", Toast.LENGTH_SHORT).show(); } } /** * 创建播放器并开始播放 */ private void createPlayer() { try { // 1. 创建播放器实例 mEZPlayer = EZOpenSDK.getInstance().createPlayer(mDeviceSerial, mCameraNo); // 2. 配置播放器 mEZPlayer.setHandler(mHandler); if (mSurfaceHolder != null) { mEZPlayer.setSurfaceHold(mSurfaceHolder); } if (mVerifyCode != null && !mVerifyCode.isEmpty()) { mEZPlayer.setPlayVerifyCode(mVerifyCode); } // 3. 开始播放 mEZPlayer.startRealPlay(); mIsPlaying = true; // 标记为正在播放 } catch (Exception e) { Log.e(TAG, "Player creation failed", e); mIsPlaying = false; // 标记为未播放 } } // 处理屏幕旋转按钮点击 public void changeScreen(View view) { Log.d(TAG, "Change screen orientation requested"); int currentOrientation = getResources().getConfiguration().orientation; if (currentOrientation == Configuration.ORIENTATION_PORTRAIT) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } else { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } // 更新UI布局 updateLayoutByOrientation(); } // Surface回调接口实现 @Override public void surfaceCreated(@NonNull SurfaceHolder holder) { if (mEZPlayer != null) { mEZPlayer.setSurfaceHold(holder); } } @Override public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {} @Override public void surfaceDestroyed(@NonNull SurfaceHolder holder) { if (mEZPlayer != null) { mEZPlayer.setSurfaceHold(null); } } @Override protected void onStop() { super.onStop(); if (mEZPlayer != null) { mEZPlayer.stopRealPlay(); mIsPlaying = false; // 标记为已停止 } } // Handler回调处理播放状态 @Override public boolean handleMessage(@NonNull Message msg) { Log.d(TAG, "handleMessage: " + msg.what); switch (msg.what) { case MSG_VIDEO_SIZE_CHANGED: break; case MSG_REALPLAY_PLAY_SUCCESS: Log.i(TAG, "播放成功"); mIsPlaying = true; // 获取并显示取流方式 int streamType = mEZPlayer.getStreamFetchType(); String streamTypeName = getStreamTypeName(streamType); Log.d(TAG, "当前取流方式: " + streamTypeName); // 发送消息显示取流方式 Message showMsg = new Message(); showMsg.what = MSG_SHOW_STREAM_TYPE; showMsg.obj = streamTypeName; mHandler.sendMessage(showMsg); runOnUiThread(() -> { if (mLiveProgressBar != null) { mLiveProgressBar.setVisibility(View.GONE); } }); // 在播放成功后检查设备是否支持云台 checkDevicePTZSupport(); break; case MSG_REALPLAY_PLAY_FAIL: Log.e(TAG, "播放失败"); mIsPlaying = false; runOnUiThread(() -> { if (mLiveProgressBar != null) { mLiveProgressBar.setVisibility(View.VISIBLE); } }); BaseException error = (BaseException) msg.obj; int errorCode = error.getErrorCode(); if (errorCode == ErrorCode.ERROR_INNER_VERIFYCODE_NEED || errorCode == ErrorCode.ERROR_INNER_VERIFYCODE_ERROR) { mVerifyCode = "123456"; if (mEZPlayer != null) { mEZPlayer.setPlayVerifyCode(mVerifyCode); mEZPlayer.startRealPlay(); } } else { Log.e(TAG, "播放失败,错误码: " + errorCode); } break; case MSG_SHOW_STREAM_TYPE: String type = (String) msg.obj; Toast.makeText(MainActivity.this, "取流方式: " + type + (mP2PEnabled ? " (P2P已启用)" : ""), Toast.LENGTH_LONG).show(); break; } return true; } private void checkDevicePTZSupport() { new Thread(() -> { try { // 这里使用SDK方法检查设备能力 // 如果SDK没有提供方法,可以使用HTTP API查询设备能力 // 简化处理:假设所有设备都支持云台 mIsSupportPTZ = true; // 实际项目中应该查询设备能力 // mIsSupportPTZ = queryDevicePTZCapability(); } catch (Exception e) { Log.e(TAG, "Failed to check PTZ support", e); } }).start(); } @Override protected void onDestroy() { super.onDestroy(); if (mExecutorService != null) { mExecutorService.shutdown(); } // +++移除Handler回调避免内存泄漏 +++ if (mHandler != null) { mHandler.removeCallbacksAndMessages(null); } if (mEZPlayer != null) { mEZPlayer.release(); mEZPlayer = null; } } private String getStreamTypeName(int type) { switch (type) { case 0: return "流媒体"; case 1: return "P2P"; case 2: return "内网直连"; case 4: return "云存储"; default: return "未知(" + type + ")"; } } } activitymain:<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#fff2f2f2" tools:context="com.videogo.ui.login.MainActivity"> <RelativeLayout android:id="@+id/ra_title" android:layout_width="match_parent" android:layout_height="44dp" android:background="@mipmap/title_bg"> <TextView android:id="@+id/titlename" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_gravity="center" android:text="易丰视频监控" android:textColor="@android:color/white" android:textSize="18sp" /> <ImageButton android:id="@+id/back" android:layout_width="40dp" android:layout_height="match_parent" android:background="@null" android:contentDescription="@null" android:paddingLeft="10dp" android:src="@mipmap/img_back" /> <Button android:id="@+id/huifang" android:layout_width="50dp" android:layout_height="match_parent" android:layout_alignParentRight="true" android:layout_marginRight="65dp" android:background="@drawable/gps_select" android:contentDescription="@null" android:scaleType="centerInside" android:src="@mipmap/ic_size_sel" android:text="回放" android:textColor="@color/white" android:textSize="18sp" /> <ImageButton android:id="@+id/ib_rotate" android:layout_width="50dp" android:layout_height="match_parent" android:layout_alignParentRight="true" android:layout_marginRight="6dp" android:background="@drawable/gps_select" android:contentDescription="@null" android:onClick="changeScreen" android:scaleType="centerInside" android:src="@mipmap/ic_size_sel" /> </RelativeLayout> <RelativeLayout android:id="@+id/rl_control" android:layout_width="match_parent" android:layout_height="266dp" android:layout_alignParentBottom="true" android:visibility="visible"> <LinearLayout android:id="@+id/ll_center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_centerHorizontal="true" android:background="@mipmap/ycjk_yp" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/ycjk_kb1" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/ycjk_kb2" /> <ImageButton android:id="@+id/left_up" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:visibility="gone" /> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/ycjk_kb3" /> </LinearLayout> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/ycjk_kb4" /> </LinearLayout> <ImageButton android:id="@+id/ptz_top_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/nnew_video_up" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/ycjk_kb1" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/ycjk_kb3" /> <ImageButton android:id="@+id/right_up" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:visibility="gone" /> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/ycjk_kb2" /> </LinearLayout> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/ycjk_kb4" /> </LinearLayout> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent"> <ImageButton android:id="@+id/ptz_left_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/nnew_video_left" /> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/ycjk_zj" /> <ImageButton android:id="@+id/ptz_right_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/nnew_video_right" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/ycjk_kb4" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/ycjk_kb2" /> <ImageButton android:id="@+id/left_down" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:visibility="gone" /> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/ycjk_kb3" /> </LinearLayout> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/ycjk_kb1" /> </LinearLayout> <ImageButton android:id="@+id/ptz_bottom_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/nnew_video_down" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/ycjk_kb4" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/ycjk_kb3" /> <ImageButton android:id="@+id/right_down" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:visibility="gone" /> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/ycjk_kb2" /> </LinearLayout> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/ycjk_kb1" /> </LinearLayout> </LinearLayout> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_toLeftOf="@id/ll_center" android:gravity="center" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:orientation="vertical"> <ImageButton android:id="@+id/focus_add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/video_more1" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="焦距 +" android:textColor="@color/black" android:textSize="16dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:orientation="vertical"> <ImageButton android:id="@+id/guangquan_add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/video_more3" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="光圈 +" android:textColor="@color/black" android:textSize="16dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:orientation="vertical"> <ImageButton android:id="@+id/zoom_add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/video_more5" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="变倍 +" android:textColor="@color/black" android:textSize="16dp" /> </LinearLayout> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_toRightOf="@id/ll_center" android:gravity="center" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:orientation="vertical"> <ImageButton android:id="@+id/foucus_reduce" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/video_more2" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="焦距 -" android:textColor="@color/black" android:textSize="16dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:orientation="vertical"> <ImageButton android:id="@+id/guangquan_reduce" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/video_more4" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="光圈 -" android:textColor="@color/black" android:textSize="16dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center" android:orientation="vertical"> <ImageButton android:id="@+id/zoom_reduce" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/video_more6" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="变倍 -" android:textColor="@color/black" android:textSize="16dp" /> </LinearLayout> </LinearLayout> </RelativeLayout> <RelativeLayout android:layout_above="@id/rl_control" android:layout_below="@id/ra_title" android:layout_width="match_parent" android:layout_height="match_parent" > <SurfaceView android:id="@+id/realplay_sv" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/transparent" /> <ImageButton android:id="@+id/ib_rotate2" android:layout_width="40dp" android:layout_height="40dp" android:layout_alignParentLeft="true" android:layout_marginLeft="3dp" android:background="@color/green" android:contentDescription="@null" android:onClick="changeScreen" android:visibility="gone" android:src="@mipmap/img_systems_close" /> <ProgressBar android:id="@+id/liveProgressBar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:visibility="visible" /> <LinearLayout android:id="@+id/ll_hc" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:visibility="gone"> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:gravity="center" android:layout_weight="1" > <ImageButton android:id="@+id/ptz_top_btn2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/h_up" /> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:gravity="center" android:layout_weight="1" > <ImageButton android:id="@+id/ptz_bottom_btn2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/h_down" /> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:gravity="center" android:layout_weight="1" > <ImageButton android:id="@+id/ptz_left_btn2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/h_left" /> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:gravity="center" android:layout_weight="1" > <ImageButton android:id="@+id/ptz_right_btn2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/h_right" /> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:gravity="center" android:layout_weight="1" > <ImageButton android:id="@+id/focus_add2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/video_more1" /> </LinearLayout> <LinearLayout android:gravity="center" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" > <ImageButton android:id="@+id/foucus_reduce2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/video_more2" /> </LinearLayout> <LinearLayout android:gravity="center" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" > <ImageButton android:id="@+id/zoom_add2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/video_more5" /> </LinearLayout> <LinearLayout android:gravity="center" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" > <ImageButton android:id="@+id/zoom_reduce2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/video_more6" /> </LinearLayout> </LinearLayout> </RelativeLayout> </RelativeLayout> 不在代码中测试设备是否支持云台控制,严格按照上述开发文档的开始云台控制和停止云台控制,开始云台控制之后必须先调用停止云台控制接口才能进行其他操作,包括其他方向的云台转动。accessToken,deviceSerial,channelNo,direction,speed必须使用选择这5种参数来进行云台控制
06-25
说明以下C51启动文件的配置,是否正确配置了 LARGE模式下的模拟栈:$NOMOD51 ;------------------------------------------------------------------------------ ; This file is part of the C51 Compiler package ; Copyright (c) 1988-2005 Keil Elektronik GmbH and Keil Software, Inc. ; Version 8.01 ; ; *** <<< Use Configuration Wizard in Context Menu >>> *** ;------------------------------------------------------------------------------ ; STARTUP.A51: This code is executed after processor reset. ; ; To translate this file use A51 with the following invocation: ; ; A51 STARTUP.A51 ; ; To link the modified STARTUP.OBJ file to your application use the following ; Lx51 invocation: ; ; Lx51 your object file list, STARTUP.OBJ controls ; ;------------------------------------------------------------------------------ ; ; User-defined <h> Power-On Initialization of Memory ; ; With the following EQU statements the initialization of memory ; at processor reset can be defined: ; ; <o> IDATALEN: IDATA memory size <0x0-0x100> ; <i> Note: The absolute start-address of IDATA memory is always 0 ; <i> The IDATA space overlaps physically the DATA and BIT areas. IDATALEN EQU 80H ; ; <o> XDATASTART: XDATA memory start address <0x0-0xFFFF> ; <i> The absolute start address of XDATA memory XDATASTART EQU 0 ; ; <o> XDATALEN: XDATA memory size <0x0-0xFFFF> ; <i> The length of XDATA memory in bytes. XDATALEN EQU 0 ; ; <o> PDATASTART: PDATA memory start address <0x0-0xFFFF> ; <i> The absolute start address of PDATA memory PDATASTART EQU 0H ; ; <o> PDATALEN: PDATA memory size <0x0-0xFF> ; <i> The length of PDATA memory in bytes. PDATALEN EQU 0H ; ;</h> ;------------------------------------------------------------------------------ ; ;<h> Reentrant Stack Initialization ; ; The following EQU statements define the stack pointer for reentrant ; functions and initialized it: ; ; <h> Stack Space for reentrant functions in the SMALL model. ; <q> IBPSTACK: Enable SMALL model reentrant stack ; <i> Stack space for reentrant functions in the SMALL model. IBPSTACK EQU 0 ; set to 1 if small reentrant is used. ; <o> IBPSTACKTOP: End address of SMALL model stack <0x0-0xFF> ; <i> Set the top of the stack to the highest location. IBPSTACKTOP EQU 0xFF +1 ; default 0FFH+1 ; </h> ; ; <h> Stack Space for reentrant functions in the LARGE model. ; <q> XBPSTACK: Enable LARGE model reentrant stack ; <i> Stack space for reentrant functions in the LARGE model. XBPSTACK EQU 0 ; set to 1 if large reentrant is used. ; <o> XBPSTACKTOP: End address of LARGE model stack <0x0-0xFFFF> ; <i> Set the top of the stack to the highest location. XBPSTACKTOP EQU 0xFFFF +1 ; default 0FFFFH+1 ; </h> ; ; <h> Stack Space for reentrant functions in the COMPACT model. ; <q> PBPSTACK: Enable COMPACT model reentrant stack ; <i> Stack space for reentrant functions in the COMPACT model. PBPSTACK EQU 0 ; set to 1 if compact reentrant is used. ; ; <o> PBPSTACKTOP: End address of COMPACT model stack <0x0-0xFFFF> ; <i> Set the top of the stack to the highest location. PBPSTACKTOP EQU 0xFF +1 ; default 0FFH+1 ; </h> ;</h> ;------------------------------------------------------------------------------ ; ; Memory Page for Using the Compact Model with 64 KByte xdata RAM ; <e>Compact Model Page Definition ; ; <i>Define the XDATA page used for PDATA variables. ; <i>PPAGE must conform with the PPAGE set in the linker invocation. ; ; Enable pdata memory page initalization PPAGEENABLE EQU 0 ; set to 1 if pdata object are used. ; ; <o> PPAGE number <0x0-0xFF> ; <i> uppermost 256-byte address of the page used for PDATA variables. PPAGE EQU 0 ; ; <o> SFR address which supplies uppermost address byte <0x0-0xFF> ; <i> most 8051 variants use P2 as uppermost address byte PPAGE_SFR DATA 0A0H ; ; </e> ;------------------------------------------------------------------------------ ; Standard SFR Symbols ACC DATA 0E0H B DATA 0F0H SP DATA 81H DPL DATA 82H DPH DATA 83H NAME ?C_STARTUP ?C_C51STARTUP SEGMENT CODE ?STACK SEGMENT IDATA RSEG ?STACK DS 1 EXTRN CODE (?C_START) PUBLIC ?C_STARTUP CSEG AT 0 ?C_STARTUP: LJMP STARTUP1 RSEG ?C_C51STARTUP STARTUP1: IF IDATALEN <> 0 MOV R0,#IDATALEN - 1 CLR A IDATALOOP: MOV @R0,A DJNZ R0,IDATALOOP ENDIF IF XDATALEN <> 0 MOV DPTR,#XDATASTART MOV R7,#LOW (XDATALEN) IF (LOW (XDATALEN)) <> 0 MOV R6,#(HIGH (XDATALEN)) +1 ELSE MOV R6,#HIGH (XDATALEN) ENDIF CLR A XDATALOOP: MOVX @DPTR,A INC DPTR DJNZ R7,XDATALOOP DJNZ R6,XDATALOOP ENDIF IF PPAGEENABLE <> 0 MOV PPAGE_SFR,#PPAGE ENDIF IF PDATALEN <> 0 MOV R0,#LOW (PDATASTART) MOV R7,#LOW (PDATALEN) CLR A PDATALOOP: MOVX @R0,A INC R0 DJNZ R7,PDATALOOP ENDIF IF IBPSTACK <> 0 EXTRN DATA (?C_IBP) MOV ?C_IBP,#LOW IBPSTACKTOP ENDIF IF XBPSTACK <> 0 EXTRN DATA (?C_XBP) MOV ?C_XBP,#HIGH XBPSTACKTOP MOV ?C_XBP+1,#LOW XBPSTACKTOP ENDIF IF PBPSTACK <> 0 EXTRN DATA (?C_PBP) MOV ?C_PBP,#LOW PBPSTACKTOP ENDIF MOV SP,#?STACK-1 ; This code is required if you use L51_BANK.A51 with Banking Mode 4 ;<h> Code Banking ; <q> Select Bank 0 for L51_BANK.A51 Mode 4 #if 0 ; <i> Initialize bank mechanism to code bank 0 when using L51_BANK.A51 with Banking Mode 4. EXTRN CODE (?B_SWITCH0) CALL ?B_SWITCH0 ; init bank mechanism to code bank 0 #endif ;</h> LJMP ?C_START END
最新发布
08-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值