I have got an issue with the same setup. I am using a CM4 IO board with two Pi Camera v2.1 devices. Both of them were attached to the board and I executed the dual-camera option:
sudo wget https://datasheets.raspberrypi.org/cmio/dt-blob-dualcam.bin -O /boot/dt-blob.bin
I can see one of the cameras (attached to the CAM1 port) but I cannot use the CAM0 camera....
I had something similar when trying to use the generic camera commands through ssh during the setup process.
I could tell that something was taking control of the camera on boot. Turned out to be the on board web server.
Try opening a browser and typing in:
XXX.XXX.XXX.XXX:5000 where XXX... is the private IP of the robot and it is on the same network as the ...
raspistill -t 10 -v -md 3 -bm -ex off -ag 1 -ISO 800 -st -ss 2000000 -a 1052
And get a 2 second exposure. I have found that raspistill takes 5 exposures before it takes the exposure that returns an image. This means that call will take 5-6 times the shutter speed. In this case 10 seconds for the 5 exposures you don't see and then 2 seconds for the ...
I send a stream of JPEG files using zmq which is a kind of wrapper over sockets that handles most of the ugly for you. It's not a standard protocol though.
from picamera import PiCamera
context = zmq.Context()
socket = context.socket(zmq.PUB)
# CONFLATE=1 disables the send queue so it will drop frames instead of creating latency.
For the complete workflow (decode image, send result elsewhere) you will need to invest some programming time, but the zbar-tools suite offers tools to read a camera stream and decode various codes found on the images, so you can take that as a starting point.