Запуск OpenIPC на камере Hikvision DS-2CD2345F-IS

OpenIPC

О том, как работать с этой камерой хоть и с рядом ограничений, но зато без сложных манипуляций, рассказано в статье Работа с камерой Hikvision DS-2CD2345F-IS без Ростелеком. Здесь же речь пойдёт про установку на имеющуюся аппаратную платформу альтернативной прошивки OpenIPC.

Это первая редакция статьи, написанная по результатам манипуляций с одной камерой. Как только попадёт в руки следующая — дополню картинками и исправлю неточности, если такие обнаружатся. В любом случае, если загрузчик жив, то всё поправимо.
Стабильная работа на данном этапе не гарантируется. Но, поскольку спрашивают, то выкладываю, как оно есть на текущем этапе — развлекайтесь!
По мере исправления багов и доработки, буду вносить в статью изменения.

Прошивка OpenIPC находится в статусе разработки и это нужно учитывать при работе с ней. Всё течёт, всё меняется и когда-то OpenIPC станет универсальным и стабильным продуктом, но пока это не так. Поэтому после сборки придётся немного доработать напильником.

Возможности

Первым делом стоит сказать о том, какие функции железа поддерживаются, а какие нет. Хотя, в данном случае, это не так уж и важно, потому что РТ-прошивка крайне ограничена, а родной прошивки производителя нет вовсе.

• Веб-интерфейс
• Протоколы: RTSP, ONVIF, JPEG, MJPEG
• Облако IP EYE (бесплатная трансляция, только H264)
• Троит переключение день/ночь
• Неподходящая для типа памяти NAND файловая система JFFS для раздела root_fs, в результате чего иногда происходят сбои при перезапуске. Ждём выхода новой сборки.
З.Ы. Сборка готова, приступаю к тестированию!
• Аудио
• Вход, выход
EPIC FAIL

При попытке прошить православный бут, он же u-boot-hi3516av100-universal.bin потерпел неудачу. Сам бут рабочий, но после прошивки камера умерла. Видимо, что-то пошло не так или ошибся с параметрами команд.
Есть ещё одна аналогичная камера… Браться за неё не хотел, пока не разберусь в чём был косяк и не починю окирпиченную, но статья написана, люди шьют, возникают вопросы… Так что придётся рискнуть.

Подготовка

Качаем с GitHub архив с образами ядра и файловой системы для имеющегося процессора. Тут есть один нюанс — вообще, в камере установлен процессор hi3516dv100, но собранный под него образ системы OpenIPC предназначен для работы с памятью SPI NOR, а здесь SPI NAND, поэтому берём образ для процессора hi3516av100, который не отличается ничем, кроме целевого типа памяти.

Для прошивки понадобится подключиться через UART, что соответственно, потребует адаптер USB-TTL, коннектор к нему и программу-терминал. Подробнее об этом в статье Работа с загрузчиком.

Загрузчик менять не надо. Просто изменим значение переменных окружения. Главное — не похерить загрузчик случайно. Об одном таком случае лично мне известно. Починить пока не получилось… Так что — аккуратнее!

  • Подключаем коннектор к камере и адаптеру.
  • Подключаем адаптер к компьютеру — появится виртуальный COM-порт. Исхожу из того, что драйверы уже установлены.
  • Запускаем терминал.
  • Подаём питание на камеру и, как только побежит лог загрузки, нажимаем комбинацию клавиш Ctrl+U для остановки запуска и попадания в загрузчик. Успели? Отлично! Нет? Пробуем ещё раз.

Прошивка

Переменные окружения

Первым делом нужно задать переменные окружения и обязательно сохранить внесённые изменения в постоянную память.

  • soc — процессор. Сердце всей системы: hi3516av100.
  • sensor — сенсор. Тот элемент, который оцифровывает изображение: ov4689.
  • totalmem — общее количество памяти: 128Мб.
  • osmem — количество памяти, используемое системой: 32Мб.
  • bootargs — параметры загрузки и разметка флешки.
  • bootcmd — командная строка загрузки.
  • ethaddr — MAC-адрес сетевого интерфейса.
  • ipaddr — IP-адрес сетевого интерфейса.
  • netmask — маска сети.
  • gateway — шлюз сети.
  • serverip — адрес TFTP-сервера.
  • saveenv — сохранить переменные окружения.
setenv soc hi3516av100
setenv sensor ov4689
setenv totalmem 128M

setenv osmem 32M

setenv bootargs 'mem=32M console=ttyAMA0,115200 panic=20 root=/dev/mtdblock3 rootfstype=squashfs init=/init mtdparts=hinand:1024k(boot),1024k(env),2048k(kernel),5120k(rootfs),-(rootfs_data)'

setenv bootcmd 'setenv setargs setenv bootargs ${bootargs}; run setargs; nand read 0x82000000 0x200000 0x200000; bootm 0x82000000'

setenv ethaddr 00:12:34:56:78:90    //задать MAC-адрес камеры, если не задан
setenv ipaddr 192.168.1.10          //задать IP-адрес камеры, если не задан
setenv serverip 192.168.1.2         //задать адрес компа с TFTP-сервером

saveenv

Образ ядра и файловой системы

Теперь нужно записать в постоянную память образы ядра и файловой системы. Алгоритм стандартный — очистить область оперативной памяти, загрузить в неё с TFTP-сервера бинарный файл, очистить область постоянной памяти и сохранить в неё из оперативки полученный блок данных. Подробнее об этом — в статье Работа с памятью в загрузчике. Повторяться не буду — приведу только сами команды. Последняя команда — перезапуск.

mw.b 0x82000000 0xff 0x1000000
tftp 0x82000000 uImage.${soc}
nand erase 0x200000 0x200000
nand write.i 0x82000000 0x200000 0x200000

mw.b 0x82000000 0xff 0x1000000
tftp 0x82000000 rootfs.squashfs.${soc}
nand erase 0x400000 0x500000
nand write 0x82000000 0x400000 0x500000

reset

Первый запуск

После того, как система загрузится, нужно войти в неё под именем root без пароля и выполнить команду firstboot. После завершения её выполнения дать команду на перезапуск: reboot.

После того, как система вновь запустится, нужно почистить область данных и снова перезапустить:

nand erase 0x900000 0x7700000
reboot

Эту же операцию нужно выполнить, если происходят сбои по вине неподходящей файловой системы. Но то же самое можно сделать и через веб-интерфейс. Об этом ниже.

Для того чтобы определить какой адрес получит камера, достаточно ввести в консоли команду ifconfig eth0.

Веб-интерфейс

Веб-интерфейс по умолчанию доступен по порту 85. Логин: admin, пароль: 12345. При первом входе будет предложено задать новый сложный пароль.

Сам использую англоязычный интерфейс, поэтому и все пункты меню буду приводить тоже на английском.

Основная часть системы — стример Majestic. Он выполняет функции захвата и трансляции изображения и делает всё остальное, что с этим связано. Надо настроить.

Пункт меню Majestic->Majestic settings

Основной поток

  • Включить Enable Video0
  • Выбрать Video0 codec: h265
  • Задать Video resolution: 1920×1080
  • Задать Video frame rate: 25
  • Задать Video bitrate: 2048
  • Задать Send I-frame each 1 second: 1

Дополнительный поток

  • Включить Enable Video1
  • Выбрать Video0 codec: h265
  • Задать Video resolution: 704×576
  • Задать Video frame rate: 25
  • Задать Video bitrate: 512
  • Задать Send I-frame each 1 second: 1

После проведения указанных манипуляций сохранить изменения — видео настроено. В разделе Preview картинку можно увидеть только для JPEG и MJPEG. Просмотр видео работает не всегда — баг это или фича, разбираемся.

Увидеть картинку можно через VLC, выбрав в меню пункт Открыть URL и введя одну из строк:

  • rtsp://admin:password@ip-address:554/stream=0 — первый поток
  • rtsp://admin:password@ip-address:554/stream=1 — второй поток

где: password — ваш пароль, ip-address — адрес камеры.

Переключение день/ночь

При наступлении тёмного времени суток или выключении источников света, как правило, видеокамеры переходят в ночной режим. Происходит перевод изображения в чёрно-белый режим, отключается ИК-фильтр и включается ИК-подсветка. В обратной ситуации производятся обратные действия.

Система может определять отсутствие света либо по датчику, либо по изображению. Пока Majestic умеет работать только с датчиком. В этой модели камеры его нет. Значит надо задать параметры управляющих выходов, а управлять ими придётся с помощью скрипта.

  • Включить Enable night mode
  • Задать GPIO pin1 of signal for IRcut filter: 105
  • Задать GPIO pin2 of signal for IRcut filter: 104
  • Задать GPIO pin to turn on night mode illumination: 114

Теперь Majestic знает про GPIO и можно попробовать поуправлять переключением вручную из командной строки через API. Нужно войти в систему под пользователем root без пароля. Команды следующие:

  • curl http://ip-address/night/on — включить ночной режим.
  • curl http://ip-address/night/off — выключить ночной режим.
  • curl http://ip-address/night/toggle — переключить режим.

Если всё работает, движемся дальше — автоматизируем процесс управления переключением режима на основе изменения времени экспозиции.

Скрипт управления переключением режима

Создаём файл файл скрипта:

cat > /usr/sbin/checkexp.sh

… и вставляем содержимое через буфер обмена:

!/bin/sh

login=$(cat /etc/httpd.conf | grep cgi-bin | cut -d':' -f2)
pass=$(cat /etc/httpd.conf | grep cgi-bin | cut -d':' -f3)

chtime=5 #change time to check exptime
chexp=50 #change exptime threshold (40-80)
day=1

while true; do

exp=$(curl -s http://localhost/metrics | grep ^isp_exptime | cut -d' ' -f2)
chexp=50 #change exptime threshold (40-80)
bri=expr $exp / 1000
echo $bri

if [ $bri -gt $chexp -a $day -eq 1 ] ;then
day=0
curl -u $login:$pass http://localhost/night/on
fi

if [ $bri -le $chexp -a $day -eq 0 ] ;then
day=1
curl -u $login:$pass http://localhost/night/off
fi

sleep $chtime
done

Сохраняем файл нажав комбинацию Ctrl+D и даём разрешение на выполнение:

chmod +x /usr/sbin/checkexp.sh

Если теперь запустить скрипт, то он начнёт анализировать экспозицию и управлять ночным режимом. В консоль, с интервалом в 5 секунд, будут выдаваться значения экспозиции. Самая простая проверка — накрыть камеру ладонью и через 5 секунд должен раздаться щелчок ИК-фильтра — включится ночной режим. Убрать ладонь и ещё через 5 секунд ночной режим выключится.

Для того, чтобы скрипт запускался автоматически при старте системы, создаём файл запуска:

cat > /etc/init.d/S99rc.local

… и вставляем содержимое:

./usr/sbin/checkexp.sh > /dev/null 2>&1 &
exit 0

Сохраняем файл нажав комбинацию Ctrl+D и даём разрешение на выполнение:

chmod +x /usr/sbin/S99rc.local

Теперь можно перезапускать камеру и радоваться что переключение режима работает. На самом деле, скрипт работает неидеально — надо допиливать.

Данная статья является обобщением информации на эту тему из обсуждения в группе OpenIPC users.
После того, как всё проверю ещё раз и решу, что явных косяков нет, статья появится в OpenIPC Wiki.

Оцените статью
( 1 оценка, среднее 5 из 5 )
МихаТроник
Добавить комментарий

  1. Аноним

    спасибо большое. очень много мучений с данной камерой. лежит уже год. а картинку на 4 пиксела показывает?

    Ответить
    1. mixatronik автор

      На прошивке РТ получить 4МП не удалось, только 3МП. На OpenIPC ещё не пробовал.

      Ответить
  2. trikolor

    Здравствуйте! Прошил вашей прошивкой, пинг идет, а в веб морду зайти не могу что делать!?

    Ответить
    1. mixatronik автор

      Во-первых, прошивка не моя. Я не настолько крут 🙂 Спасибо за фидбэк — самое главное то я и не указал! Входить надо через порт 85. Логин: admin, пароль: 12345. Добавлю в статью.

      Ответить
      1. trikolor

        и снова здравствуйте) зайти в веб интерфейс получилось, но существует ряд других проблем. в нем не сохраняются настройки, т.е. после перезапуска камеры она сбрасывается на заводские. и по потокам тоже пусто. пробовал открыть оба через влс плеер, результата нет. jpeg страница тоже пустая. по инструкции перепрошивали несколько раз, вроде все правильно сделал. а, еще момент, после того как подключаю камеру к интернету и пытаюсь зайти на нее, то пинги пропадают и достучаться к ней никак не получается. сетевые настройки были сделаны через путти, ибо через веб морду ничего не сохранилось, как я уже описал выше. при подключении к компу напрямую, без доступа в интернет, данной проблемы не наблюдается

        Ответить
        1. mixatronik автор

          Про глюк со сбросом в статье написано. Есть такой косяк, но это решаемо, хоть и временно. нужно сделать nand erase 0x900000 0x7700000. После этого настройки сохраняются, но потом, в какой-то момент опять могут сброситься. Решение будет, но позже. Потоки сразу не транслируются, тоже верно. Видимо что-то не так с настройками по умолчанию. Решение — надо явно настроить. Как именно, в сатье показано. Наблюдал отвал веб-морды после некорректных настроек. С выходом в Интернет проблем не было — адрес камера получает по DHCP, поэтому сразу в сети. И в облако IPEye её добавлял — видео транслирует.

          Ответить
          1. Wizard

            глюков дохуище
            1. бинарник majestic по умолчанию не запускается, поэтому изображения и нету — захожу консолью или ssh и запускаю
            2. в статье ничего не описано что надо ещё и модуль нужный выбрать — в данном случае libsns_ov4689.so
            3. настройки сохраняются никогда. не исключаю, что батарейка дохлая, но это не должно влиять
            4. зачем в этой инструкции мак адрес обнулять? после этого сетевой стек не инициализируется, пришлось руками в enveronment прописывать правильный MAC
            5. developer web dev+014db71, 2022-06-16 поинтереснее чуток

            короче, шляпа. ещё очень сырое fw но чуваки молодцы что делают

          2. mixatronik автор

            1. В норме бинарник запускается автоматически, но видимо, что-то не так с параметрами по умолчанию для этого сенсора, поэтому работать начинает только после того, как задашь эти параметры явно.
            2. Сенсор задаётся в энвах командой setenv sensor ov4689, выбирать его в настройках не обязательно.
            3. Чистил память nand erase 0x900000 0x7700000?
            4. Если ты про это setenv ethaddr 00:00:00:00:00:00, то имелось ввиду, что адрес надо задать свой. Понтяно же, что нули — это некорректно… Нет? Сорян, поправил.
            5. Сырое да, так и написал. Есть новая сборка с UBIFS: openipc.hi3516av100-nand-br.tgz. Там проблем с несохранением настроек быть не должно. Уже начал было тестировать и параллельно переписывать статью, но решил прошить православный бут вместо родного и что-то пошло не так — окирпичил.

            То, что в статье возможны косяки понятно, поэтому и не выкладываю пока в Вики проекта. Спасибо за обратную связь! Она помогает косяки устранять.

  3. Wizard

    >> Есть новая сборка с UBIFS

    я так понимаю, загрузчик не поддерживает UBIFS?

    No filesystem could mount root, tried: squashfs

    Kernel panic — not syncing: VFS: Unable to mount root fs on unknown-block(31,3)
    CPU: 0 PID: 1 Comm: swapper Not tainted 4.9.37 #1
    Hardware name: Hisilicon Hi3516A (Flattened Device Tree)
    Backtrace:
    [] (dump_backtrace) from [] (show_stack+0x18/0x1c)
    r7:c107e009 r6:c0530858 r5:00000000 r4:c056e2e8
    [] (show_stack) from [] (dump_stack+0x24/0x28)
    [] (dump_stack) from [] (panic+0xd0/0x238)
    [] (panic) from [] (mount_block_root+0x26c/0x2b0)
    r3:c1837ea0 r2:80000000 r1:c1837ea0 r0:c049a338
    r7:c107e009
    [] (mount_block_root) from [] (mount_root+0x128/0x130)
    r10:c0530838 r9:c050e5fc r8:c0530834 r7:c056e000 r6:c056e024 r5:c054488c
    r4:01f00003
    [] (mount_root) from [] (prepare_namespace+0x184/0x1cc)
    r9:c050e5fc r8:c0530834 r7:c056e000 r6:c056e000 r5:c056e024 r4:c0530858
    [] (prepare_namespace) from [] (kernel_init_freeable+0x1d0/0x1e0)
    r6:c056e000 r5:00000009 r4:c050b570
    [] (kernel_init_freeable) from [] (kernel_init+0x10/0xfc)
    r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c041ac84
    r4:00000000
    [] (kernel_init) from [] (ret_from_fork+0x14/0x2c)
    r5:c041ac84 r4:00000000
    Rebooting in 20 seconds..

    Ответить
    1. mixatronik автор

      Теоретически должен, там в оригинале, насколько помню, оно и есть, но в энвах прописано другое и надо либо заливать бут от OpenIPC, в котором есть все макросы, либо вручную править энвы в этом буте. Я выбрал первый вариант и… Теперь хочу на другой камере поправить энвы в имеющемся буте. И таблицу разделов тоже править надо.

      Вот вывод printenv из бута OpenIPC от другой камеры, чтобы понимать, что править, если соберёшься:
      bootargs=mem=${osmem} console=ttyAMA0,115200 panic=20 root=/dev/mtdblock3 rootfstype=squashfs init=/init mtdparts=${mtdparts}
      bootcmd=setenv setargs setenv bootargs ${bootargs}; run setargs; sf probe 0; sf read ${baseaddr} 0x50000 0x200000; bootm ${baseaddr}; reset
      bootdelay=1
      baudrate=115200
      ethaddr=00:00:23:34:45:66
      ipaddr=192.168.1.10
      serverip=192.168.1.107
      gatewayip=192.168.1.1
      netmask=255.255.255.0
      bootfile="uImage"
      baseaddr=0x82000000
      uknor=mw.b ${baseaddr} ff 1000000; tftpboot ${baseaddr} uImage.${soc} && sf probe 0; sf erase 0x50000 0x200000; sf write ${baseaddr} 0x50000 ${filesize}
      uknor16m=run uknor
      urnor8m=mw.b ${baseaddr} ff 1000000; tftpboot ${baseaddr} rootfs.squashfs.${soc} && sf probe 0; sf erase 0x250000 0x500000; sf write ${baseaddr} 0x250000 ${filesize}
      urnor16m=mw.b ${baseaddr} ff 1000000; tftpboot ${baseaddr} rootfs.squashfs.${soc} && sf probe 0; sf erase 0x250000 0xa00000; sf write ${baseaddr} 0x250000 ${filesize}
      uknand=mw.b ${baseaddr} ff 1000000; tftpboot ${baseaddr} uImage.${soc} && nand erase 0x100000 0x300000; nand write ${baseaddr} 0x100000 0x300000
      urnand=mw.b ${baseaddr} ff 1000000; tftpboot ${baseaddr} rootfs.ubi.${soc} && nand erase 0x400000 0x1000000; nand write ${baseaddr} 0x400000 0x1000000
      mtdparts=hi_sfc:256k(boot),64k(env),2048k(kernel),5120k(rootfs),-(rootfs_data)
      mtdpartsubi=setenv mtdparts hinand:256k(boot),768k(wtf),3072k(kernel),-(ubi)
      mtdpartsnand=setenv mtdparts hinand:256k(boot),768k(wtf),3072k(kernel),10240k(rootfs),-(rootfs_data)
      mtdpartsnor8m=setenv mtdparts hi_sfc:256k(boot),64k(env),2048k(kernel),5120k(rootfs),-(rootfs_data)
      mtdpartsnor16m=setenv mtdparts hi_sfc:256k(boot),64k(env),2048k(kernel),10240k(rootfs),-(rootfs_data)
      nfsroot=/srv/nfs/hi3516cv300
      bootargsnfs=mem=${osmem} console=ttyAMA0,115200 panic=20 root=/dev/nfs rootfstype=nfs ip=${ipaddr}:::255.255.255.0::eth0 nfsroot=${serverip}:${nfsroot},v3,nolock rw
      bootargsubi=mem=${osmem} console=ttyAMA0,115200 panic=20 init=/init root=ubi0:rootfs rootfstype=ubifs ubi.mtd=3,2048 mtdparts=${mtdparts}
      bootnfs=setenv setargs setenv bootargs ${bootargsnfs}; run setargs; tftpboot ${baseaddr} uImage.${soc}; bootm ${baseaddr}; reset
      bootcmdnand=setenv setargs setenv bootargs ${bootargs}; run setargs; nand read ${baseaddr} 0x100000 0x300000; bootm ${baseaddr}; reset
      bootcmdubi=setenv setargs setenv bootargs ${bootargsubi}; run setargs; nand read ${baseaddr} 0x100000 0x300000; bootm ${baseaddr}; reset
      bootcmdnor=setenv setargs setenv bootargs ${bootargs}; run setargs; sf probe 0; sf read ${baseaddr} 0x50000 0x200000; bootm ${baseaddr}; reset
      setnand=run mtdpartsubi; setenv bootcmd ${bootcmdubi}; saveenv; reset
      setnor8m=run mtdpartsnor8m; setenv bootcmd ${bootcmdnor}; saveenv; reset
      setnor16m=run mtdpartsnor16m; setenv bootcmd ${bootcmdnor}; saveenv; reset
      osmem=32M
      soc=hi3516cv300
      stdin=serial
      stdout=serial
      stderr=serial
      totalmem=256M
      verify=n
      ver=U-Boot 2010.06-dirty (May 12 2022 - 18:47:54)

      Ответить
      1. Wizard

        Видимо, нектоне хочет ковыряться в bootargs))

        Ответить
        1. mixatronik автор

          Это безопаснее, а насчёт ковыряния — всё ж есть. Тупо копи-паст, но с умом конечно.

          Ответить