嵌入式与单片机实验课答案
第一次实验
实验基本要求
写取平均值脚本
创建项目文件
1 | mkdir Project //在用户目录下(~)创建Project文件夹 |
使用vim创建mean.sh文件
1 | vim mean.sh |
如果出现这种情况
1 | sudo apt install vim |
安装完后在执行vim mean.sh,执行完后界面为
按i键进入插入模式
输入代码
1 |
|
输入完后按esc键退出插入模式,输入:wq退出vim
1 | sudo chmod 777 mean.sh //给mean.sh权限 |
执行完后10文件夹内出现 mean_result_学号_名字.txt 文件
内容为 平均数
创建ReadMe.md
1 | vim ReadMe.md |
进入后直接:wq退出
看到文件夹内多出了文件ReaMe.md,双击
在文本编辑器内写入以下示例后保存
打包成.tgz格式的压缩包(别忘了传图片)
1 | tar -czvf 压缩包的名字.tgz 你要压缩的第一个文件 第二个 .... |
进入学习通上交即可
进阶要求
代码修改为
执行命令改为
1 | ./mean.sh 1000ValuesCalcMean |
执行完后压缩上交即可(别忘了在ReadMe中说明使用了进阶要求)
第二次实验
实验要求
基本要求只需要配置SCP和NFS,配置SCP和NFS的文件时候添加上自己的学号截图,使用SCP和NFS的时候截图并放在Word里,把word和压缩后的配置文件上交即可
配置SCP
我使用的termux,就是老师发在群里的那个app
如果你是第一次安装termux
1 | //termux 上执行 |
安装Openssh
1 | //termux 上执行 |
安装成功后可以测试ssh的连接
1 | //termux |
连接成功后,在ubuntu上随便创建一个文件测试SCP,新开一个终端
1 | //ubuntu |
截图保存
NFS
我使用的是我购买的服务器,你可以采用windos和虚拟机,或者虚拟机之间通信
1 | sudo apt-get install nfs-kernel-server #安装NFS服务器端 |
在服务器上
- 设置本地目录权限
1 | sudo mkdir /nfs |
- 添加目录的绝对路径到共享
1 | vim /etc/exports |
- 启动NFS服务
1 | sudo /usr/sbin/exportfs -arf |
在客户端上
- NFS服务测试
1 | sudo mount -t nfs 192.168.12.123:/nfs /mnt -o nolock |
截图,把exports复制一份
提交
这样就完成的基本要求
把配置文件压缩
把图放到word,别忘加标题
把这个表复制到word
提交即可
进阶要求
可以参考我的git的使用
进阶没时间写了,找个其他时间再写
<<<<<<< Updated upstream
这是我实验二的文件包括了进阶要求的文件,可以参考着改改,不会可以线下问我,或者在我的评论区给我留言
=======
这是我实验二的[文件](HomeWork_1: 单片机嵌入式作业000000 - Gitee.com)包括了进阶要求的文件,可以参考着改改,不会可以线下问我,或者在我的评论区给我留言
第三次实验
实验要求
配置和安装VSCode
以下内容我都是在VSCode上完成的,虽然说不在VSCode上做也能完成,为了方便,我教以下怎么安装配置VSCode,方便以后的实验
进入官网
Ubuntu点击下载.deb格式的安装包
下载完成后,在下载的文件里面右键,打开终端
执行命令
1 | #注意你的安装包的名字可能因为版本不同和我不一样 |
安装完成后进入VSCode,进入扩展,搜索拓展
C/C++
Makefile Tools
安装上即可
C编程调试
在用户目录创建本实验项目的文件夹并打开VSCode
1 | cd ~ |
在VSCode中新建一个hello.c文件
输入
在VSCode按下Ctrl
+~
打开终端中依次执行并查看运行结果
1 | gcc –E hello.c –o hello.i |
使用gdb调试
生成可调试的可执行文件
1 | gcc -g -Wall hello.c -o hello_dbg.o |
开始调试
1 | gdb ./hello_dbg.o |
至少设置一个被调用函数内的断点并暂停(截图包括 list、break和print 被调用函数内变量,能看出是被调用函数内暂停)
1 | #以下语句在gdb里面按顺序执行 |
gcc改为makefile
vscode新建一个Makefile文件写入
1 | CC = gcc |
使用make编译并运行
1 | make all |
提交文件
word文档里面就是自己做了什么和截图,压缩包里面可能就是Makefile的文件把,我也不清楚,我就这样交上去的,他没说压缩包里面要有什么
第四次实验
实验要求
我感觉这个实验很水,把每次实验结果截图就行
查看编译运行源代码
创建本次实验项目文件夹
1 | cd ~ |
把下载文件你可以用的方式,把文件解压到30这个文件
线程
先在1_pthread的文件夹打开VSCode
1 | code ~/30/1_pthread |
使用自己的变量重命名(这个我觉得应该随便改改就行)
随便改个名字就行,例如把上边1.pthread_create_exit.c
中的returned_code_err
改为returned_code_wrong
改成这样
1 | /* 线程的创建与终止 : */ |
先清除以前编译的文件后编译代码在VSCode按下Ctrl
+~
打开终端
1 | make clean |
1 | make all |
依次执行文件并截图,后面是理解和解释的运行状态(这个要复制到word里面)
1 | ./1.pthread_create_exit.out |
pthread_create()可以创建线程,其代码如下:
1 | void *thread_function(void *index) |
·thread_id 为所创建线程的id
·attr为线程的属性
·thread_function给所创建的线程附加内容
·index给thread_function函数提供所需要的参数
·值得注意的是,当线程创建成功时,其函数返回值为0,否则,为1。
1 | ./2.pthread_join.out |
线程的连接
pthread_join()函数功能为等待指定线程结束,其放在主线程中目的是等待子线程结束,主线程再继续运行,其代码如下:
1 | pthread_join(pthread_t thread, void **retval) |
·thread为一指定的需要等待运行结束的线程
·retval为线程的退出码
1 | ./3.pthread_attr_init_destroy_getstack-foo_bar.out |
属性对象的初始化与销毁
pthread_attr_init()函数用于对线程属性对象的初始化,线程具有属性,在对该结构进行处理之前必须进行初始化,其代码如下:
1 | int pthread_attr_init(pthread_attr_t *attr) |
attr为线程属性结构体的指针变量
线程属性在使用之后就要对其进行销毁,即去初始化,要用到pthread_attr_destroy()函数,其代码如下:
1 | int pthread_attr_destroy(pthread_attr_t *attr) |
1 | ./4.pthread_mutex.out |
互斥锁静态与动态初始化及销毁
互斥锁可用于使线程按顺序进行,其中互斥锁的初始化用到pthread_mutex_t mutex以及int pthread_mutex_init()函数,前者可静态初始化互斥锁,后者可动态初始化互斥锁其代码如下:
1 | pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER |
·PTHREAD_MUTEX_INITIALIZER为一结构常量
·restrict mutex为新建的互斥锁变量
·restrict attr指定了新建互斥锁的属性
·互斥锁的销毁意味着释放它所占用的资源,且要求锁当前处于开放状态。需要用到pthread_mutex_destroy()函数。由于在Linux中,互斥锁并不占用任何资源,pthread_mutex_destroy()除了检查锁状态以外没有其他动作。其代码如下:
1 | int pthread_mutex_destroy(pthread_mutex_t *mutex) |
mutex为需要销毁的互斥锁变量
1 | ./5.pthread_dead_lock_of_mutex.out |
这里通过让两个进程不断争夺运行资源来使程序进入死锁状态。主线程创建了两个子线程pthread_1和pthread_2,p_1、p_2分别获得mutexA和mutexB,由于两个锁都上锁了,无法获得对方的锁,就造成了死锁现象。因为进入了死锁状态,所以不能继续操作了,这里使用了ctrl+z退出死锁状态。
1 | ./6.pthread_conditional_variable.out |
主线程创建的两个线程会对sum_lock交替上锁,不断地打印,循环:sum++,打印,解锁互斥量,执行if语句的操作,当sum=100时,发送一个唤醒命令到一个条件变量队列等待的线程,后者会在sum大于等于100时,随时有可能接收到来自pthread_cond_signal()函数的唤醒信号使得sum=0,并打印执行信息,但无论如何主线程都会在sum与120个1相加(即前两个创建的子线程所执行的循环中i都为60时)终止线程。
进程
打开2_process文件夹内打开VSCode
1 | code ~/30/2_process |
在VSCode按Ctrl
+~
打开终端,先清楚编译后的代码在编译
1 | make clean |
和上面一样挨个运行我就不写了,直接贴图和理解了(理解和图都是要粘贴到Word里面的)
这个没有理解,也写不了
这个没有理解,也写不了
这里就打印出来了父进程和子进程的pid。父进程的pid是3147,子进程的pid是3148。
这个没有理解,也写不了
第五个要修改一下源代码,如果上边都是按照我的来的话,改成和我一样就行
修改后的代码
1 | /* 子进程加载新程序 */ |
重新编译并运行
1 | make all |
通过运行结果可知,子进程携带参数执行了另一个程序,输出了对应结果。
检测子进程的退出状态
创建守护进程并写入时间到文件中
按两次ctrl+c可以退出
程序代码利用sigaction函数实现当进程首次收到SIGINT(Ctrl+c)信号时在终端打印Ouch信息,第2次按Ctrl+c时进程退出。
提交
就这样就行了,后边的应该不用运行了把截图和理解粘贴到Word里面直接交上就行了
第五次实验
实验要求
查看编译运行源代码
老样子创建项目此实验的项目文件夹
1 | cd ~ |
把这个上机 040 - tcp-while-neat(简洁示例).tgz 文件下载解压到这个文件夹,解压后如图
这个文件夹内打开VSCode
1 | code ~/40/tcp-while-neat |
在VSCode新建一个Makefile文件,并输入以下内容
打开终端(我上边说过怎么打开),先清除在编译代码
1 | make clean |
新开一个终端,在一个终端运行server一个运行client,点那个加号
1 | #开启服务器 |
在客户端终端输入hello world回车
返回服务器终端查看是否受到消息
修改为多线程代码
打开服务端代码修改一下
1 |
|
修改后重新编译代码
1 | make all |
Split三个终端(在终端里面按住Ctrl
+Shift
+5
)
在一个终端运行服务器,另两个运行客户端,查看是否三连接一个客户端还能继续连接其他客户端
1 | #服务端 |
提交文件
随便写写就行了,这是我的文件,压缩包我是把代码压缩上传了,他也没有说压缩包里要什么