博通机顶盒平台framebuffer输出(一)

2023-10-08 08:59

本文主要是介绍博通机顶盒平台framebuffer输出(一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

博通机顶盒平台framebuffer输出(一)之CFE 命令行输出到LCD

博通机顶盒平台framebuffer输出分为两部分:

  • 第一部分是bootloader,即CFE支持framebuffer的命令行显示;
  • 第二部分是linux,将linux的命令行通过framebuffer输出显示;

一旦bootloader和linux两部分都支持framebuffer,机顶盒一开机就能通过HDMI输出显示的命令行到外部设备。

环境:

  • 硬件平台:BCM97583
  • CFE 版本:bcm97583 cfe v3.7
  • Linux版本:stblinux-3.3-4.0linux 3.3.8的定制版本)
  • 输出方式:HDMIHDMIDVI

本文详细讲述第一部分,CFE将命令行输出到LCD的实现。

1. 简述

CFE默认只支持串口输出,我刚接触CFE的时候就特别期望能将CFE的命令行输出到显示器上。

借鉴u-bootlcd驱动,在cfe上实现将命令行输出到显示器上。

很容易基于这个版本的代码将实现移植到最新的cfe(mips平台)或bolt(arm平台)代码上。

2. 效果预览

CFE命令行(720x576)通过HDMIDVI输出到显示器:

CFE命令行输出到LCD

3. 代码实现

3.1 显示综述

官方CFE代码不支持framebuffer驱动,所以不能进行任意的输出控制。但是CFE有个SPLASH功能,可以将存放在flash上的BMP图像作为开机logo显示。

对于SPLASH,实现分为几个步骤:

  1. 指定显示使用的surface memory
  2. BMP图像读取到内存
  3. 加载预先生成的显示和输出相关寄存器
  4. 将内存中的BMP图像输出到surface memory相应位置

显然,通过上一节中的步骤1和4,机顶盒已经完成了显示的初始化,具备了基本的显示能力,例如显示一个单色屏幕。

基于这个显示基础,通过操纵surface memory,实现命令行的输出。

功能上代码实现分为4个部分:

  • 字库数据(font_8x16.h
  • 显示设备管理(dev_lcd.c
  • 显示内容管理(fbcon.c
  • 显示的初始化和调用(cfe_main.c, cfe_console.c

3.2 字库数据

font_8x16.h表述了字符数据信息:

#define VIDEO_FONT_CHARS    256
#define VIDEO_FONT_WIDTH    8
#define VIDEO_FONT_HEIGHT   16
#define VIDEO_FONT_SIZE     (VIDEO_FONT_CHARS * VIDEO_FONT_HEIGHT)static unsigned char video_fontdata[VIDEO_FONT_SIZE] =
{...
}

包括:

  • 字符数量:VIDEO_FONT_CHARS
  • 字符宽度:VIDEO_FONT_WIDTH
  • 字符高度:VIDEO_FONT_HEIGHT
  • 字符数据大小:VIDEO_FONT_SIZE

    (每个bit描述一个pixel2568x16的字符,占用大小为256x(8x16)/8=256x16字节)

  • 字符数据内容:video_fontdata[VIDEO_FONT_SIZE]

这里直接采用Linux下的等宽字库数据font_8x16.h,也是最经典的命令行字库,从小到大看到的命令行基本上都是采用这个字库。等宽字符的优点很明显,可以通过ascii码以及字符的高和宽线性计算字符数据的起始地址从而获得所需的点阵数据。
也可以根据喜好更换为其它等宽字库数据。

3.3 数据结构

dev_lcd.h定义了lcd驱动所用到的结构体,主要包括3类:

  • lcd_probe_t

lcd_probe_t定义了用于设备初始化操作probe的结构体:

typedef struct lcd_probe_s {/* 旋转标识,暂时没有用到 */uint8_t rotation;   /* rotation of display (0, 1, 2, 3) *//* 单个像素占用的比特数,可计算转换为单个像素占用的字节数 */uint8_t bpp;        /* bits per pixel *//* 显示设备的宽和高 */uint32_t width, height;/* 显示输出使用的前景和背景色 */uint32_t bg_color, fg_color; /* background/foreground color *//* 定义console的区域 */win_t win;/* framebuffer基址 */void *base;         /* buffer */
}lcd_probe_t;

console默认宽高和设备宽高一致,也可以通过win指定console的宽和高,使其只占用一部分显示区域。

  • fbcon_t

fbcon_t是结构体fbcon_stypedeftypedef struct fbcon_s fbcon_t;

其定义了console的详细信息和操作:

struct fbcon_s {/* 起始位置(左上角) */uint32_t x, y;/* 宽、高 */uint32_t w, h;/* 总列和行数量(按字符统计) */int32_t cols, rows;/* 当前cursor位置 */int32_t cur_col, cur_row;/* 在全屏坐标位置(x, y)输出字符c */void (*putc_xy)(fbcon_t *con, uint32_t x, uint32_t y, char c);/* 移动rowsrc行到rowdst */void (*moverow)(fbcon_t *con, uint32_t rowdst, uint32_t rowsrc);/* 使用颜色color清除row位置的整行 */void (*setrow)(fbcon_t *con, uint32_t row, uint32_t color);/* framebuffer基址 */void *start;    /* framebuffer start addr *//* 预留,未使用 */void *cmap;     /* color map *//* 指向显示设备的指针 */lcddev_t *lcd;  /* lcd device */
};

start指向framebuffer基址,如果console起始位置为(0,0),则start指向显示设备的base

lcd指向结构体lcddev_t的指针,便于访问设备的rotationbg_colorfg_color等信息

  • lcddev_t

lcddev_t是结构体lcddev_stypedeftypedef struct lcddev_s lcddev_t;

struct lcddev_s {uint8_t rotation;               /* rotation of displays */uint8_t bpp;                    /* bits per pixel */uint32_t width, height;uint32_t pitch;                 /* line pitch in bytes */uint32_t bg_color, fg_color;fbcon_t con;                  /* consoles */void *base;                     /* buffer */
};

3.4 显示设备管理

dev_lcd.c实现了显示设备的管理,主要围绕CFE设备管理的两个结构体进行操作:

/** device dispatch*/
const static cfe_devdisp_t lcddrv_dispatch = {lcddrv_open,NULL /* lcddrv_read */,NULL /* lcddrv_inpstat */,lcddrv_write,NULL /* lcddrv_ioctl */,lcddrv_close,NULL /* lcddrv_poll */,NULL
};const cfe_driver_t lcddrv = {"LCD Console","lcd",CFE_DEV_OTHER,&lcddrv_dispatch,lcddrv_probe
};

这里将显示使用的surface memory虚拟为一个lcd设备,由结构体lcddrv进行管理,并对这个设备进行操作:

  • lcddrv_probe

结构体lcddrv的成员lcddrv_probe会根据传入的参数对lcd进行初始化:


static void lcddrv_probe(cfe_driver_t *drv,unsigned long probe_a, unsigned long probe_b,void *probe_ptr)
{lcddev_t *softc;lcd_probe_t *probe;win_t win;bvn_init *init = NULL;char descr[80];char buffer[40];BPXL_Format format;/** Now, on with the probing:*  probe_a is the bvn_init function address*  probe_b is unused*  probe_ptr is probe structure pointer*//** probe_a:指向显示的BVN(Braodcom Video Network)初始化函数* probe_b:未使用* probe_ptr:指向lcd_probe_t结构体*/probe = (lcd_probe_t *)probe_ptr;softc = (lcddev_t *)KMALLOC(sizeof(lcddev_t), 0);if (softc){memset(softc, 0, sizeof(lcddev_t));if (probe){/* 根据probe信息初始化设备管理结构体softc */softc->rotation = probe->rotation;softc->bpp = probe->bpp;softc->width = probe->width;softc->height = probe->height;softc->pitch = probe->width * NBYTES(probe->bpp);softc->bg_color = probe->bg_color;softc->fg_color = probe->fg_color;softc->base = probe->base;debug("fb range: [0x%08x - 0x%08x]\n", softc->base, (char *)softc->base + softc->pitch * softc->height);/* 定义显示的console子窗口 */if (probe->win.w == 0 || probe->win.h == 0){/* construt a default window */memset(&win, 0, sizeof(win));win.w = probe->width;win.h = probe->height;}else{/* preset window */memcpy(&win, &probe->win, sizeof(win));}/* 初始化console */fbcon_init(&softc->con, &win, softc);/* ...其它操作... *//* 更新设备描述信息,用于show devices命令显示 *//* description */xsprintf(descr, "%s at 0x%08x, size [%d,%d,%d,%d]",drv->drv_description, softc->base,win.x, win.y, win.x + win.w, win.y + win.h);/* 添加设备到cfe的设备管理队列 */cfe_attach(drv, softc, NULL, descr);/** 各项结构体初始化完成后调用bvn_init初始化显示相关寄存器* 完成后输出的格式就确定下来了*//* call init */init = (bvn_init *)probe_a;if (init != NULL){/* reg, heap, surface */init(NULL, NULL, softc->base);}/* 清理显存区域,可用于显示默认的logo图像或提示信息 *//* clear whole screen with background color */lcd_clear(softc);}}return;
}
  • ldcdrv_dispatch

结构体lcddrv的成员lcddrv_dispatch链接了lcd设备的各种操作接口,当上层调用文件系统接口cfe_opencfe_closecfe_read, cfe_write, cfe_ioctl时,具体操作由lcddrv_displath链接的函数来执行。
如果支持所有操作,需要实现以下接口:

>
- int (*dev_open)(cfe_devctx_t *ctx)
- int (*dev_read)(cfe_devctx_t *ctx,iocb_buffer_t *buffer)
- int (*dev_inpstat)(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat)
- int (*dev_write)(cfe_devctx_t *ctx,iocb_buffer_t *buffer)
- int (*dev_ioctl)(cfe_devctx_t *ctx,iocb_buffer_t *buffer)
- int (*dev_close)(cfe_devctx_t *ctx)
- void (*dev_poll)(cfe_devctx_t *ctx,int64_t ticks)
- void (*dev_reset)(void *softc)

由于lcd只支持简单的输出显示,这里只实现了open, writeclose接口,可以根据需要进一步丰富lcd的操作。

  • lcddrv_open
static int lcddrv_open(cfe_devctx_t *ctx)
{lcddev_t *lcd = ctx->dev_softc;fbcon_set_cursor(&lcd->con, 0, 0);return 0;
}

应用操作调用cfe_open时会被转发到这里的lcddrv_open来,open时调用fbcon_set_cursor设置字符输出的起始位置。

  • lcddrv_write
static int lcddrv_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer)
{lcddev_t *lcd = ctx->dev_softc;fbcon_t *con = &lcd->con;unsigned char *bptr;int blen;bptr = buffer->buf_ptr;blen = buffer->buf_length;while ( blen > 0 ){fbcon_putc(con, *bptr);bptr++;blen--;}buffer->buf_retlen = buffer->buf_length - blen;lcd_sync(lcd);return 0;
}

应用操作调用cfe_write时会被转发到这里的lcddrv_write来,write操作只是调用fbcon_putc来逐个输出缓冲区的字符。

CFE串口输出的是xterm格式,但这里原样逐个输出字符,实际上还需要在调用fbcon_putc前过滤处理转意字符,此处略去实现。

  • lcddrv_close
static int lcddrv_close(cfe_devctx_t *ctx)
{return 0;
}

应用操作调用cfe_close时会被转发到这里的lcddrv_write来,close操作需要处理open时打开的一些资源,但由于open并没有分配额外的资源,这里的close就没有做任何操作。

  • 其它

    • 应用操作调用cfe_ioctl来进行一些额外的设置,如清屏,指定输出位置,指定输出颜色等,这部分操作可以通过定义lcddrv_ioctl来扩展。
    • 如果定义了pull操作,则cfe会在background任务中通过PULL操作来实现一些定期的任务,例如这里可以定义lcddrv_poll来实现光标的显示。

3.5 显示内容管理

fbcon.c实现了显示内容的管理,主要围绕显示内容的更新操作,例如屏幕滚动,特殊字符的输出等。

  • fbcon_set_cursor
void fbcon_set_cursor(fbcon_t *con, int32_t row, int32_t col)
{con->cur_row = min(row, con->rows - 1);con->cur_col = min(row, con->cols - 1);return;
}

fbcon_set_cursor根据传入的参数设置当前的输出位置。

  • fbcon_putc_xy
static void fbcon_putc_xy(fbcon_t *con, uint32_t x, uint32_t y, char c)
{lcddev_t *lcd;uint32_t bg_color, fg_color;int i, row;fbptr_t *dst;lcd = con->lcd;bg_color = lcd->bg_color;fg_color = lcd->fg_color;dst = (fbptr_t *)con->start + y * lcd->width + x;for (row=0; row<VIDEO_FONT_HEIGHT; row++){uint8_t bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];for (i=0; i<VIDEO_FONT_WIDTH; i++){*dst++ = (bits & 0x80) ? fg_color : bg_color;bits <<= 1;}dst += (lcd->width - VIDEO_FONT_WIDTH);}return;
}

fbcon_putc_xy根据传入的位置参数和字符,从字库数据中获取对应字符的点阵并输出到屏幕上。

  • fbcon_moverow
static void fbcon_moverow(fbcon_t *con, uint32_t rowdst, uint32_t rowsrc)
{lcddev_t *lcd = con->lcd;int i;fbptr_t *src, *dst;/** Note: this only works in full screen console*/dst = (fbptr_t *)con->start + rowdst * VIDEO_FONT_HEIGHT * lcd->width;src = (fbptr_t *)con->start + rowsrc * VIDEO_FONT_HEIGHT * lcd->width;for (i=0; i<(VIDEO_FONT_HEIGHT * lcd->width); i++){*dst++ = *src++;}return;
}

fbcon_moverow实现行复制,将指定的rowsrc行复制到rowdst行上。

  • fbcon_setrow
static void fbcon_setrow(fbcon_t *con, uint32_t row, uint32_t color)
{lcddev_t *lcd = con->lcd;int32_t i;fbptr_t *dst;/** Note: this only works in full screen console*/dst = (fbptr_t *)con->start + row * VIDEO_FONT_HEIGHT * lcd->width;for (i=0; i<(VIDEO_FONT_HEIGHT * lcd->width); i++){*dst++ = color;}return;
}

fbcon_setrow使用指定的颜色color将制定的row行清空。

  • fbcon_back
static void fbcon_back(fbcon_t *con)
{if (--con->cur_col < 0){con->cur_col = con->cols - 1;if (--con->cur_row < 0){con->cur_row = 0;}}con->putc_xy(con,con->cur_col * VIDEO_FONT_WIDTH,con->cur_row * VIDEO_FONT_HEIGHT,' ');return;
}

fbcon_back实现退格键’\b’的效果(光标往前移动一个位置,并将当前光标位置设置为空白)。

  • fbcon_newline
static void fbcon_newline(fbcon_t *con)
{lcddev_t *lcd = con->lcd;const int rows = CONSOLE_SCROLL_LINES;uint32_t i, bg_color = lcd->bg_color;con->cur_col = 0;/* Check if we need to scroll to the terminal */if (++con->cur_row >= con->rows){for (i=0; i<con->rows-rows; i++)con->moverow(con, i, i+rows);for (i=0; i<rows; i++)con->setrow(con, con->rows-i-1, bg_color);con->cur_row -= rows;}
}

fbcon_newline调整光标位置,实现换行输出,如果换行的时候需要滚动屏幕,则还需要实现滚动屏幕的效果。

  • fbcon_putc
void fbcon_putc(fbcon_t *con, const char c)
{switch(c){case '\r':con->cur_col = 0;break;case '\n':fbcon_newline(con);break;case '\t': /* Tab (8 chars alignment) */con->cur_col += 8;con->cur_col &= ~7;if (con->cur_col >= con->cols)fbcon_newline(con);break;case '\b':fbcon_back(con);break;default:con->putc_xy(con,con->cur_col * VIDEO_FONT_WIDTH,con->cur_row * VIDEO_FONT_HEIGHT,c);if (++con->cur_col >= con->cols)fbcon_newline(con);break;}return;
}

fbcon_putc在屏幕的当前位置输出指定的字符,是整个fbcon的字符输出接口,实现了退格、换行和制表等功能。

  • fbcon_init
void fbcon_init(fbcon_t *con, win_t *win, lcddev_t *lcd)
{con->x = win->x;con->y = win->y;con->w = win->w;con->h = win->h;con->cols = win->w / VIDEO_FONT_WIDTH;con->rows = win->h / VIDEO_FONT_HEIGHT;con->cur_col = 0;con->cur_row = 0;con->putc_xy = fbcon_putc_xy;con->moverow = fbcon_moverow;con->setrow = fbcon_setrow;con->start = (char *)lcd->base + (win->y * lcd->width + win->x) * NBYTES(lcd->bpp); /* console buffer maybe not continous */con->cmap = NULL;con->lcd = lcd;return;
}

fbcon_init根据传入的位置参数和lcddev_t参数初始化fbcon_t结构体。

3.6 显示的初始化和调用

1. 显示的初始化
  • cfe_lcd_init

cfe_min.c文件中定义一个cfe_lcd_init函数,用于lcd设备的初始化:

/* 导入相关头文件 */
#include "dev_lcd.h"
#include "splash_script_load.h"extern cfe_driver_t lcddrv;/* 定义lcd设备的全局handle */
int hLcd = -1;
static void cfe_lcd_init(void)
{lcd_probe_t probe;memset(&probe, 0, sizeof(lcd_probe_t));probe.rotation = 0;probe.bpp = LCD_COLOR16;splash_get_surf_dimensions(&probe.width, &probe.height);probe.bg_color = CONSOLE_COLOR_BLACK;probe.fg_color = CONSOLE_COLOR_WHITE;/* console layout */probe.win.x = 0;probe.win.y = 0;probe.win.w = probe.width;probe.win.h = probe.height;//splash_get_surf_address(&probe.base, &pitch);probe.base = (void *)PHYS_TO_K0(SURFACE_MEM_ADDRS);/* 添加lcd设备 */cfe_add_device(&lcddrv, (unsigned long)&splash_bvn_init, NULL, &probe);/* 打开添加的设备并保存设备handle到全局变量hLcd中 */hLcd = cfe_open("lcd0");if (hLcd < 0) {xprintf("cannot open lcd0\n");return;}return;
}
  • cfe_main

在函数cfe_main中,串口初始化后随即初始化lcd设备,以确保lcd能够输跟串口一样的信息而不会遗漏。

void cfe_main(int a,int b)
{.../** Initialize the console.  It is done before the other devices* get turned on.  The console init also sets the variable that* contains the CPU speed.*/console_init();/* init lcd console */cfe_lcd_init();...
}
2. 显示输出调用

在串口输出的同时,根据初始化打开的hLcd句柄,调用cfe_write将内容输出到lcd上:

extern int hLcd;
int console_write(unsigned char *buffer,int length)
{.../** Do nothing if no console*/if (console_handle == -1) return -1;/** Write text to device*/for (;;) {res = cfe_write(console_handle,buffer,length);if (hLcd != -1)cfe_write(hLcd, buffer, length);...}if (res < 0) return -1;return 0;            
}

自此,当串口进行输出时,同时会将这些内容送往lcd显示。

4. 其它

此版本的cfe中,HDMI默认的输出格式为PAL制的576p(即分辨率为720x576),如果需要更改为其它格式,如720P,1080i或VESA格式,则需要根据Broadcom的SDK中splashgen工具生成对应格式的显示寄存器再应用到cfe中。

最新的cfe中,splash显示部分有些变化,会针对高标清分别输出,所以在获取surface参数时有些不同,如果将这里的代码移植到最新的cfe上,需要对调用splash_get_surf_xxx函数进行调整。具体有如下几个函数:

  • splash_get_surf_dimensions
  • splash_bvn_init
  • splash_get_surf_format

由于博通MIPS平台机顶盒引导程序CFEARM平台的引导程序BOLT的设备管理操作和结构是一致的,所以也很容易将这部分代码实现移植到上BOLT上。BOLT采用device treelinux传递参数,这点跟CFE采用环境变量传递参数不一样,所以BOLT上还需要将一些lcd参数更新到device tree`中

5. patch

针对bcm97583 cfe v3.7版本的patch代码下载:bcm97584_cfe_v3.7-framebuffer.patch

这篇关于博通机顶盒平台framebuffer输出(一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/164172

相关文章

流媒体平台/视频监控/安防视频汇聚EasyCVR播放暂停后视频画面黑屏是什么原因?

视频智能分析/视频监控/安防监控综合管理系统EasyCVR视频汇聚融合平台,是TSINGSEE青犀视频垂直深耕音视频流媒体技术、AI智能技术领域的杰出成果。该平台以其强大的视频处理、汇聚与融合能力,在构建全栈视频监控系统中展现出了独特的优势。视频监控管理系统EasyCVR平台内置了强大的视频解码、转码、压缩等技术,能够处理多种视频流格式,并以多种格式(RTMP、RTSP、HTTP-FLV、WebS

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

如何解决线上平台抽佣高 线下门店客流少的痛点!

目前,许多传统零售店铺正遭遇客源下降的难题。尽管广告推广能带来一定的客流,但其费用昂贵。鉴于此,众多零售商纷纷选择加入像美团、饿了么和抖音这样的大型在线平台,但这些平台的高佣金率导致了利润的大幅缩水。在这样的市场环境下,商家之间的合作网络逐渐成为一种有效的解决方案,通过资源和客户基础的共享,实现共同的利益增长。 以最近在上海兴起的一个跨行业合作平台为例,该平台融合了环保消费积分系统,在短

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

【区块链 + 人才服务】区块链集成开发平台 | FISCO BCOS应用案例

随着区块链技术的快速发展,越来越多的企业开始将其应用于实际业务中。然而,区块链技术的专业性使得其集成开发成为一项挑战。针对此,广东中创智慧科技有限公司基于国产开源联盟链 FISCO BCOS 推出了区块链集成开发平台。该平台基于区块链技术,提供一套全面的区块链开发工具和开发环境,支持开发者快速开发和部署区块链应用。此外,该平台还可以提供一套全面的区块链开发教程和文档,帮助开发者快速上手区块链开发。

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

顺序表之创建,判满,插入,输出

文章目录 🍊自我介绍🍊创建一个空的顺序表,为结构体在堆区分配空间🍊插入数据🍊输出数据🍊判断顺序表是否满了,满了返回值1,否则返回0🍊main函数 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以:点赞+关注+评论+收藏(一键四连)哦~ 🍊自我介绍   Hello,大家好,我是小珑也要变强(也是小珑),我是易编程·终身成长社群的一名“创始团队·嘉宾”

衡石分析平台使用手册-单机安装及启动

单机安装及启动​ 本文讲述如何在单机环境下进行 HENGSHI SENSE 安装的操作过程。 在安装前请确认网络环境,如果是隔离环境,无法连接互联网时,请先按照 离线环境安装依赖的指导进行依赖包的安装,然后按照本文的指导继续操作。如果网络环境可以连接互联网,请直接按照本文的指导进行安装。 准备工作​ 请参考安装环境文档准备安装环境。 配置用户与安装目录。 在操作前请检查您是否有 sud

业务协同平台--简介

一、使用场景         1.多个系统统一在业务协同平台定义协同策略,由业务协同平台代替人工完成一系列的单据录入         2.同时业务协同平台将执行任务推送给pda、pad等执行终端,通知各人员、设备进行作业执行         3.作业过程中,可设置完成时间预警、作业节点通知,时刻了解作业进程         4.做完再给你做过程分析,给出优化建议         就问你这一套下