ARM平台YUV转RGB888(转)
YUV422p To RGB888 C语言版本接口说明:
- /****************************************YUV422P_To_RGB24.c**************************/
- //模块功能:将YUV422_PLANAR图像数据转换成RGB24格式
- typedef unsigned char BYTE; // [0..255]
- /*
- * 接口说明:
- * 功能:构建查询表,转换模块运行前必须进行的初始化操作
- */
- void YUV422P_To_RGB24_init();
- /*
- *接口说明:
- *功能:将YUV422P图像数据转换成RGB24格式
- *参数:
- * pY: YUV422P图像数据Y的起始指针
- * pU: YUV422P图像数据U的起始指针
- * pV: YUV422P图像数据V的起始指针
- * DstPic: 转换成的RGB24图像数据的起始指针
- * width: 图像宽度
- * height: 图像高度
- *返回值:成功返回0,失败返回-1
- *注意:DstPic所指向的缓冲区必须事先分配好,其大小应该为 width*height*3
- */
- int YUV422P_To_RGB24(BYTE* pY, BYTE* pU, BYTE* pV, BYTE* DstPic, int width, int height);
/****************************************YUV422P_To_RGB24.c**************************/ //模块功能:将YUV422_PLANAR图像数据转换成RGB24格式 typedef unsigned char BYTE; // [0..255] /* * 接口说明: * 功能:构建查询表,转换模块运行前必须进行的初始化操作 */ void YUV422P_To_RGB24_init(); /* *接口说明: *功能:将YUV422P图像数据转换成RGB24格式 *参数: * pY: YUV422P图像数据Y的起始指针 * pU: YUV422P图像数据U的起始指针 * pV: YUV422P图像数据V的起始指针 * DstPic: 转换成的RGB24图像数据的起始指针 * width: 图像宽度 * height: 图像高度 *返回值:成功返回0,失败返回-1 *注意:DstPic所指向的缓冲区必须事先分配好,其大小应该为 width*height*3 */ int YUV422P_To_RGB24(BYTE* pY, BYTE* pU, BYTE* pV, BYTE* DstPic, int width, int height);
实现:
- //使用整数运算(定点数运算)来代替浮点运算
- const int csY_coeff_16 = 1.164383 * (1 << 16);
- const int csU_blue_16 = 2.017232 * (1 << 16);
- const int csU_green_16 = (-0.391762) * (1 << 16);
- const int csV_green_16 = (-0.812968) * (1 << 16);
- const int csV_red_16 = 1.596027 * (1 << 16);
- //颜色查表
- static BYTE _color_table[256 * 3];
- static const BYTE* color_table = &_color_table[256];
- //查表
- static int Ym_tableEx[256];
- static int Um_blue_tableEx[256];
- static int Um_green_tableEx[256];
- static int Vm_green_tableEx[256];
- static int Vm_red_tableEx[256];
- //颜色饱和函数
- inline long border_color(long color) {
- if (color > 255)
- return 255;
- else if (color < 0)
- return 0;
- else
- return color;
- }
- //采用查找表进行计算时,必须运行的初始化函数
- void YUV422P_To_RGB24_init() {
- int i;
- for (i = 0; i < 256 * 3; ++i)
- _color_table[i] = border_color(i - 256);
- for (i = 0; i < 256; ++i) {
- Ym_tableEx[i] = (csY_coeff_16 * (i - 16)) >> 16;
- Um_blue_tableEx[i] = (csU_blue_16 * (i - 128)) >> 16;
- Um_green_tableEx[i] = (csU_green_16 * (i - 128)) >> 16;
- Vm_green_tableEx[i] = (csV_green_16 * (i - 128)) >> 16;
- Vm_red_tableEx[i] = (csV_red_16 * (i - 128)) >> 16;
- }
- }
- inline void YUVToRGB24_Table(BYTE *p, const BYTE Y0, const BYTE Y1,
- const BYTE U, const BYTE V) {
- int Ye0 = Ym_tableEx[Y0];
- int Ye1 = Ym_tableEx[Y1];
- int Ue_blue = Um_blue_tableEx[U];
- int Ue_green = Um_green_tableEx[U];
- int Ve_green = Vm_green_tableEx[V];
- int Ve_red = Vm_red_tableEx[V];
- int UeVe_green = Ue_green + Ve_green;
- *p = color_table[(Ye0 + Ve_red)];
- *(p + 1) = color_table[(Ye0 + UeVe_green)];
- *(p + 2) = color_table[(Ye0 + Ue_blue)];
- *(p + 3) = color_table[(Ye1 + Ve_red)];
- *(p + 4) = color_table[(Ye1 + UeVe_green)];
- *(p + 5) = color_table[(Ye1 + Ue_blue)];
- }
- int YUV420P_To_RGB24(BYTE* pY, BYTE* pU, BYTE* pV, BYTE* DstPic, int width,
- int height) {
- int y, x, x_uv;
- BYTE* pDstLine = DstPic;
- if ((width % 2) != 0 || (height % 2) != 0)
- return (-1);
- for (y = 0; y < height; ++y) {
- //DECODE_PlanarYUV211_Common_line(pDstLine, pY, pU, pV,width);
- for (x = 0; x < width; x += 2) {
- x_uv = x >> 1;
- YUVToRGB24_Table(&pDstLine[x * 3], pY[x], pY[x + 1], pU[x_uv],
- pV[x_uv]);
- }
- pDstLine += width * 3; //RGB888
- pY += width; //YUV422
- if (y % 2 == 1) {
- pU += width / 2;
- pV += width / 2;
- }
- }
- return 0;
- }
//使用整数运算(定点数运算)来代替浮点运算 const int csY_coeff_16 = 1.164383 * (1 << 16); const int csU_blue_16 = 2.017232 * (1 << 16); const int csU_green_16 = (-0.391762) * (1 << 16); const int csV_green_16 = (-0.812968) * (1 << 16); const int csV_red_16 = 1.596027 * (1 << 16); //颜色查表 static BYTE _color_table[256 * 3]; static const BYTE* color_table = &_color_table[256]; //查表 static int Ym_tableEx[256]; static int Um_blue_tableEx[256]; static int Um_green_tableEx[256]; static int Vm_green_tableEx[256]; static int Vm_red_tableEx[256]; //颜色饱和函数 inline long border_color(long color) { if (color > 255) return 255; else if (color < 0) return 0; else return color; } //采用查找表进行计算时,必须运行的初始化函数 void YUV422P_To_RGB24_init() { int i; for (i = 0; i < 256 * 3; ++i) _color_table[i] = border_color(i - 256); for (i = 0; i < 256; ++i) { Ym_tableEx[i] = (csY_coeff_16 * (i - 16)) >> 16; Um_blue_tableEx[i] = (csU_blue_16 * (i - 128)) >> 16; Um_green_tableEx[i] = (csU_green_16 * (i - 128)) >> 16; Vm_green_tableEx[i] = (csV_green_16 * (i - 128)) >> 16; Vm_red_tableEx[i] = (csV_red_16 * (i - 128)) >> 16; } } inline void YUVToRGB24_Table(BYTE *p, const BYTE Y0, const BYTE Y1, const BYTE U, const BYTE V) { int Ye0 = Ym_tableEx[Y0]; int Ye1 = Ym_tableEx[Y1]; int Ue_blue = Um_blue_tableEx[U]; int Ue_green = Um_green_tableEx[U]; int Ve_green = Vm_green_tableEx[V]; int Ve_red = Vm_red_tableEx[V]; int UeVe_green = Ue_green + Ve_green; *p = color_table[(Ye0 + Ve_red)]; *(p + 1) = color_table[(Ye0 + UeVe_green)]; *(p + 2) = color_table[(Ye0 + Ue_blue)]; *(p + 3) = color_table[(Ye1 + Ve_red)]; *(p + 4) = color_table[(Ye1 + UeVe_green)]; *(p + 5) = color_table[(Ye1 + Ue_blue)]; } int YUV420P_To_RGB24(BYTE* pY, BYTE* pU, BYTE* pV, BYTE* DstPic, int width, int height) { int y, x, x_uv; BYTE* pDstLine = DstPic; if ((width % 2) != 0 || (height % 2) != 0) return (-1); for (y = 0; y < height; ++y) { //DECODE_PlanarYUV211_Common_line(pDstLine, pY, pU, pV,width); for (x = 0; x < width; x += 2) { x_uv = x >> 1; YUVToRGB24_Table(&pDstLine[x * 3], pY[x], pY[x + 1], pU[x_uv], pV[x_uv]); } pDstLine += width * 3; //RGB888 pY += width; //YUV422 if (y % 2 == 1) { pU += width / 2; pV += width / 2; } } return 0; }
经测试发现,在hi3512(arm 926ej-s,267MHz)平台上运行时,该yuv转rgb模块的速度不是很快,大概20帧/秒。为了提高效率,核心解码模块我采用了arm汇编,重写了YUVToRGB24_Table模块。
YUV420P_To_RGB24_asm.c代码:
- extern int YUVToRGB24_Assemble(unsigned char *pDstLine, unsigned char **yuv, int width);
- //使用整数运算(定点数运算)来代替浮点运算
- const int csY_coeff_16 = 1.164383 * (1 << 16);
- const int csU_blue_16 = 2.017232 * (1 << 16);
- const int csU_green_16 = (-0.391762) * (1 << 16);
- const int csV_green_16 = (-0.812968) * (1 << 16);
- const int csV_red_16 = 1.596027 * (1 << 16);
- //查表
- int Ym_tableEx[256];
- int Um_blue_tableEx[256];
- int Um_green_tableEx[256];
- int Vm_green_tableEx[256];
- int Vm_red_tableEx[256];
- //采用查找表进行计算时,必须运行的初始化函数
- void YUV422P_To_RGB24_init()
- {
- int i;
- for (i = 0; i < 256; ++i)
- {
- Ym_tableEx[i]=(csY_coeff_16 * (i - 16) )>>16;
- Um_blue_tableEx[i]=(csU_blue_16 * (i - 128) )>>16;
- Um_green_tableEx[i]=(csU_green_16 * (i - 128) )>>16;
- Vm_green_tableEx[i]=(csV_green_16 * (i - 128) )>>16;
- Vm_red_tableEx[i]=(csV_red_16 * (i - 128) )>>16;
- }
- }
- int YUV420P_To_RGB24(BYTE* pY, BYTE* pU, BYTE* pV, BYTE* DstPic, int width, int height)
- {
- int y;
- BYTE* pDstLine = DstPic;
- BYTE* yuv[3];
- if ((width % 8)!=0)
- return(-1);
- yuv[0] = pY;
- yuv[1] = pU;
- yuv[2] = pV;
- for (y = height; y > 0; --y)
- {
- YUVToRGB24_Assemble(pDstLine, yuv, width); //decoder a line with asm function in YUVToRGB24_Assemble.s
- pDstLine += width * 3; //RGB888
- yuv[0] += width; //YUV422
- if(y % 2 == 1) {
- yuv[1] += width >> 1;
- yuv[2] += width >> 1;
- }
- }
- return 0;
- }
extern int YUVToRGB24_Assemble(unsigned char *pDstLine, unsigned char **yuv, int width); //使用整数运算(定点数运算)来代替浮点运算 const int csY_coeff_16 = 1.164383 * (1 << 16); const int csU_blue_16 = 2.017232 * (1 << 16); const int csU_green_16 = (-0.391762) * (1 << 16); const int csV_green_16 = (-0.812968) * (1 << 16); const int csV_red_16 = 1.596027 * (1 << 16); //查表 int Ym_tableEx[256]; int Um_blue_tableEx[256]; int Um_green_tableEx[256]; int Vm_green_tableEx[256]; int Vm_red_tableEx[256]; //采用查找表进行计算时,必须运行的初始化函数 void YUV422P_To_RGB24_init() { int i; for (i = 0; i < 256; ++i) { Ym_tableEx[i]=(csY_coeff_16 * (i - 16) )>>16; Um_blue_tableEx[i]=(csU_blue_16 * (i - 128) )>>16; Um_green_tableEx[i]=(csU_green_16 * (i - 128) )>>16; Vm_green_tableEx[i]=(csV_green_16 * (i - 128) )>>16; Vm_red_tableEx[i]=(csV_red_16 * (i - 128) )>>16; } } int YUV420P_To_RGB24(BYTE* pY, BYTE* pU, BYTE* pV, BYTE* DstPic, int width, int height) { int y; BYTE* pDstLine = DstPic; BYTE* yuv[3]; if ((width % 8)!=0) return(-1); yuv[0] = pY; yuv[1] = pU; yuv[2] = pV; for (y = height; y > 0; --y) { YUVToRGB24_Assemble(pDstLine, yuv, width); //decoder a line with asm function in YUVToRGB24_Assemble.s pDstLine += width * 3; //RGB888 yuv[0] += width; //YUV422 if(y % 2 == 1) { yuv[1] += width >> 1; yuv[2] += width >> 1; } } return 0; }
arm汇编核心解码模块:
- .text
- .macro loadu a
- adr r1, UM_BLUE
- ldr r1, [r1]
- ldr r9, [r1, /a, lsl #2]
- adr r1, UM_GREEN
- ldr r1, [r1]
- ldr r10, [r1, /a, lsl #2]
- .endm
- .macro loadv a
- adr r1, VM_RED
- ldr r1, [r1]
- ldr r11, [r1, /a, lsl #2]
- adr r1, VM_GREEN
- ldr r1, [r1]
- ldr r12, [r1, /a, lsl #2]
- .endm
- .macro bound_r0
- cmp r0, #0x00
- movlt r0, #0x00
- cmp r0, #255
- movgt r0, #255
- .endm
- .globl YUVToRGB24_Assemble
- @ r0 = pDstLine; r1 = yuv; r2 = width
- YUVToRGB24_Assemble:
- stmdb sp!, { r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}
- ldmia r1, {r1, r3, r4} @r1 = y; r3 = u; r4 = v;
- mov r5, #0 @r5 = row counter
- hloop:
- ldr r6, [r1], #0x04 @load y; 4 bytes
- ldrh r7, [r3], #0x02 @load u; 2 bytes
- ldrh r8, [r4], #0x02 @load v; 2 bytes
- stmdb sp!, {r0, r1, r2, r3, r4, r5}
- @ temp register: r0,r1 rgbdata: r2,r3,r4
- @ ye:r5 ue_blue:r9 ue_green:r10 ve_red:r11 ve_green:r12
- mov r2, #0
- mov r3, #0
- mov r4, #0
- @ load ue_bule0, ue_green0
- mov r0, r7
- and r0, r0, #0xFF
- loadu r0
- @load ve_red0, ve_green0
- mov r0, r8
- and r0, r0, #0xFF
- loadv r0
- @load ye0
- mov r0, r6
- and r0, r0, #0xFF
- adr r1, YM
- ldr r1, [r1]
- ldr r5, [r1, r0, lsl #2]
- @r0 = ye0+ve_red0
- add r0, r5, r11
- bound_r0
- orr r2, r2, r0
- @g0 = ye0+ue_green0+ve_green0
- adds r0, r10, r12
- adc r0, r0, r5
- bound_r0
- orr r2, r2, r0, lsl #8
- @b0 = ye0+ue_blue0
- add r0, r5, r9
- bound_r0
- orr r2, r2, r0, lsl #16
- @load ye1
- mov r0, r6, lsr #8
- and r0, r0, #0xFF
- ldr r5, [r1, r0, lsl #2]
- @r1 = ye1+ve_red0
- add r0, r5, r11
- bound_r0
- orr r2, r2, r0, lsl #24
- @g1 = ye1+ue_green0+ve_green0
- adds r0, r10, r12
- adc r0, r0, r5
- bound_r0
- orr r3, r3, r0
- @b1 = ye1+ue_blue0
- add r0, r5, r9
- bound_r0
- orr r3, r3, r0, lsl #8
- @ load ue_bule1, ue_green1
- mov r0, r7, lsr #8
- and r0, r0, #0xFF
- loadu r0
- @load ve_red1, ve_green1
- mov r0, r8, lsr #8
- and r0, r0, #0xFF
- loadv r0
- @load ye2
- mov r0, r6, lsr #16
- and r0, r0, #0xFF
- adr r1, YM
- ldr r1, [r1]
- ldr r5, [r1, r0, lsl #2]
- @r2 = ye2+ve_red1
- add r0, r5, r11
- bound_r0
- orr r3, r3, r0, lsl #16
- @g2 = ye2+ue_green1+ve_green1
- adds r0, r10, r12
- adc r0, r0, r5
- bound_r0
- add r3, r3, r0, lsl #24
- @b2 = ye2+ue_blue1
- add r0, r5, r9
- bound_r0
- orr r4, r4, r0
- @load ye3
- mov r0, r6, lsr #24
- and r0, r0, #0xFF
- ldr r5, [r1, r0, lsl #2]
- @r3 = ye3+ve_red1
- add r0, r5, r11
- bound_r0
- orr r4, r4, r0, lsl #8
- @g3 = ye3+ue_green1+ve_green1
- adds r0, r10, r12
- adc r0, r0, r5
- bound_r0
- orr r4, r4, r0, lsl #16
- @b3 = ye3+ue_blue1
- add r0, r5, r9
- bound_r0
- orr r4, r4, r0, lsl #24
- mov r10, r2
- mov r11, r3
- mov r12, r4
- ldmia sp!, {r0, r1, r2, r3, r4, r5}
- stmia r0!, {r10, r11, r12}
- add r5, r5, #4
- cmp r5, r2
- blo hloop
- ldmia sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r12, pc} @exit
- @tables
- YM : .long Ym_tableEx
- UM_BLUE : .long Um_blue_tableEx
- UM_GREEN: .long Um_green_tableEx
- VM_GREEN: .long Vm_green_tableEx
- VM_RED : .long Vm_red_tableEx
.text .macro loadu a adr r1, UM_BLUE ldr r1, [r1] ldr r9, [r1, /a, lsl #2] adr r1, UM_GREEN ldr r1, [r1] ldr r10, [r1, /a, lsl #2] .endm .macro loadv a adr r1, VM_RED ldr r1, [r1] ldr r11, [r1, /a, lsl #2] adr r1, VM_GREEN ldr r1, [r1] ldr r12, [r1, /a, lsl #2] .endm .macro bound_r0 cmp r0, #0x00 movlt r0, #0x00 cmp r0, #255 movgt r0, #255 .endm .globl YUVToRGB24_Assemble @ r0 = pDstLine; r1 = yuv; r2 = width YUVToRGB24_Assemble: stmdb sp!, { r4, r5, r6, r7, r8, r9, r10, r11, r12, lr} ldmia r1, {r1, r3, r4} @r1 = y; r3 = u; r4 = v; mov r5, #0 @r5 = row counter hloop: ldr r6, [r1], #0x04 @load y; 4 bytes ldrh r7, [r3], #0x02 @load u; 2 bytes ldrh r8, [r4], #0x02 @load v; 2 bytes stmdb sp!, {r0, r1, r2, r3, r4, r5} @ temp register: r0,r1 rgbdata: r2,r3,r4 @ ye:r5 ue_blue:r9 ue_green:r10 ve_red:r11 ve_green:r12 mov r2, #0 mov r3, #0 mov r4, #0 @ load ue_bule0, ue_green0 mov r0, r7 and r0, r0, #0xFF loadu r0 @load ve_red0, ve_green0 mov r0, r8 and r0, r0, #0xFF loadv r0 @load ye0 mov r0, r6 and r0, r0, #0xFF adr r1, YM ldr r1, [r1] ldr r5, [r1, r0, lsl #2] @r0 = ye0+ve_red0 add r0, r5, r11 bound_r0 orr r2, r2, r0 @g0 = ye0+ue_green0+ve_green0 adds r0, r10, r12 adc r0, r0, r5 bound_r0 orr r2, r2, r0, lsl #8 @b0 = ye0+ue_blue0 add r0, r5, r9 bound_r0 orr r2, r2, r0, lsl #16 @load ye1 mov r0, r6, lsr #8 and r0, r0, #0xFF ldr r5, [r1, r0, lsl #2] @r1 = ye1+ve_red0 add r0, r5, r11 bound_r0 orr r2, r2, r0, lsl #24 @g1 = ye1+ue_green0+ve_green0 adds r0, r10, r12 adc r0, r0, r5 bound_r0 orr r3, r3, r0 @b1 = ye1+ue_blue0 add r0, r5, r9 bound_r0 orr r3, r3, r0, lsl #8 @ load ue_bule1, ue_green1 mov r0, r7, lsr #8 and r0, r0, #0xFF loadu r0 @load ve_red1, ve_green1 mov r0, r8, lsr #8 and r0, r0, #0xFF loadv r0 @load ye2 mov r0, r6, lsr #16 and r0, r0, #0xFF adr r1, YM ldr r1, [r1] ldr r5, [r1, r0, lsl #2] @r2 = ye2+ve_red1 add r0, r5, r11 bound_r0 orr r3, r3, r0, lsl #16 @g2 = ye2+ue_green1+ve_green1 adds r0, r10, r12 adc r0, r0, r5 bound_r0 add r3, r3, r0, lsl #24 @b2 = ye2+ue_blue1 add r0, r5, r9 bound_r0 orr r4, r4, r0 @load ye3 mov r0, r6, lsr #24 and r0, r0, #0xFF ldr r5, [r1, r0, lsl #2] @r3 = ye3+ve_red1 add r0, r5, r11 bound_r0 orr r4, r4, r0, lsl #8 @g3 = ye3+ue_green1+ve_green1 adds r0, r10, r12 adc r0, r0, r5 bound_r0 orr r4, r4, r0, lsl #16 @b3 = ye3+ue_blue1 add r0, r5, r9 bound_r0 orr r4, r4, r0, lsl #24 mov r10, r2 mov r11, r3 mov r12, r4 ldmia sp!, {r0, r1, r2, r3, r4, r5} stmia r0!, {r10, r11, r12} add r5, r5, #4 cmp r5, r2 blo hloop ldmia sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r12, pc} @exit @tables YM : .long Ym_tableEx UM_BLUE : .long Um_blue_tableEx UM_GREEN: .long Um_green_tableEx VM_GREEN: .long Vm_green_tableEx VM_RED : .long Vm_red_tableEx
将核心模块改成汇编后,解码达到了50帧/秒,效率提高了60%,汇编果然强大,哈哈。
ARM平台YUV转RGB888(转)相关推荐
- QtCreator动态编译jsoncpp完美支持x86和arm平台
如果是做嵌入式开发. 在Qt下支持JSon最好的办法,可能不是采用qjson这个库.QJson这个库的实例只提供了x86环境下的编译方法. Installing QJson ------------- ...
- 微软Win8将有多个版本 四款面向ARM平台
据英特尔高管透露说,微软下一代Windows操作系统(即Windows 8)将有多个版本,当中有四款是针对ARM平台的.英特尔软件部负责人里尼·詹姆斯(Renee James)说,针对英特尔设计的Wi ...
- mysql 客户端 交叉编译_移植mysql到嵌入式ARM平台
移植MySQL到嵌入式ARM平台 MySQL没有专门针对ARM的版本,移植到ARM没有官方文档可参考,因此,暂时参考这样一篇文档: http://blog.chinaunix.net/space.ph ...
- ARM平台下独占访问指令LDREX和STREX的原理与使用详解
为了实现线程间同步,一般都要在执行关键代码段之前加互斥(Mutex)锁,且在执行完关键代码段之后解锁.为了实现所谓的互斥锁的概念,一般都需要所在平台提供支持. 在计算机领域里,如果要在多线程的情况下要 ...
- docker image aarch64 x86_64_「docker」交叉编译适用于ARM平台的Docker源码
前言 docker的编译环境实际是创建了一个docker容器,在docker容器内对代码进行编译.创建该docker容器的过程中,会安装一些编译docker源码需要的第三方库以及go语言环境.此处需要 ...
- 如何在arm平台移植ubuntu系统(转)
linux查看内核版本和发行版本号: https://www.cnblogs.com/guiyishanren/articles/8638921.html 华为开源镜像网站:含有不同平台架构的系统资源 ...
- java7 arm_zynq7000系列移植—JDK1.7 移植到嵌入式ARM平台
今天无意间搜索到 armv7的硬件相关信息--ARM 浮点运算 硬浮点Hard-float 编译器将代码直接编译成发射给硬件浮点协处理器(浮点运算单元FPU)去执行.FPU通常有一套额外的寄存器来完成 ...
- 编译ARM平台的 QtEmbedded 的MySQL插件和移植MySQL到ARM开发板
经过几天的努力,终于交叉编译出了arm平台所需Qt/E的MySQL插件(驱动),其中顺便把MySQL也移植到了mini2410的开发板上. 编译器:arm-linux-gcc(4.3.2) Pc平台: ...
- 4G通信模块在ARM平台下的应用
4G模块是连接物与物的重要载体,是终端设备接入物联网的核心部件之一.随着4G的普及,许多新兴市场对4G通信模块的需求都在日益扩大,那么在ARM平台的嵌入式设备上如何快速的应用4G模块呢? 4G通信模块 ...
最新文章
- 腾讯微博快速有效增加广播转播量的方法与技巧
- Java黑皮书课后题第6章:*6.6(显示图案)编写方法显示如下图案:public static void displayPattern(int n)
- Linux云服务器安装Redis并设置远程连接设置开机自启
- 【渝粤题库】陕西师范大学202801 中国古代文学(五) 作业
- 漫画-Linux中断子系统综述
- 几行代码撸了一天,源码到底该如何读?
- 用python写用手机发邮件_如何用python写发邮件?
- 【管理心得之三】管理者们扪心自问一下 “你们杀了几个属下”
- 超好玩的msn自制动画头像
- 前端测试之用户体验测试
- 嘉禾病历系统服务器,嘉和电子病历系统使用手册-医生工作站
- uniapp实现拨打电话跳转手机拨号盘
- IT行业产品经理和项目经理的区别?
- 【XGBoost】第 7 章:使用 XGBoost 发现系外行星
- IKBC_DC-108 改装,加灯,加锂电池和充电
- qlineedit 获取文本_Python如何获取QLineEdit文本?
- DAMA数据管理知识体系指南之数据安全管理
- 优维EasyOps®全平台又一波新功能上线,操作体验更带劲
- 通过c语言来实现斐波那契数列。斐波那契数列指的是这样一个数列 1, 1, 2, 3, 5, 8, 13...这个数列从第3项开始,每一项都等于前两项之和。
- python_learning_2
热门文章
- VTK:Filtering之ProgrammableFilter
- OpenCV equalizeHist直方图均衡化的实例(附完整代码)
- Qt Creator在属性之间添加绑定
- OpenGL渲染纹理和平面反射
- QT的QNetworkProxy类的使用
- 证书访问_3+证书|高考注册页面可访问,具体流程看这里!
- java——JMM内存模型
- 通过源码的方式编译hadoop的安装文件
- 在Linux上的虚拟机上启动Oracle上报ORA-00845: MEMORY_TARGET not supported on this system的问题解决
- 02_创建Git仓库,克隆仓库,git add,git commit,git push,git pull,同行冲突,不同行冲突的结局方案,git mergetool的使用