课下作业(ucosii、catuserlist、ls实现、stat实现等)-20175204张湲祯
任务一:ucosii
1.任务要求:
- 下载附件,尝试在vc6.0 中编译运行ucos
- 下载附件,尝试在vs2017中编译运行ucos,给出你遇到的问题和解决方式
2.实现
3.遇到的问题:
1.在使用VC时,运行文件后显示无法加载SHSQL.DLL文件,需要重新安装。
2.在点击打开文件后VC闪退。
解决方案:
1.卸载之前的VC,重新安装后可以使用。
2.参考网上教程,插入FileTool.dll 文件后,可以打开文件。
4.任务要求:
阅读附件中的代码,回答:
1.ucos是如何分层的?
2.HAL都有哪些代码?
3.分析任务是如何切换的。
5.实现
1.在代码压缩包中UCOS中有四个文件夹:Config CPU SHELL SOURCE 这些文件应该是用来配置UCOS内核的。
在根据相关知识参考
硬件相关层:有三个重要的接口Open,Close,Ctrl。 Open主要来完成对应硬件初始化。Close失能硬件。Ctrl来实现一些控制的修改如:优先级,中断回调函数等等。
驱动接口层:用到一个或多个硬件层的接口,进行组合来实现特定功能的程序。
应用接口层:主要连接驱动和应用。
应用层:在模块内可以有本模块化共用的主头文件,来方便本模块的维护。对硬件的访问其实直接调用应用接口就可完成。
2.时钟节拍中断服务函数OSTickISR()进行切换,任务中调用时间延迟函数OSTimeDly()进行切换。
任务二:stat命令的实现-mysate
1.任务要求
学习使用stat(1),并用C语言实现
- 提交学习stat(1)的截图
- man -k ,grep -r的使用
- 伪代码
- 产品代码 mystate.c,提交码云链接
- 测试代码,mystat 与stat(1)对比,提交截图
实现步骤:
1.使用man 1 stat
stat命令主要用于显示文件或文件系统的详细信息,stat命令显示的是文件的I节点信息。Linux文件系统以块为单位存储信息,为了找到某一个文件所在存储空间的位置,用I节点对每个文件进行索引,I节点包含了描述文件所必要的全部信息,其中包含了文件的大小,类型,存取权限,文件的所有者。该命令的语法格式如下:
-f:不显示文件本身的信息,显示文件所在文件系统的信息
-L:显示符号链接
-t:简洁模式,只显示摘要信息
2.使用man -k stat | grep 2
可以看出Linux下的stat函数是通过文件名filename获取文件信息,并保存在buf所指的结构体stat中
头文件
#include <sys/stat.h>
#include <unistd.h>
函数int stat(const char *file_name, struct stat *buf );
3.伪代码
由man -k stat | grep 2函数学习后可知调用stat函数实现功能
依次调用函数,打印输出文件名字name,节点ino,文件类型mode,文件的连接数nlink,用户ID uid和组ID gid,块大小blksize,字节数size,块数目blocks,以及三个时间atime、mtime、ctime
4.代码实现
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
struct stat sb;
if (argc != 2) {
fprintf(stderr, "Usage: %s <pathname>\n", argv[0]);
exit(EXIT_FAILURE);
}
if (stat(argv[1], &sb) == -1) {
perror("stat");
exit(EXIT_FAILURE);
}
printf("File type: ");
switch (sb.st_mode & S_IFMT) {
case S_IFBLK: printf("block device\n");
break;
case S_IFCHR: printf("character device\n");
break;
case S_IFDIR: printf("directory\n");
break;
case S_IFIFO: printf("FIFO/pipe\n");
break;
case S_IFLNK: printf("symlink\n");
break;
case S_IFREG: printf("regular file\n");
break;
case S_IFSOCK: printf("socket\n");
break;
default: printf("unknown?\n");
break;
}
printf("name: '%s'\n",argv[1]);
printf("I-node number: %ld\n", (long) sb.st_ino);
printf("Mode: %lo (octal)\n",(unsigned long) sb.st_mode);
printf("Link count: %ld\n", (long) sb.st_nlink);
printf("Ownership: UID=%ld GID=%ld\n",(long) sb.st_uid, (long) sb.st_gid);
printf("Preferred I/O block size: %ld bytes\n",(long) sb.st_blksize);
printf("File size: %lld bytes\n",(long long) sb.st_size);
printf("Blocks allocated: %lld\n",(long long) sb.st_blocks);
printf("Last status change: %s", ctime(&sb.st_ctime));
printf("Last file access: %s", ctime(&sb.st_atime));
printf("Last file modification: %s", ctime(&sb.st_mtime));
exit(EXIT_SUCCESS);
}
5.mystat与stat对比:
任务三:实现ls
1.参考伪代码实现ls的功能,提交代码的编译,运行结果截图,码云代码链接。
1.打开目录文件
2.针对目录文件
3.读取目录条目
4.显示文件名
5.关闭文件目录文件
2.实验代码
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <dirent.h>
int do_ls(char *dir,char *filename,int lflag)
{
int n;
struct stat buf;
char out[100];
struct passwd *pw;
struct group *gr;
struct tm *t;
if(lflag == 0)
{
printf("%s\t",filename);
return 0;
}
if(lstat(dir,&buf)<0)
{
fprintf(stderr,"stat error:%s\n",strerror(errno));
return -1;
}
switch(buf.st_mode & S_IFMT)
{
case S_IFREG:
printf("-");
break;
case S_IFDIR:
printf("d");
break;
case S_IFCHR:
printf("c");
break;
case S_IFBLK:
printf("b");
break;
case S_IFIFO:
printf("p");
break;
case S_IFLNK:
printf("l");
break;
case S_IFSOCK:
printf("s");
break;
}
for(n=8; n>=0; n--)
{
if(buf.st_mode&(1<<n))
{
switch(n%3)
{
case 2:
printf("r");
break;
case 1:
printf("w");
break;
case 0:
printf("x");
break;
default:
break;
}
}
else
{
printf("-");
}
}
printf(" %d",buf.st_nlink);
pw = getpwuid(buf.st_uid);
printf(" %s",pw->pw_name);
gr = getgrgid(buf.st_gid);
printf(" %s",gr->gr_name);
printf(" %ld",buf.st_size);
t = localtime(&buf.st_atime);
printf(" %d-%d-%d %d:%d"
,t->tm_year+1900
,t->tm_mon+1
,t->tm_mday
,t->tm_hour
,t->tm_min);
printf(" %s ",filename);
if(S_ISLNK(buf.st_mode))
{
printf(" -> ");
if(readlink(filename,out,100)==-1)
{
//printf("readlink error\n");
}
printf("%s",out);
}
printf("\n");
return 0;
}
int ls_prepare(char *w,int aflag,int lflag)
{
struct stat buf;
char name[100];
DIR *dir;
struct dirent *pdr;
if(lstat(w,&buf)<0)
{
fprintf(stderr,"stat error:%s\n",strerror(errno));
return -1;
}
if(S_ISDIR(buf.st_mode))
{
dir = opendir(w);
while ((pdr = readdir(dir))!=NULL)
{
if(aflag==0)
{
if(pdr->d_name[0]=='.')
continue;
memset(name,0,100);
strcpy(name,w);
strcat(name,"/");
strcat(name,pdr->d_name);
do_ls(name,pdr->d_name,lflag);
}
else
{
memset(name,0,100);
strcpy(name,w);
strcat(name,"/");
strcat(name,pdr->d_name);
do_ls(name,pdr->d_name,lflag);
}
}
closedir(dir);
}
else
{
do_ls(w,w,lflag);
}
return 0;
}
int main(int argc,char **argv)
{
int aflag =0;
int lflag =0;
char c;
int i;
while((c = getopt(argc,argv,"al"))!=-1)
{
switch(c)
{
case 'a':
aflag =1;
break;
case 'l':
lflag =1;
break;
default:
break;
}
}
if(argc == optind )
{
ls_prepare("./",aflag,lflag);
}
else
{
for(i=optind; i<argc; i++)
ls_prepare(argv[i],aflag,lflag);
}
printf("\n");
return 0;
}
任务四:cat userlist
1.学习cat命令
cat命令是linux下的一个文本输出命令,通常是用于观看某个文件的内容的;
cat主要有三大功能:
1.一次显示整个文件: cat filename
2.从键盘创建一个文件: cat > filename(只能创建新文件,不能编辑已有文件).
3.将几个文件合并为一个文件:cat file1 file2 > file
参数:
-n 或 –number 由 1 开始对所有输出的行数编号
-b 或 –number-nonblank 和 -n 相似,只不过对于空白行不编号
-s 或 –squeeze-blank 当遇到有连续两行以上的空白行,就代换为一行的空白行
-v 或 --show-nonprinting:使用 ^ 和 M- 符号,除了 LFD 和 TAB 之外。
-E 或 --show-ends : 在每行结束处显示 $。
-T 或 --show-tabs: 将 TAB 字符显示为 ^I