物流设备管理系统界面
一、 设计介绍 ....................................................................................................................................................................................... 2
1.1 设计目的 .................................................................................................................................................................................. 2 1.2 课题分析 .................................................................................................................................................................................. 2 二、 系统硬件模块 ............................................................................................................................................................................... 3
2.1 S5PV210 ..................................................................................................................................................................................... 3 三、 系统软件 ....................................................................................................................................................................................... 4
3.1 操作系统 .................................................................................................................................................................................. 4 3.2 编译工具 .................................................................................................................................................................................. 4 四、 模块划分 ....................................................................................................................................................................................... 5
4.1主界面模块 ............................................................................................................................................................................... 5
4.1.1 功能描述 ....................................................................................................................................................................... 5 4.1.2 程序代码 ....................................................................................................................................................................... 5 4.2 wifi设备模块 ............................................................................................................................................................................ 9
4.2.1 功能描述 ....................................................................................................................................................................... 9 4.2.2 程序代码 ..................................................................................................................................................................... 10
五、 结束语 ......................................................................................................................................................................................... 15 六、 附录 ............................................................................................................................................................................................. 17 6.1 设备管理完整代码 ........................................................................................................................................................................ 17
.
.
广 西 科 技 大 学
课 程 设 计 报 告
设 计 名 称: 物流设备界面管理系统
专 业 班 级: 自动化142
学 生 姓 名:
学 生 学 号:
指 导 教 师:
设 计 时 间: 2016.11
一、设计介绍
1.1 设计目的
此次课程设计是基于s5pv210芯片在linux系统上进行编程设计。旨在通过具体的工程项目实训能够使我们基本掌握在虚拟机环境下,运用linux系统指令进行程序设计与编写;理解模块化的设计思想以及学会利用库函数进行编程;熟知函数之间的封装,调用与API接口。为将来进行大规模的系统设计与开发打下良好基础。
1.2 课题分析
.
.
课题名称为“物流设备界面管理系统”,具体分为4大模块:Wife设备管理,Camrea设别管理,Zigbee设备管理以及RFID管理。希望能够通过编程实现每个设备的借还记录管理,方便仓库管理人员对设备的管理与维护。具体描述为,当从仓库中向外借出设备时,该设备的数量减一;反之数量加一。如此,可大大减轻相关人员的工作量,实现设备的自动化管理。
二、系统硬件模块
由于此次设计是由校企合作和培训机构导师进行讲解,于是我们硬件模块用到了S5PV210的开发板。一下详细介绍这块芯片以及我们系统使用到开发板的相应功能模块。
2.1 S5PV210
S5PV210采用了ARM CortexTM-A8内核,ARM V7指令集,主频可达1GHZ,64/32位内部总线结构,32/32KB的数据/指令一级缓存,512KB的二级缓存,可以实现2000DMIPS(每秒运算2亿条指令集)的高性能运算能力。S5PV210包含很多强大的硬件编解码功能,内建MFC(Multi Format Codec),支持MPEG-1/2/4,H.263,H.264等格式视频的编解码,支持模拟/数字TV输出。JPEG硬件编解码,最大支持8000x8000分辨率,内建高性能PowerVR SGX540 3D图形引擎和2D图形引擎,支持2D/3D图形加速,是第五代PowerVR产品,其多边形生成率为2800万多边形/秒,像素填充率可达2.5亿/秒,在3D和多媒体方面比以往大幅提升,能够支持DX9,SM3.0,OpenGL2.0等PC级别显示技术。具备IVA3硬件加速器,具备出色的图形解码性能,可以支持全高清、多标准的视频编码,流畅播放和录制30帧/秒的1920×1080像素(1080p)的视频文件,可以更快解码更高质量的图像和视频,同时,内建的HDMIv1.3,可以将高清视频输出到外部显示器上。
此次设计我们主要用到了一下模块:LCD屏幕显示,触摸板,以及摄像头等模块。
.
.
三、系统软件
3.1 操作系统
这次设计选择了linux作为操作系统。Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的UNIX工具软件、应用程序和网络协议。它支持32位和64位硬件。Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。Linux同时具有字符界面和图形界面。在字符界面用户可以通过键盘输入相应的指令来进行操作。它同时也提供了类似Windows图形界面的X-Window系统,用户可以使用鼠标对其进行操作。在X-Window环境中就和在Windows中相似,可以说是一个Linux版的Windows。Linux可以运行在多种硬件平台上,如具有x86、680x0、SPARC、Alpha等处理器的平台。此外Linux还是一种嵌入式操作系统,可以运行在掌上电脑、机顶盒或游戏机上。2001年1月份发布的Linux 2.4版内核已经能够完全支持Intel 64位芯片架构。同时Linux也支持多处理器技术。多个处理器同时工作,使系统性能大大提高。
3.2 编译工具
因为装了ubantu的虚拟机所以采用了交叉编译,编译工具为gcc。GCC的外部接口长得像一个标准的Unix编译器。使用者在命令列下键入gcc之程序名,以及一些命令参数,以便决定每个输入档案使用的个别语言编译器,并为输出程序码使用适合此硬件平台的组合语言编译器,并且选择性地执行连接器以制造可执行的程序。每个语言编译器都是独立程序,此程序可处理输入的原始码,并输出组合语言码。全部的语言编译器都拥有共通的中介架构:一个前端解析符合此语言的原始码,并产生一抽象语法树,以及一翻译此语法树成为GCC的暂存器转换语言〈RTL〉的后端。编译器最佳化与静态程序码解析技术(例如FORTIFY_SOURCE,一个试
.
.
图发现缓冲区溢位〈buffer overflow〉的编译器)在此阶段应用于程序码上。最后,适用于此硬件架构的组合语言程序码以Jack Davidson与Chris Fraser发明的算法产出。几乎全部的GCC都由C写成,除了Ada前端大部分以Ada写成。
四、模块划分
4.1主界面模块
4.1.1 功能描述
主界面主要是调用了LCD屏幕显示相关机构及开发人员的详细信息,并附上属于自己的Logo。具体编程思路为:首先对LCD屏幕进行配置,相关的参数可以通过库函数进行修改;显示自己制作的Logo图片;通过循环输出每个像素点。
4.1.2 程序代码
#include #include #include #include #include . . #include #include #include \"tslib.h\" #define TS_DEV \"/dev/event0\" #define LCD_DEV \"/dev/fb0\" int lcd_init(void) { //void *则为“无类型指针”,void *可以指向任何类型的数据 g_lcd_fd = open(\"/dev/fb0\ //打开屏幕 g_fd_men=(unsignedlong*)mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED, g_lcd_fd,0); //强制转换为无符号长整型指针 if(g_fd_men == NULL) . . { printf(\"mmap g_fd_men failed!\\n\"); return -1; } return 0; } int show_shape(unsigned long *g_fd_men,int x,int *pathname) { int bmp_fd,i,j; char bmp_buffer[w*h*3]; int lcd_buffer[w*h]; bmp_fd = open(pathname,O_RDONLY);//图片首地址 if(bmp_fd == -1) . y,int w,int h,const char . { printf(\"open failed!\\n\"); return -1; } lseek(bmp_fd,54,SEEK_SET); read(bmp_fd,bmp_buffer,sizeof(bmp_buffer)); for(i=0;i lcd_buffer[i] = bmp_buffer[3*i] | bmp_buffer[3*i+1]<<8 | bmp_buffer[3*i+2]<<16; } for(i=0;i . . *(g_fd_men+(y+i)*800+x+j) = lcd_buffer[(h-1-i)*w+j]; } close(bmp_fd); return 0; } show_wifi_number(int x,int y,int wifi) { int fd; char buffer[1]; show_shape(g_fd_men,x,y,72,72,bmp[wifi]); } 4.2 wifi设备模块 4.2.1 功能描述 . . 此模块主要实现,wifi设备的数量管理以及语音提示相关操作人员的误操作。涉及到的有图片处理用于显示当前数量以及相关按键;语音提示数量已达上下限。 4.2.2 程序代码 void wifi(void) { //显示wifi设备主页 show_shape(g_fd_men,0,0,800,480,\"wifi.bmp\"); //显示wifi初始值 //show_shape(g_fd_men,540,18,118,118,\"5.bmp\"); //wifi数量初值 int wifi=wifi_init; bai = wifi/100; shi = wifi%100/10; ge = wifi%100%10; . . show_wifi_number(512,33,bai); show_wifi_number(602,33,shi);//x+20 show_wifi_number(692,33,ge); //进行坐标扫描 while(1) { //扫描是不是有触摸按下,读坐标的值 ts_read(ts, &samp, 1); if(samp.x>345&&samp.x<458&&samp.y>230&&samp.y<317&&(samp.pressure>0)){ system(\"madplay city_in_sky.mp3 -r &\"); } if(samp.x>29&&samp.x<110&&samp.y>391&&samp.y<461&&(samp.pressure>0)){ . . system(\"killall -9 madplay city_in_sky.mp3\"); } if(samp.x>28 && samp.x<170 && samp.y>200 && samp.y<275 && (samp.pressure>0)) { if(wifi>0){ wifi--; bai = wifi/100; shi = wifi%100/10; ge = wifi%100%10; show_wifi_number(512,33,bai); show_wifi_number(602,33,shi);//x+20 show_wifi_number(692,33,ge); . . } else{ // system(\"killall -STOP madplay city_in_sky.mp3 &\"); //暂停 system(\"madplay wifi1.mp3 &\"); // system(\"killall -CONT madplay city_in_sky.mp3 &\"); } } if(samp.x>630 && samp.x<770 && samp.y>200 && samp.y<275 && (samp.pressure>0)) { { //while(wifi<1000){ if(wifi<10){ . . bai = wifi/100; shi = wifi%100/10; ge = wifi%100%10; show_wifi_number(512,33,bai); show_wifi_number(602,33,shi);//x+20 show_wifi_number(692,33,ge); wifi++; } else{ // system(\"killall -STOP madplay city_in_sky.mp3 &\"); system(\"madplay wifi2.mp3 &\"); // system(\"killall -CONT madplay city_in_sky.mp3 &\"); } . . } if(samp.x>490 && samp.x<780 && samp.y>360 && samp.y<442 && (samp.pressure>0)) { show_shape(g_fd_men,0,0,800,480,\"index.bmp\"); break; } } 剩余三个模块与wifi设备管理大同小异,限于篇幅,不做多余描述,具体代码至附录中进行查阅。 五、结束语 通过此次课程设计我知道了设计是一个把需求分析、程序编写、程序调试、撰写报告结合为一体的过程。在这个过程中,不仅锻炼了我们缜密的思维和坚持不解的毅力,更磨练了一个队伍的团结互助的精神。只有通过大家一起努力才能将课程设计的所有环节都顺利的完成。另外程序设计中我们遇到问题并解决问题的过程,使得我们独自探索并解决问题的能力了有了一个提高,这有利于我们以后的学习。同时这整一个过程,也使我们对程序编写的整个过程有了 . . 一个统筹全局的思想,因为需求分析、程序编写、程序调试、撰写报告这些过程是环环相扣的,绝对不可能独立进行。 课程设计是学习《C程序设计》后对知识的全面测试,刚拿到题目时不知道怎么去处理,觉得很复杂,经过和小组成员的讨论,上网查资料,逐个问题逐个击破,问题不再那么复杂。通过课程设计,我发现自己还存在很多知识漏洞,编写程序时,经常会出现低级错误,很多知识点都不熟悉。在今后的时间里,我一定要投入更多精力学习C语言,以课本为基础,请教老师,与同学讨论努力将课堂上的内容与实践融为一体。 . . 六、附录 6.1 设备管理完整代码 #include #include #include #include #include #include #include #include \"tslib.h\" #define TS_DEV \"/dev/event0\" #define LCD_DEV \"/dev/fb0\" //打开屏幕 #define wifi_init 5 . . #define camrea_init 5 #define zigbee_init 5 #define rfid_init 5 struct tsdev *ts; struct ts_sample samp; unsigned long *g_fd_men; //得到的地址不变 int g_lcd_fd; int ge,shi,bai; char bmp[10][6]={\"0.bmp\bmp\ //初始化屏幕 int lcd_init(void) { . . //void *则为“无类型指针”,void *可以指向任何类型的数据 g_lcd_fd = open(\"/dev/fb0\ //打开屏幕 g_fd_men=(unsignedlong*)mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED, g_lcd_fd,0); //强制转换为无符号长整型指针 if(g_fd_men == NULL) { printf(\"mmap g_fd_men failed!\\n\"); return -1; } return 0; } //解除映射 . . int lcd_uninit(void) { munmap(g_fd_men,800*480*4);//该调用在进程地址空间中解除一个映射关系,addr是调用mmap()时返回的地址, //len是映射区的大小。当映射关系解除后,对原来映射地址的访问将导致段错误发生。 } /*unsigned long *g_fd_men 映射的起始地址 *int x 控件起始坐标x *int y 控件起始坐标y *int w 控件的宽 *int h 控件的高 *int color 控件的颜色 * . . */ //open(const char *pathname,int flags) //图片处理 int show_shape(unsigned long *g_fd_men,int x,int *pathname) { int bmp_fd,i,j; char bmp_buffer[w*h*3]; int lcd_buffer[w*h]; bmp_fd = open(pathname,O_RDONLY);//图片首地址 if(bmp_fd == -1) { printf(\"open failed!\\n\"); return -1; . y,int w,int h,const char . } lseek(bmp_fd,54,SEEK_SET); read(bmp_fd,bmp_buffer,sizeof(bmp_buffer)); for(i=0;i lcd_buffer[i] = bmp_buffer[3*i] | bmp_buffer[3*i+1]<<8 | bmp_buffer[3*i+2]<<16; } for(i=0;i *(g_fd_men+(y+i)*800+x+j) = lcd_buffer[(h-1-i)*w+j]; } close(bmp_fd); . . return 0; } int show_wifi_number(int x,int y,int wifi) { /*int fd; char buffer[1]; //打开存储WIFI设备的文件 fd = open(\"wifi\打开 if(fd == -1) { printf(\"open wifi failure\\n\"); return -1; } . . //从文件WIFI中读取出数量,并存储在数据中 read(fd,buffer,sizeof(buffer)); //从文件中读出来的为字符 //读取到的值为字符类型 printf(\"buffer = %c\\n\ wifi_number = buffer[0]-48; */ show_shape(g_fd_men,x,y,72,72,bmp[wifi]); //close(fd); } void wifi(void) { //显示wifi设备主页 show_shape(g_fd_men,0,0,800,480,\"wifi.bmp\"); . . //显示wifi初始值 //show_shape(g_fd_men,540,18,118,118,\"5.bmp\"); //wifi数量初值 int wifi=wifi_init; bai = wifi/100; shi = wifi%100/10; ge = wifi%100%10; show_wifi_number(512,33,bai); show_wifi_number(602,33,shi);//x+20 show_wifi_number(692,33,ge); //进行坐标扫描 while(1) { . . //扫描是不是有触摸按下,读坐标的值 ts_read(ts, &samp, 1); if(samp.x>345&&samp.x<458&&samp.y>230&&samp.y<317&&(samp.pressure>0)){ system(\"madplay city_in_sky.mp3 -r &\"); } if(samp.x>29&&samp.x<110&&samp.y>391&&samp.y<461&&(samp.pressure>0)){ system(\"killall -9 madplay city_in_sky.mp3\"); //system(\"killall -STOP madplay &\"); } //借坐标 if(samp.x>28 && samp.x<170 && samp.y>200 && samp.y<275 && (samp.pressure>0)) . . { if(wifi>0){ wifi--; bai = wifi/100; shi = wifi%100/10; ge = wifi%100%10; show_wifi_number(512,33,bai); show_wifi_number(602,33,shi);//x+20 show_wifi_number(692,33,ge); } else{ // system(\"killall -STOP madplay city_in_sky.mp3 &\"); //暂停 system(\"madplay wifi1.mp3 &\"); . . // system(\"killall -CONT madplay city_in_sky.mp3 &\"); } } // //还坐标 if(samp.x>630 && samp.x<770 && samp.y>200 && samp.y<275 && (samp.pressure>0)) { //while(wifi<1000){ if(wifi<10){ bai = wifi/100; shi = wifi%100/10; ge = wifi%100%10; . . show_wifi_number(512,33,bai); show_wifi_number(602,33,shi);//x+20 show_wifi_number(692,33,ge); wifi++; } else{ // system(\"killall -STOP madplay city_in_sky.mp3 &\"); system(\"madplay wifi2.mp3 &\"); // system(\"killall -CONT madplay city_in_sky.mp3 &\"); } } //返回目录坐标 if(samp.x>490 && samp.x<780 && samp.y>360 . . && samp.y<442 && (samp.pressure>0)) { show_shape(g_fd_men,0,0,800,480,\"index.bmp\"); break; } } } int show_camrea_number(int x,int y,int camrea) { show_shape(g_fd_men,x,y,72,72,bmp[camrea]); } //camrea void camrea(void) . . { int camrea=camrea_init; bai = camrea/100; shi = camrea%100/10; ge = camrea%100%10; show_shape(g_fd_men,0,0,800,480,\"camrea.bmp\"); show_camrea_number(472,59,bai); show_camrea_number(572,59,shi);//x+30 show_camrea_number(672,59,ge); //进行坐标扫描 while(1) { //扫描是不是有触摸按下,读坐标的值 . . ts_read(ts, &samp, 1); if(samp.x>338&&samp.x<467&&samp.y>224&&samp.y<289&&(samp.pressure>0)){ system(\"madplay missing.mp3 -r &\"); } if(samp.x>2&&samp.x<84&&samp.y>391&&samp.y<461&&(samp.pressure>0)){ system(\"killall -9 madplay missing.mp3\"); //system(\"killall -STOP madplay missing.mp3 &\"); } //借坐标 if(samp.x>67 && samp.x<183 && samp.y>229 && samp.y<290 && (samp.pressure>0)) { if(camrea>0){ . . camrea--; bai = camrea/100; shi = camrea%100/10; ge = camrea%100%10; show_camrea_number(472,59,bai); show_camrea_number(572,59,shi);//x+30 show_camrea_number(672,59,ge); } else{ system(\"madplay wifi1.mp3 &\"); } } //还坐标 . . if(samp.x>598 && samp.x<729 && samp.y>229 && samp.y<290 && (samp.pressure>0)) { if(camrea<10){ camrea++; bai = camrea/100; shi = camrea%100/10; ge = camrea%100%10; show_camrea_number(472,59,bai); show_camrea_number(572,59,shi);//x+30 show_camrea_number(672,59,ge); } else{ . . system(\"madplay wifi2.mp3 &\"); } } //返回目录坐标 if(samp.x>512 && samp.x<752 && samp.y>385 && samp.y<442 && (samp.pressure>0)) { show_shape(g_fd_men,0,0,800,480,\"index.bmp\"); break; } } } int show_zigbee_number(int x,int y,int zigbee) . . { show_shape(g_fd_men,x,y,72,72,bmp[zigbee]); } //zigbee void zigbee(void) { show_shape(g_fd_men,0,0,800,480,\"zigbee.bmp\"); int zigbee=zigbee_init; bai = zigbee/100; shi = zigbee%100/10; ge = zigbee%100%10; //show_shape(g_fd_men,529,32,118,118,\"5.bmp\"); show_zigbee_number(510,30,bai); . . show_zigbee_number(610,30,shi);//x+30 show_zigbee_number(710,30,ge); //进行坐标扫描 while(1) { //扫描是不是有触摸按下,读坐标的值 ts_read(ts, &samp, 1); //借坐标 if(samp.x>62 && samp.x<175 && samp.y>216 && samp.y<275 && (samp.pressure>0)) { if(zigbee>0){ zigbee--; . . bai = zigbee/100; shi = zigbee%100/10; ge = zigbee%100%10; show_zigbee_number(510,30,bai); show_zigbee_number(610,30,shi);//x+30 show_zigbee_number(710,30,ge); } else{ system(\"madplay wifi1.mp3 &\"); } } //还坐标 if(samp.x>596 && samp.x<723 && samp.y>216 . . && samp.y<275 && (samp.pressure>0)) { if(zigbee<10){ zigbee++; bai = zigbee/100; shi = zigbee%100/10; ge = zigbee%100%10; show_zigbee_number(510,30,bai); show_zigbee_number(610,30,shi);//x+30 show_zigbee_number(710,30,ge); } else{ system(\"madplay wifi2.mp3 &\"); . . } } //返回目录坐标 if(samp.x>495 && samp.x<740 && samp.y>369 && samp.y<422 && (samp.pressure>0)) { show_shape(g_fd_men,0,0,800,480,\"index.bmp\"); break; } } } int show_rfid_number(int x,int y,int rfid) { . . show_shape(g_fd_men,x,y,72,72,bmp[rfid]); } //rfid void rfid(void) { int rfid=rfid_init; bai = rfid/100; shi = rfid%100/10; ge = rfid%100%10; show_shape(g_fd_men,0,0,800,480,\"rfid.bmp\"); //show_shape(g_fd_men,436,28,118,118,\"5.bmp\"); show_rfid_number(460,36,bai); show_rfid_number(570,36,shi);//x+30 . . show_rfid_number(680,36,ge); //进行坐标扫描 while(1) { //扫描是不是有触摸按下,读坐标的值 ts_read(ts, &samp, 1); //借坐标 if(samp.x>28 && samp.x<155 && samp.y>216 && samp.y<275 && (samp.pressure>0)) { if(rfid>0){ rfid--; bai = rfid/100; . . shi = rfid%100/10; ge = rfid%100%10; show_rfid_number(460,36,bai); show_rfid_number(570,36,shi);//x+30 show_rfid_number(680,36,ge); } else{ system(\"madplay wifi1.mp3 &\"); } } //还坐标 if(samp.x>630 && samp.x<755 && samp.y>216 && samp.y<275 && (samp.pressure>0)) . . { if(rfid<10){ rfid++; bai = rfid/100; shi = rfid%100/10; ge = rfid%100%10; show_rfid_number(460,36,bai); show_rfid_number(570,36,shi);//x+30 show_rfid_number(680,36,ge); } else{ system(\"madplay wifi2.mp3 &\"); } . . } //返回目录坐标 if(samp.x>507 && samp.x<749 && samp.y>374 && samp.y<433 && (samp.pressure>0)) { show_shape(g_fd_men,0,0,800,480,\"index.bmp\"); break; } } } int main(void) { //打开触摸屏 . . ts = ts_open(TS_DEV,0); if(ts == NULL) { printf(\"open ts failure\\n\"); return -1; } //配置触摸屏 int ret = ts_config(ts); if(ret == -1) { printf(\"ts_config failure\\n\"); ts_close(ts); return -1; . . } //初始化屏幕 lcd_init(); //显示logo.bmp show_shape(g_fd_men,0,0,800,480,\"logo.bmp\"); system(\"madplay logo.mp3 &\"); //延时5秒 sleep(6); show_shape(g_fd_men,0,0,800,480,\"index.bmp\"); while(1) //读坐标 { ts_read(ts, &samp, 1); . . printf(\"samp.x = %d,samp.y = %d,samp.pressure = %d\\n\ samp.x,samp.y,samp.pressure); //wifi管理坐标 if(samp.x>56 && samp.x<250 && samp.y>87 && samp.y<141 && (samp.pressure>0)) { system(\"madplay wifi.mp3 &\"); wifi(); system(\"madplay index.mp3 &\"); show_shape(g_fd_men,0,0,800,480,\"index.bmp\"); } //摄像头管理坐标 if(samp.x>512 && samp.x<756 && samp.y>87 . . && samp.y<141 && (samp.pressure>0)) { system(\"madplay camrea.mp3 &\"); camrea(); system(\"madplay index.mp3 &\"); show_shape(g_fd_men,0,0,800,480,\"index.bmp\"); } //zi'g'bee if(samp.x>48 && samp.x<295 && samp.y>311 && samp.y<365 && (samp.pressure>0)) { system(\"madplay zigbee.mp3 &\"); zigbee(); . . system(\"madplay index.mp3 &\"); //show_shape(g_fd_men,0,0,800,480,\"index.bmp\"); } //rfid if(samp.x>550 && samp.x<750 && samp.y>311 && samp.y<365 && (samp.pressure>0)) { system(\"madplay rfid.mp3 &\"); rfid(); system(\"madplay index.mp3 &\"); //show_shape(g_fd_men,0,0,800,480,\"index.bmp\"); } } . . lcd_uninit();//解除映射关系 ts_close(ts);//关闭触摸屏 return 0; } . 因篇幅问题不能全部显示,请点此查看更多更全内容