Upcoming maintenance
Dear Customers and Partners.
This website will be undergoing scheduled maintenance on June 14, 2023. Please be aware there may be disruption to the developer portal website and associated services during the scheduled maintenance period.
This upgrade is essential to ensure the continued performance, reliability, and security of Developer World.
We apologize for any inconvenience.
I can't get the camera sample program to work.
-
Hi!
I'm having trouble getting my camera program to work and would really appreciate your help.Previously, the camera sample program worked fine, but since I created my own camera program, I get link errors when I try to build only the camera sample program.
The error was as follows.arm-none-eabi-ld: /Users/gyps/spresense/nuttx/staging/libapps.a(camera_main.c.Users.gyps.spresense.sdk.apps.examples.camera.o): in function `camera_main': /Users/gyps/spresense/sdk/apps/examples/camera/camera_main.c:766: undefined reference to `video_uninitialize' arm-none-eabi-ld: /Users/gyps/spresense/sdk/apps/examples/camera/camera_main.c:507: undefined reference to `video_initialize' arm-none-eabi-ld: /Users/gyps/spresense/nuttx/staging/libapps.a(my_camera_main.c.Users.gyps.spresense.myapps.mycamera.o): in function `mycamera_main': /Users/gyps/spresense/myapps/mycamera/my_camera_main.c:62: undefined reference to `video_initialize' arm-none-eabi-ld: /Users/gyps/spresense/myapps/mycamera/my_camera_main.c:198: undefined reference to `video_uninitialize' make[2]: *** [nuttx] Error 1 make[1]: *** [nuttx] Error 2 make: *** [all] Error 2
◯ What I tried
1, Run only the camera sample after doing make distclean.
→The same error occurred.2, run source spresenseenv/setup.
→The same error occurred.3, Try the same thing in another environment (wsl2 ).
→The same error occurred.◯ Environment
OS: mac OS Big Sur version 11.6
Ubuntu 20.04 LTS (WSL2)
SDK version: 2.6 -
The following shows the process from the time the environment is created until the error occurs.
1, Make a new environment.
(Download spresense again via git clone.)2, Get the camera sample working.
(at this point it works and I can make the camera work)3, Run "make distclean", delete the camera sample settings in the config menu, and build my own camera program with "make -j".
I got a link error as shown below.arm-none-eabi-ld: /home/gyps/spresense/nuttx/staging/libapps.a(my_camera_main.c.home.gyps.spresense.myapps.my_camera.o): in function `my_camera_main': /home/gyps/spresense/myapps/my_camera/my_camera_main.c:59: undefined reference to `video_initialize' arm-none-eabi-ld: /home/gyps/spresense/myapps/my_camera/my_camera_main.c:195: undefined reference to `video_uninitialize' make[2]: *** [Makefile:156: nuttx] Error 1 make[1]: *** [tools/Makefile.unix:420: nuttx] Error 2 make: *** [Makefile:114: all] Error 2
4, Execute "make distclean", delete the program you created by myself in the config menu, and build the camera sample with "make -j".
The following link error occurs.arm-none-eabi-ld: /home/gyps/spresense/nuttx/staging/libapps.a(camera_main.c.home.gyps.spresense.sdk.apps.examples.camera.o): in function `camera_main': /home/gyps/spresense/sdk/apps/examples/camera/camera_main.c:507: undefined reference to `video_initialize' arm-none-eabi-ld: /home/gyps/spresense/sdk/apps/examples/camera/camera_main.c:766: undefined reference to `video_uninitialize' arm-none-eabi-ld: /home/gyps/spresense/nuttx/staging/libapps.a(camera_bkgd.c.home.gyps.spresense.sdk.apps.examples.camera.o): in function `nximage_listener': /home/gyps/spresense/sdk/apps/examples/camera/camera_bkgd.c:134: undefined reference to `nx_eventhandler' arm-none-eabi-ld: /home/gyps/spresense/nuttx/staging/libapps.a(camera_bkgd.c.home.gyps.spresense.sdk.apps.examples.camera.o): in function `nximage_initialize': /home/gyps/spresense/sdk/apps/examples/camera/camera_bkgd.c:241: undefined reference to `nx_connectinstance' arm-none-eabi-ld: /home/gyps/spresense/sdk/apps/examples/camera/camera_bkgd.c:273: undefined reference to `nx_setbgcolor' arm-none-eabi-ld: /home/gyps/spresense/sdk/apps/examples/camera/camera_bkgd.c:274: undefined reference to `nx_requestbkgd' arm-none-eabi-ld: /home/gyps/spresense/sdk/apps/examples/camera/camera_bkgd.c:278: undefined reference to `nx_disconnect' arm-none-eabi-ld: /home/gyps/spresense/nuttx/staging/libapps.a(camera_bkgd.c.home.gyps.spresense.sdk.apps.examples.camera.o): in function `nximage_draw': /home/gyps/spresense/sdk/apps/examples/camera/camera_bkgd.c:320: undefined reference to `nx_bitmap' arm-none-eabi-ld: /home/gyps/spresense/nuttx/staging/libapps.a(camera_bkgd.c.home.gyps.spresense.sdk.apps.examples.camera.o): in function `nximage_finalize': /home/gyps/spresense/sdk/apps/examples/camera/camera_bkgd.c:337: undefined reference to `nx_disconnect' make[2]: *** [Makefile:156: nuttx] Error 1 make[1]: *** [tools/Makefile.unix:420: nuttx] Error 2 make: *** [Makefile:114: all] Error 2
-
Hello, @gyps
This problem usually happens when you don't have the right configurations for the sdk.
For example: The message "undefined reference to `video_uninitialize'" will appear if you don't have the DRIVERS_VIDEO configuration enabled on the sdk.Can I ask how are you creating your own application?
-
Thanks for the reply.
I took the camera sample project to the MYAPPS directory and corrected the "Kconfig", "Makefile" and "Make.defs" as usual, and also rewrote the main program to get only one image.In addition, I have merged c files into one, and removed programs I deemed unnecessary.
Also, the device driver settings in the config menu have not been changed.
For reference, the modified files other than my_camera_main.c are shown below.
Kconfig
config MYAPPS_CAMERA tristate "My Camera example" default y ---help--- Enable the camera example if MYAPPS_CAMERA config MYAPPS_CAMERA_PROGNAME string "Program name" default "mycamera" ---help--- This is the name of the program that will be use when the NSH ELF program is installed. config MYAPPS_CAMERA_PRIORITY int "Camera task priority" default 100 config MYAPPS_CAMERA_STACKSIZE int "Camera stack size" default 2048 config MYAPPS_CAMERA_OUTPUT_LCD bool "Output to LCD" default n ---help--- This enables to output the captured RGB565 image to LCD. endif
Makefile
include $(APPDIR)/Make.defs include $(SDKDIR)/Make.defs PROGNAME = $(CONFIG_MYAPPS_CAMERA_PROGNAME) PRIORITY = $(CONFIG_MYAPPS_CAMERA_PRIORITY) STACKSIZE = $(CONFIG_MYAPPS_CAMERA_STACKSIZE) MODULE = $(CONFIG_MYAPPS_CAMERA) MAINSRC = my_camera_main.c include $(APPDIR)/Application.mk
Make.defs
ifneq ($(CONFIG_MYAPPS_CAMERA),) CONFIGURED_APPS += mycamera endif
and my_camera_main.c
-
A simplified my_camera_main.c is shown below.
#include <nuttx/config.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <sys/time.h> #include <sys/ioctl.h> #include <time.h> #include <nuttx/video/video.h> #include <stdint.h> #include <sys/types.h> #define IMAGE_RGB_SIZE (320*240*2) #define IMAGE_FILENAME_LEN (32) #define STILL_BUFNUM (1) struct v_buffer { uint32_t *start; uint32_t length; }; typedef struct v_buffer v_buffer_t; static void free_buffer(struct v_buffer *buffers, uint8_t bufnum) { uint8_t cnt; if (buffers){ for (cnt = 0; cnt < bufnum; cnt++){ if (buffers[cnt].start){ free(buffers[cnt].start); } } free(buffers); } } int main(void){ int ret; int fd; int buffernum = 2; int cnt; struct v4l2_format fmt = {0}; struct v4l2_requestbuffers req = {0}; struct v4l2_buffer buf ={0}; struct v_buffer *buffers_still = NULL; static char s_fname[IMAGE_FILENAME_LEN]; static int s_framecount = 0; FILE *fp; ret = video_initialize("/dev/video"); if (ret != 0){ printf("ERROR: Failed to initialize video: errno = %d\n", errno); return ERROR; } fd = open("/dev/video", 0); if (fd < 0){ printf("ERROR: Failed to open video.errno = %d\n", errno); return ERROR; } fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = VIDEO_HSIZE_QVGA; fmt.fmt.pix.height = VIDEO_VSIZE_QVGA; fmt.fmt.pix.field = V4L2_FIELD_ANY; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB565; ret = ioctl(fd, VIDIOC_REQBUFS, (unsigned long)&fmt); if (ret < 0){ printf("Failed to VIDIOC_REQBUFS: errno = %d\n",errno); return ERROR; } req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_USERPTR; req.count = buffernum; req.mode = V4L2_BUF_MODE_RING; ret = ioctl(fd, VIDIOC_REQBUFS, (unsigned long)&req); if (ret < 0){ printf("Failed to VIDIOC_REQBUFS: errno = %d\n", errno); return ERROR; } buffers_still = malloc(sizeof(v_buffer_t) * buffernum); if (!(buffers_still)){ printf("Out of memory for array of v_buffer_t[%d]\n", buffernum); return ERROR; } for (cnt = 0; cnt < buffernum; cnt++){ (buffers_still)[cnt].length = IMAGE_RGB_SIZE;//QVGA_RGB(320,240,2) (buffers_still)[cnt].start = memalign(32, IMAGE_RGB_SIZE); if (!(buffers_still)[cnt].start){ printf("Out of memory for image buffer of %d/%d\n",cnt, buffernum); while (cnt){ cnt--; free((buffers_still)[cnt].start); } free(buffers_still); buffers_still = NULL; return ERROR; } } for (cnt = 0; cnt < buffernum; cnt++){ memset(&buf, 0, sizeof(v4l2_buffer_t)); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_USERPTR; buf.index = cnt; buf.m.userptr = (unsigned long)(buffers_still)[cnt].start; buf.length = (buffers_still)[cnt].length; ret = ioctl(fd, VIDIOC_QBUF, (unsigned long)&buf); if (ret){ printf("Fail QBUF %d\n", errno); free_buffer(buffers_still, buffernum); buffers_still = NULL; return ERROR; } } int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = ioctl(fd, VIDIOC_STREAMON, (unsigned long)&type); if (ret < 0){ printf("Failed to VIDIOC_STREAMON: errno = %d\n", errno); free_buffer(buffers_still, buffernum); buffers_still = NULL; return ERROR; } memset(&buffers_still, 0, sizeof(v4l2_buffer_t)); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_USERPTR; ret = ioctl(fd, VIDIOC_DQBUF, (unsigned long)buffers_still); if (ret){ printf("Fail DQBUF %d\n", errno); return ERROR; } s_framecount++; if (s_framecount >= 1000){ s_framecount =1; } memset(s_fname, 0, sizeof(s_fname)); snprintf(s_fname, IMAGE_FILENAME_LEN, "%s/VIDEO/%03d.%s", "/mnt/spif", s_framecount,"RGB"); printf("FILENAME:%s\n", s_fname); fp = fopen(s_fname, "wb"); if (NULL == fp){ printf("fopen error : %d\n", errno); return ERROR; } if (buf.bytesused != fwrite((uint8_t *)buf.m.userptr, 1, (size_t)buf.bytesused, fp)){ printf("fwrite error : %d\n", errno); } fclose(fp); ret = ioctl(fd, VIDIOC_QBUF, (unsigned long)&buffers_still); if(ret){ printf("Fail QBUF %d\n",errno); return ERROR; } close(fd); free_buffer(buffers_still, STILL_BUFNUM); video_uninitialize(); return 0; }
-
So you created a new MYAPPS directory.
Did you remember to copy Makefile, Make.defs and .sdksubdirs from the examples directory and put those in your MYAPPS directory?
Like mentioned in: https://developer.sony.com/develop/spresense/docs/sdk_set_up_en.html#_add_to_a_different_directory
-
I didn't copy them, but created a directory like "tools/mkappsdir.py myapps "My Apps"".
-
This post is deleted! -
Hey, @gyps
I'm trying to reproduce your process on my side to see if I can figure out what went wrong, but I'm just thinking..
You know what is a quick way to figure out if your issue is with your own code or with the process of creating a new app is to slowly modify the actual camera example and see in which point it stops working.
-
@CamilaSouza
Thank you for your thoughts.
I changed the camera sample and was able to build it successfully. I think it may be due to the environment, not the code. I don't know the specific cause yet, but I will fill in the details as soon as I find out. -
Thank you for the feedback!
-
@CamilaSouza I have built the camera program since then, but only when enabling multi_webcam from the Kconfig file or from the OS settings, it does not work and I often get the aforementioned error.
Also If I do the following, I can enable it successfully without any problem.. /tools/config.py examples/multiwebcam