今天来兴致了,写一点8月份接到的一个编码器定制的心得吧,喜欢的老铁们耐点心看看,也不枉小编我的辛苦付出。
背景
这是一个来自佛山某学校的定制需求,就是想用我们的ENC编码器
实现定时录像的功能,需求比较明确,经过几次的需求文件修订,最终定稿。
下面就详细讲讲定制的过程,这个需要开发板的,对应于成品的,目前有ENC1,ENC2,ENC5
支持定制开发,客户选型为ENC2, 链接如下:https://item.taobao.com/item.htm?spm=a2oq0.12575281.0.0.50111debCy8vsG&ft=t&id=630502728823
然后如下图所示,链接好串口线:
第一步:下载交叉编译环境
值得称道的是,开发板提供的交叉编译环境是现成的虚拟机,只要下载下来就能直接使用了。至于在哪下载,这里就不贴了,买了开发板自然就会有了。包括开发说明书等。虚拟机中有许多关于编码器的例子工程,如下图所示:
第二步:更新最新的编码器源码
如果连接开发板,如何通过串口命令启动开发板,说明书里都有,这里跳过,由于虚拟机中集成了多种板卡的运行环境,需要在使用之前进行切换,选择您所购买的板卡类型。具体操作为:
cd ~/work/35XX/
./board.sh
运行效果如下图:
更新SDK:
cd ~/work/LinkLib
./update.sh
更新编码器源码:
cd ~/work/Encoder
git pull
第三步:增加定时录像功能
通过对编码器的代码分析,结构很清晰,都是通过一个叫RPC
的功能模块在WEB界面和Encoder之间进行json的参数传递和发送指令,这里我们增加一个功能模块就行了,我取名为TimerTask
。
下面就是这个功能模块的头文件,功能实现这里就不展现了,需要的朋友可以通过以下链接找到我:
https://item.taobao.com/item.htm?spm=a2oq0.12575281.0.0.50111debCy8vsG&ft=t&id=656995423274
#ifndef TIMERTASK_H
#define TIMERTASK_H
#include <QObject>
///
/// The RecTask class
#include "Link.h"
#include <QTimer>
#define TIMER_TASK_VERSION "3.20"
#define TIMERTASKPATH "/link/config/timertask.json"
#define TASKMODE_CLOSE "x"
#define TASKMODE_ONCE "-"
#define TASKMODE_EVERYDAY "*"
#define TASKMODE_MON "1"
#define TASKMODE_TUES "2"
#define TASKMODE_WEDNES "3"
#define TASKMODE_THURS "4"
#define TASKMODE_FRI "5"
#define TASKMODE_SATUR "6"
#define TASKMODE_SUN "0"
#define TASKSTATE_CLOSE 0
#define TASKSTATE_WAITING 1
#define TASKSTATE_STARTING 2
#define MOD_LICKEY_NULL 0
#define MOD_LICKEY_VALID 1
#define MOD_LICKEY_TEST 2
#ifndef __MOD_AUTHRESULT__
#define __MOD_AUTHRESULT__
#define MOD_AUTHRESULT_OK 10000
#define MOD_AUTHRESULT_ERR_VENDOR 10001
#define MOD_AUTHRESULT_ERR_AUTHID 10002
#define MOD_AUTHRESULT_ERR_NORMAL 10003
#define MOD_AUTHRESULT_ERR_TESTID_NULL 10004
#define MOD_AUTHRESULT_ERR_TESTID_VENDOR 10005
#define MOD_AUTHRESULT_ERR_TESTID_FORMAT 10006
#define MOD_AUTHRESULT_ERR_TESTID_KEYFMT 10007
#define MOD_AUTHRESULT_ERR_TESTID_KEY 10008
#define MOD_AUTHRESULT_ERR_TESTID_EXPIRED 10009
#endif
class TimerTask : public QObject
{
Q_OBJECT
public:
explicit TimerTask(QObject *parent = 0);
QVariantMap config;
virtual void init();
QString writeCom(const QString &com);
bool start_task(QVariantMap &taskMap, QString dbgstr="");
bool stop_task(QVariantMap &taskMap, int taskstate=TASKSTATE_CLOSE, QString dbgstr="");
bool start();
bool stop();
private:
QTimer* timerRec = nullptr;
bool m_bTaskUpdated = false;
QVariantMap m_authcfg;
bool m_getauthcfg_flag=false;
QStringList m_weekcns;
QStringList m_weekens;
QStringList m_taskmods;
QVariantMap m_taskstates;
int m_timercounter = 0;
int m_lickey_type = 0;
void test();
bool isMountDisk();
QString get_auth_code(QString devsn="");
bool update_authfile();
QVariantMap make_hongshan_auth_map(int flag, QString devsn="");
QVariantMap get_hongshan_auth();
void set_hongshan_auth(QVariantMap authcfg);
void init_hongshan_auth();
QString encode_test_id(QString testid);
QString decode_test_id(QString base64testid);
bool check_authid_update();
void decrease_test_id_counter(QVariantMap& vendor);
void clear_test_id_counter();
int test_id_is_valid();
int hongshan_auth_is_valid(QString dbgstr="");
bool updateauth_is_valid(QVariantMap authcfg);
bool channel_is_enabled(int chid);
bool check_task_changed(QVariantList &newtasks, QVariantList oldtasks);
bool startch(int chid);
bool stopch(int chid);
int getThisTimestamp(QString time);
int getCurrTimestamp(QString &week);
int getRecFileSize(QString filename);
QString getNewFileName(QString recpath, QString filehead, QString filefmt);
bool IsRecordState(int chid);
void check_switchfile_for_filesize();
void week_transto_taskmod(QString &week);
//void test_printf_any(QVariantMap anyObj);
void set_task_status(QString taskid, int st, QString dbgstr="");
int get_task_status(QString taskid);
bool task_is_starting(QString taskid);
void delete_this_taskid(QString taskid);
int get_sys_runtime();
bool isSysRunTimeout();
void delete_curr_authfile();
public slots:
void timerRecProcess();
bool update(QString json);
int authvalid();
QString getTaskStatus();
};
extern TimerTask *GTimerTask;
#endif // TIMERTASK_H
然后将这个功能类在main函数中创建以下:
int main(int argc, char *argv[])
{
//.......
*[2021-7-24] *///
setbuf(stdout, NULL); /*printf 输出控制*/
GTimerTask=new TimerTask();
GTimerTask->init();
*[2021-7-24] *///
//......
}
经过了1-2个月的晚上编写,终于完成了代码,然后编译:
执行文件在如下目录:
/home/linkpi/work/3531D/fs/link/bin/
第四步: 编写WEB控制页面
WEB控制页面要命了,凭着这几之前对HTML的一些了解,这些上层代码花了好几个晚上研究,照猫画虎,总算是画出个原型:
剩下的就是发送指令给Encoder, 同样参考其他页面,完全是照猫画虎式完成了整个定时录像功能,不容易啊,这一块整的时间估计比Encoder时间要长哈,也不怪了,本小编熟悉的是C, 对javasrcipt只是略懂皮毛而已。哈哈,不过通过这次,以后弄个页面也轻松许多了。
第五步: 打包成升级文件
这一步略过了,开发文档都有,就不细说了。
老铁们,码字不容易啊,多多给点赞和收藏。