栈的作用为:(1)保存现场/上下文;(2)传递参数:汇编调用C函数进行传参;(3)保存临时变量
时钟,对于CPU而言,可理解为由逻辑门组成,在特定输入下,会有相应的输出。逻辑运算为了保证操作顺序的稳定,
会将时钟作用于寄存器上,从而实现运算的控制,实现同步
关看门狗:防止程序重启
设置时钟:设置机器运行频率
初始化SDRAM:初始化内存
重定位
Nor的接口与RAM一致,可随意访问任意地址数据;Nor 容量比Nand小;代码能够给直接在Nor上运行;Nor擦除速度比Nand慢;Nand更适合存储数据
同步指发送方发出数据后,等待收方发回响应以后才发下一个数据包的通讯方式
异步指发送方发出数据后,不等接收方响应,接着发下个数据包的通讯方式
单工数据传输只支持数据在一个方向上传输;
半双工数据传输允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信;
全双工数据通信允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。
UART:全双工,异步通信,不需要时钟线,通过起始位与停止位及波特率进行数据识别,传输速率较低
I2C:半双工,包含时钟线与数据线,支持多主机多从机,速度比SPI慢
具体请看:https://blog.csdn.net/MoLiYw/article/details/101103224
SPI:全双工,同步串行传输,传输速率高,只支持单主机
具体请看:https://blog.csdn.net/MoLiYw/article/details/101106543
请看文章:https://blog.csdn.net/MoLiYw/article/details/101108969
使用cache是为了提高系统性能,但由于cache的使用可能会改变访问主存的数量、类型和时间,因此bootloader不需要
7种:
保护现场->处理异常->恢复现场 利用CPSR寄存器
属性 | 指令 | 介绍 |
---|---|---|
跳转 | B | 绝对跳转指令 |
BL | 相对跳转指令 | |
数据处理 | MOV | 数据传送 |
CMP | 比较 | |
ADD | 加法 | |
SUB | 减法 | |
AND | 逻辑与 | |
EOR | 逻辑异或 | |
ORR | 逻辑或 | |
乘法 | MUL | 32位乘 |
状态寄存器访问 | MRS | 状态寄存器到通用寄存器传送 |
内存访问 | LDR | 字数据读取 |
STR | 字数据写入 | |
异常中断 | SWI | 软中断指令 |
ARM协处理器 | MRC | 协处理器到ARM寄存器数据传送 |
MCR | ARM寄存器到协处理器寄存器数据传送 |
多进程与多线程:
对比 | 进程 | 线程 | 总结 |
---|---|---|---|
数据共享,同步 | 共享复杂,IPC;数据分开,同步简单 | 共享简单;同步复杂 | 各有优势 |
内存,CPU | 占用内存多,CPU利用率低 | 占用内存少,CPU利用率高 | 线程占优 |
切换 | 创建销毁、切换复杂;速度慢 | 创建销毁、切换简单;速度快 | 线程占优 |
可靠性 | 进程间不会影响 | 一个线程挂掉将导致整个进程挂掉 | 进程占优 |
分布式 | 适用于多核,多机分布式 | 适用于多核分布式 | 进程占优 |
进程状态:
就绪、运行、阻塞
IPC:
IPC | 优点 | 缺点 |
---|---|---|
管道 | 自身具备同步机制 | 只能用于有亲缘关系进程之间的通信;只支持单向数据流 |
信号 | 异步通信 | 可携带信息少,不具备同步机制 |
消息队列 | 提供有格式字节流,消息有类型或优先级 | 速度相比较慢,在新的应用程序中不应当再使用 |
共享内存 | 最快,效率高 | 自身不具备同步机制 |
信号量 | 速度快于记录锁 | 复杂 |
socket | 实现简单,同步机制 |
临界区是一个访问共用资源的程序片段,而这些资源又无法被多个线程同时访问的特性。
互斥量、信号量、事件(信号)
资源数量有限、锁和信号量错误使用。
死锁条件:
死锁预防:
防止条件中任何一个发生
逻辑流在时间上重叠。在访问慢速I/O设备、人机交互、推迟工作以降低延迟、服务多个网络客户端等需要。
方式 | 优点 | 缺点 | 场合 |
---|---|---|---|
多进程 | 最简单,有独立地址空间 | 共享信息复杂,速率慢 | 目标子动能交互少,如果资源和性能许可,可以设计由多个子应用程序来组合完成目的 |
I/O多路复用 | 更多对程序行为的控制 | 编码复杂,不能充分利用多核处理器;每个逻辑流都能够访问该进程全部地址空间 | 客户端要处理多个socket;客户端同时处理连接和用户输入;TCP同时监听socket和连接socket;服务器同时处理TCP和UDP;服务器监听多个端口 |
多线程 | 逻辑控制简单,共享内存,消耗低 | 一个线程崩溃导致整个程序崩溃,CPU占用高 | 常见的浏览器、web服务;需要频繁创建销毁的优先用线程;需要进行大量计算的优先使用线程; |
select O(n)
poll O(n)
epoll O(1)
OSI | TCP | 举例 | |
---|---|---|---|
应用层 | 应用层 | 应用层 | Telnet(远程登录协议)、FTP(文件传输协议)、SMTP(简单邮件传输协议)、DNS(域名解析)、SNMP(简单网络管理协议)、HTTP(超文本传输协议)、DHCP(动态主机分配协议)、SSH(安全外壳协议) |
表示层 | |||
会话层 | |||
传输层 | 传输层 | 传输层 | TCP(传输控制协议)、UDP(用户数据报协议) |
网络层 | 网络层 | 网络层 | IP(Internet协议)、ARP(地址解析协议)、ICMP(Internet控制报文协议) |
数据链路层 | 网络接口层 | 数据链路层 | 802.11、以太网、Wi-Fi、帧中继、GPRS |
物理层 | 物理层 | 以太网物理层、调制解调器 |
传输层:端对端接口
网络层:控制子网运行
数据链路层:物理寻址
TCP/IP协议族:
- Internrt协议
- 传输控制协议(TCP)和用户数据报协议(UDP)
- 处于TCP与UDP之上的一组应用协议:TELNET、文件传送协议(FTP)、域名服务(DNS)、简单邮件传送程序(SMTP)
字段 | 含义 |
---|---|
ACK | 确认号是否有效,一般置为1 |
PSH | 提示接收端应用程序立即从TCP缓冲区把数据读走 |
RST | 对方要求重新建立连接,复位 |
SYN | 请求建立连接 |
FIN | 释放一个连接 |
三次握手:
四次挥手:
这是因为Server在LISTEN状态下,收到Client建立连接请求的SYN报文后,会将ACK和SYN放在一个报文中发送给Client,其中ACK报文用来应答,SYN报文用来同步。而关闭连接时,当Server收到FIN报文时,因TCP是全双工,此时的Server可能还有数据没有发送给Client,所以Server只能先回复一个ACK报文表示已经接收到了Client的FIN报文,等待Server将所有数据全部发送后才发送FIN报文标识同意关闭连接。即ACK和FIN一般都会分开发送。所以需要四次握手。
在保证通信的时延和质量的条件下尽量降低成本
① 添加seq/ack机制,确保数据发送到对端
② 添加发送和接收缓冲区,主要是用户超时重传
③ 添加超时重传机制
RUDP:可靠用户数据报协议
RTP:实时协议
UDT:互联网数据传输协议
int main(void)
{
unsigned char c = 10;
while(c-- >= 0)
{
}
}
error:while条件会一直为真,持续循环
Problem:无符号字符型范围为0-255;当c=0时,再次执行一次循环后,c=-1,在计算机中会采取补码形式存储,即11111111,也就是255,所以会继续执行
Solution:去掉条件中的"="号
strcpy:把src开始以\0结尾的字符串复制到以dest为开始的地址空间,当源字符串的大小大于目的字符串的最大存储空间后,执行该操作会出现段错误
sprintf:把格式化字符串写入某个字符串,对写入buffer的字符数没有限制,存在溢出可能
memcpy:从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中,src和dest有可能出现空间重叠,它可以复制任何内容
void* mymemcpy(void* desc, void* src, int size)
{
if(NULL == desc && NULL == src)
return NULL;
unsigned char* desc1 = (unsigned char *)desc;
unsigned char* src1 = (unsigned char *)src;
if(desc > src && desc1 < (src1 + size)) // memory overlop
{
for(int i = size-1; i <= 0; i--)
{
*desc1++ = *src1++;
}
}
else
{
for(int i = 0; i < size; i++)
{
*desc1++ = *src1++;
}
}
return desc;
}
int main(void)
{
char a;
char* c = &a;
strcpy(c,"hello");
return 0;
}
error:内存越界
Problem:字符串"hello"占6byte,但a为1byte
会发生内存泄漏的内存就是堆上的内存,也就是说由malloc系列函数或new操作符分配的内存。如果用完之后没有及时free或delete,这块内存就无法释放,直到整个程序终止。
/*********************交换排序*********************/
/* 1.1 冒泡排序 */
void BubbleSort(int data[], int length)
{
int i,j,tmp;
bool swap; /* 添加标志位优化:前一轮有序则循环终止 */
for(j=length-1; j>0; j++)
{
swap = flase;
for(i=0; i data[i+1]) // 由小到大排序
{
tmp = data[i];
data[i] = data[i+1];
data[i+1] = tmp;
swap = true;
}
}
if(flase == swap)
{
break;
}
}
}
/* 1.2 快速排序 */
void QuicksSort(int data[], int low, int high)
{
if(low > high)
return;
int pivot = findpivot(data, low, high);
QuicksSort(data, low, pivot-1); //递归排序左子数组
QuicksSort(data, pivot+1, high); //递归排序右子数组
}
int findpivot(int data[], int low, int high)
{
int pivot = data[low];
while(low= pivot))
{
high--;
}
data[low] = data[high];
while((low < high) && (data[low] <= pivot))
{
low++;
}
data[high] = data[low];
}
data[low] = pivot;
return low;
}
/****************************二 插入排序 *****************************************/
/* 2.1 直接插入 */
void InsertSort(int data[], int length)
{
int i;
for(i=1; i 0) && (data[position-1] > value))
{
data[position] = data[position-1];
position--;
}
data[position] = value;
}
}
/* 2.2 希尔排序 */
void ShellSort_On2(int a[], int length)
{
int temp,delta,i,j;
for(delta = length/2; delta>=1; delta/=2)
{
for(i=delta; i=delta)&&(data[j] data[j])
{
min = j;
}
}
if(min != j)
{
temp = data[i];
data[i] = data[min];
data[min] = temp;
}
}
}
/************************** 四 归并排序 ***************************************/
void MergeSort(int data[], int length)
{
int temp[length];
InternalMergeSort(data, temp, 0, length-1);
}
void InternalMergeSort(int data[], int temp[], int left, int right)
{
if(left < right)
{
int middle = (left+right)/2;
InternalMergeSort(data, temp, left, middle);
InternalMergeSort(data, temp, middle+1, right);
MergeSortdata(data, temp, left, middle, right);
}
}
void MergeSortdata(int data[], int temp[], int left, int middle, int right)
{
int i = left;
int j = middle + 1;
int k = 0;
while((i < middle) && (j <= right))
{
temp[k++] = data[i] < data[j]?data[i+1]:data[j++];
}
while(i <= middle)
{
temp[k++] = data[i++];
}
while(j <= right)
{
temp[k++] = data[j++];
}
for(i=0; i temp)
{
temp = data[i];
}
}
return temp;
}
int FindMinData(int data[], int length)
{
int i = 0;
int temp = data[0];
for(i=1; i
static char table[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
char* doubletochar(double number, int fontnum, int behindnum)
{
int length;
int i;
length = fontnum + behindnum;
int g_num = number / 1;
double g_t = 0.0;
char* str = (char *)malloc(length+1);
/* 计算小数点前数据 */
for(i=1; i<=fontnum; i++)
{
if(0 == g_num)
str[fontnum - i] = table[0];
else
str[fontnum - i] = table[g_num%10];
g_num = g_num / 10;
printf("%c\t",str[g_num - i]);
}
str[fontnum] = '.';
g_t = number;
for(i=fontnum+1; i<=length; i++)
{
g_num = g_t * 10;
str[i] = table[g_num%10];
printf("%c\t",str[i]);
g_t = g_t * 10;
}
str[length] = '\0';
return str;
}
void freestring(char* str)
{
free(str);
}
参考:
[1] https://blog.csdn.net/linraise/article/details/12979473
[2] https://blog.csdn.net/shenya1314/article/details/73691088
[3] https://www.cnblogs.com/Qing-840/p/9283367.html
[4] https://blog.csdn.net/fangjian1204/article/details/39738293