前端时间带实习生的过程中顺带学习了一下F103调OV2640传感器获取图片,顺带把图像通过以太网抛出。MCU采用状态机写法(整理后开源),通过TCP/UDP传输在PC上解包不要太顺利了.(这里要感谢实习生wyr填好的路)


接下来,主要想把上位机解包程序移植到哪吒开发板上,目标平台:Tina.
开源项目
哪吒开发板实现TCP/UDP图传:
https://gitee.com/YJHmath/image-transmission-d1-tina
图传协议:
https://docs.qq.com/doc/DVkRZUXhSa3prbXZp
预期需求:
- JPEG图片输出到HDMI, 或者MIPI.
- 整合NCNN, 直观看识别效果.
- 或许会支持更通用(复杂)的PES协议.
阶段性成果汇报
2021年9月30日
HDMI调通
开发过程
一开始着重快速地把协议移植, 所以我会使用cmake工具在win下qtcreator编写, 在Ubuntu20.10交叉编译.
开发语言自然是C++和C混着搭. 因为C++有着丰富的轮子,
程序采用了:
- 陈硕大佬的muduo网络库(C++)的Buffer类作为接收缓冲区.
- UNP例程库(C)来做一个简单的UDP Server, 就喜欢它足够简单纯粹.
这两个库在哪吒上的编译过程可以参考:
muduo网络库在哪吒上编译
《Unix网络编程》例程库在哪吒上编译
技术受限
一开始我想把接收到的图片一气呵成地输出到HDMI时, 但发现若将fbviewer目录(tina-d1-open/out/d1-nezha/compile_dir/target/fbviewer)下除main.o外的.o文件链接成静态库(.a), 再编译出来的程序无法正常运行:
root@TinaLinux:/mnt/nfs/tina# ./fbtest
./fbtest: line 1: ELF�8@@
: not found
./fbtest: line 3: syntax error: EOF in backquote substitution
这是一道坎, 望各位大佬指教.
寻求解决
既然验证了链接到静态库存在问题. 那能想到解决思路有3种:
- 把已经正常运行的图传程序从C++改成C语言, 直接链接到fbviewer相关的.o文件, 这样程序大概率能正常运行. 但相当于弃盔卸甲, 还要用C把缓存区再造一遍.
- 把整个fbviewer里jpeg输出到HDMI的代码搬到图传程序里, 然后笃定地相信它会编译成功.
- 不要忘了操作系统扮演协调资源的角色. 图传程序将接收到的图片储存到运行目录下, 然后再魔改一下fbviewer, 通过stat读取运行目录下对应图像文件的最后修改时间有无发生变化来决定是否要通过HDMI输出图像. 这样就不用再纠结高层代码和底层代码之间千丝万缕的关系.
对于下班的闲暇抽空写码的我, 毫不犹豫地选择了第3种.
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/stat.h>
int main()
{
printf("Hello world\n");
char* path = "pic.jpg";
uint32_t ts = 0;
struct stat tmp;
stat(path, &tmp);
uint8_t* image = (uint8_t*)malloc(1600 * 1200 * 3);
int is_need_output = 0;
while(1)
{
stat(path, &tmp);
//printf("st_ctime:%d\n", tmp.st_ctime);
if(ts != tmp.st_ctime)
{
ts = tmp.st_ctime;
is_need_output = 1;
}
if(is_need_output)
{
fh_jpeg_load(path, image, NULL, 1600, 1200);
fb_display(image, NULL, 1600, 1200, 0, 0, 160, 0);
is_need_output = 0;
}
usleep(25 * 1000);
}
free(image);
return 0;
}
既然程序需要频繁地读写, 那就直接放到挂载到RAM的目录吧!
于是乎:
下一步把ncnn的demo整合应该也不是什么难事.
效果如上.