Jeston agx orin GMSL 相机无流时,VI通道复位导致内核奔溃

在调试GMSL相机时,使用gst拉取视频流时,当vi通道没有视频流数据时,vi道通会超时复位,出现内核奔溃死机。

修改相机平台驱动,解决此种内核奔溃现象。参考官方补丁修改。

commit 29f211921e128ee01b24f75c37abdf8ba0010240
Author: edgar <edgar_xia@aliyun.com>
Date:   Mon Apr 28 10:46:14 2025 +0800

    修改相机平台驱动:解决当无视频流时,vi通道复位死机现象

diff --git a/kernel/nvidia/drivers/media/platform/tegra/camera/csi/csi.c b/kernel/nvidia/drivers/media/platform/tegra/camera/csi/csi.c
index d788f7041..2353c1ce0 100644
--- a/kernel/nvidia/drivers/media/platform/tegra/camera/csi/csi.c
+++ b/kernel/nvidia/drivers/media/platform/tegra/camera/csi/csi.c
@@ -229,6 +229,7 @@ static int tegra_csi_s_power(struct v4l2_subdev *subdev, int enable)
        return err;
 }
 
+#if(0)
 static int tegra_csi_sync_event(struct v4l2_subdev *subdev,
        unsigned int sync_events)
 {
@@ -242,7 +243,7 @@ static int tegra_csi_sync_event(struct v4l2_subdev *subdev,
 
        return err;
 }
-
+#endif
 /*
  * -----------------------------------------------------------------------------
  * CSI Subdevice Video Operations
@@ -738,7 +739,7 @@ static struct v4l2_subdev_pad_ops tegra_csi_pad_ops = {
 
 static struct v4l2_subdev_core_ops tegra_csi_core_ops = {
        .s_power        = tegra_csi_s_power,
-       .sync           = tegra_csi_sync_event,
+       //.sync         = tegra_csi_sync_event,
 };
 
 static struct v4l2_subdev_ops tegra_csi_ops = {
diff --git a/kernel/nvidia/drivers/media/platform/tegra/camera/vi/vi5_fops.c b/kernel/nvidia/drivers/media/platform/tegra/camera/vi/vi5_fops.c
index 8404249f9..957089a6c 100644
--- a/kernel/nvidia/drivers/media/platform/tegra/camera/vi/vi5_fops.c
+++ b/kernel/nvidia/drivers/media/platform/tegra/camera/vi/vi5_fops.c
@@ -324,6 +324,9 @@ static int tegra_channel_capture_setup(struct tegra_channel *chan, unsigned int
        chan->request[vi_port] = dma_alloc_coherent(chan->tegra_vi_channel[vi_port]->rtcpu_dev,
                                        setup.queue_depth * setup.request_size,
                                        &setup.iova, GFP_KERNEL);
+       
+       chan->request_iova[vi_port] = setup.iova;
+
        if (chan->request[vi_port] == NULL) {
                dev_err(chan->vi->dev, "dma_alloc_coherent failed\n");
                return -ENOMEM;
@@ -740,7 +743,16 @@ static int vi5_channel_error_recover(struct tegra_channel *chan,
 
        /* stop vi channel */
        for (vi_port = 0; vi_port < chan->valid_ports; vi_port++) {
-               filp_close(chan->fp[vi_port], NULL);
+               //filp_close(chan->fp[vi_port], NULL);
+               err = vi_capture_release(chan->tegra_vi_channel[vi_port],
+                       CAPTURE_CHANNEL_RESET_FLAG_IMMEDIATE);
+               if(err) {
+                       dev_err(&chan->video->dev, "vi capture release failed\n");
+                       goto done;
+               }
+               vi_channel_close_ex(chan->vi_channel_id[vi_port],
+                               chan->tegra_vi_channel[vi_port]);
+
                chan->tegra_vi_channel[vi_port] = NULL;
                kfree(chan->tegra_vi_channel[vi_port]);
        }
@@ -772,10 +784,10 @@ static int vi5_channel_error_recover(struct tegra_channel *chan,
                err = -1;
                goto done;
        }
-
+#if(0)
        v4l2_subdev_call(csi_subdev, core, sync,
                V4L2_SYNC_EVENT_SUBDEV_ERROR_RECOVER);
-
+#endif
        /* restart vi channel */
        for (vi_port = 0; vi_port < chan->valid_ports; vi_port++) {
                err = vi5_channel_open(chan, vi_port);
@@ -1078,7 +1090,9 @@ err_set_stream:
 err_setup:
        if (!chan->bypass)
                for (vi_port = 0; vi_port < chan->valid_ports; vi_port++) {
-                       filp_close(chan->fp[vi_port], NULL);
+                       //filp_close(chan->fp[vi_port], NULL);
+                       vi_channel_close_ex(chan->vi_channel_id[vi_port],
+                                       chan->tegra_vi_channel[vi_port]);
                        chan->tegra_vi_channel[vi_port] = NULL;
                }
 
@@ -1093,6 +1107,8 @@ static int vi5_channel_stop_streaming(struct vb2_queue *vq)
 {
        struct tegra_channel *chan = vb2_get_drv_priv(vq);
        int vi_port = 0;
+       int err;
+
        if (!chan->bypass)
                vi5_channel_stop_kthreads(chan);
 
@@ -1101,7 +1117,35 @@ static int vi5_channel_stop_streaming(struct vb2_queue *vq)
 
        if (!chan->bypass) {
                for (vi_port = 0; vi_port < chan->valid_ports; vi_port++) {
-                       filp_close(chan->fp[vi_port], NULL);
+                       //filp_close(chan->fp[vi_port], NULL);
+                       err = vi_capture_release(chan->tegra_vi_channel[vi_port],
+                               CAPTURE_CHANNEL_RESET_FLAG_IMMEDIATE);
+
+                       if(err)
+                               dev_err(&chan->video->dev, "vi capture release failed\n");
+                       
+                       /* Release capture requests */
+                       if(chan->request[vi_port] != NULL) {
+                               dma_free_coherent(chan->tegra_vi_channel[vi_port]->rtcpu_dev,
+                               chan->capture_queue_depth * sizeof(struct capture_descriptor),
+                               chan->request[vi_port], chan->request_iova[vi_port]);
+                       }
+                       chan->request[vi_port] = NULL;
+
+                       /* Release emd data buffers */
+                       if(chan->emb_buf_size > 0) {
+                               struct device *vi_unit_dev;
+
+                               vi5_unit_get_device_handle(chan->vi->ndev, chan->port[0],
+                                       &vi_unit_dev);
+                               dma_free_coherent(vi_unit_dev, chan->emb_buf_size,
+                                       chan->emb_buf_addr, chan->emb_buf);
+                               chan->emb_buf_size = 0;
+                       }
+
+                       vi_channel_close_ex(chan->vi_channel_id[vi_port],
+                               chan->tegra_vi_channel[vi_port]);
+
                        chan->tegra_vi_channel[vi_port] = NULL;
                        kfree(chan->tegra_vi_channel[vi_port]);
                }
diff --git a/kernel/nvidia/include/media/mc_common.h b/kernel/nvidia/include/media/mc_common.h
index 3b8ad289c..b2143d0d4 100644
--- a/kernel/nvidia/include/media/mc_common.h
+++ b/kernel/nvidia/include/media/mc_common.h
@@ -276,6 +276,8 @@ struct tegra_channel {
        struct nvcsi_deskew_context *deskew_ctx;
        struct tegra_vi_channel *tegra_vi_channel[TEGRA_CSI_BLOCKS];
        struct capture_descriptor *request[TEGRA_CSI_BLOCKS];
+       dma_addr_t request_iova[TEGRA_CSI_BLOCKS];
+       
        bool is_slvsec;
        int is_interlaced;
        enum interlaced_type interlace_type;
### 安装 VSCode 和 Anaconda 的方法 #### 一、安装 Anaconda 为了在 Jetson AGX Orin 平台上成功安装并运行 Anaconda,可以按照以下说明操作: 1. **访问下载页面** 访问清华大学开源软件镜像站或其他官方资源站点,找到适用于 aarch64 架构的 Anaconda 版本文件链接[^3]。 2. **下载 Anaconda 安装包** 使用 `wget` 命令下载适合 ARM64 或 AARCH64 架构的安装脚本。例如: ```bash wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-YYYY.MM-pyXX_aarch64.sh ``` 3. **执行安装脚本** 下载完成后,在终端中通过以下命令启动安装程序: ```bash bash Anaconda3-XXXX.XX-Linux-aarch64.sh ``` 按照提示逐步完成安装过程,期间可能需要多次输入 `yes` 并确认路径设置[^1]。 4. **初始化 Conda 环境** 安装结束后,激活 conda 初始化功能: ```bash source ~/.bashrc ``` 5. **验证安装状态** 输入以下命令检查是否正常工作: ```bash conda --version ``` --- #### 二、安装 Visual Studio Code (VSCode) 1. **获取 VSCode 预编译版本** 对于 Jetson AGX Orin 设备,由于其基于 Linux for Tegra (L4T),需特别选择支持 ARM64 的预构建版本。可以从 Microsoft 提供的 Debian 软件包地址下载对应版本: ```bash wget https://update.code.visualstudio.com/latest/linux-deb-armhf/stable -O code_arm64.deb ``` 2. **安装 .deb 文件** 利用 dpkg 工具来安装已下载的 `.deb` 包: ```bash sudo dpkg -i code_arm64.deb ``` 3. **解决依赖关系冲突(如有必要)** 如果遇到未满足的依赖项,则可以通过 apt-get 进行修复: ```bash sudo apt-get install -f ``` 4. **启动 VSCode 应用程序** 执行如下指令打开编辑器界面: ```bash code ``` --- #### 三、集成 VSCode 和 Anaconda 为了让 VSCode 支持 Python 开发以及调用由 Anaconda 创建的虚拟环境,还需额外配置插件和路径映射。 1. **安装 Python 插件扩展** 启动 VSCode 后转至左侧边栏中的 Extensions 图标,搜索 “Python”,点击 Install 加入到当前实例里。 2. **指定解释器位置** 在顶部菜单依次选取 File -> Preferences -> Settings ,或者直接按下快捷键 Ctrl+, 。接着查找 interpreter 设置选项卡,并手动切换成之前定义好的某个特定 anaconda envs 子目录下的可执行文件路径,比如 `/home/user_name/.conda/envs/myenv/bin/python`. 3. **测试连接有效性** 新建一个简单的 test.py 测试脚本内容如下所示: ```python import sys print(f"Using Python version {sys.version}") ``` 右击该文档区域选择 Run Python File In Terminal 查看输出结果是否匹配预期目标版本号。 --- ### 注意事项 - 若计划进一步部署深度学习框架 PyTorch 至此平台之上,请参照先前提及的相关资料完成 CUDA/CuDNN/TensorRT 组件适配流程后再继续推进其余环节[^4]。 - 推荐定期更新基础系统组件以保持兼容性和安全性补丁最新水平。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值