实现驱动代码与设备硬件信息相分离
(7/10)
Start信号、从设备地址(7位/10位)、读/写(读为1,写为0)、ACK、数据
#define SWAP(a,b) {a=b-a;b=b-a;a=a+b;}
奇偶校验、CRC校验、应用层协议检查(应用层协议通常会定义特定的数据格式和结构。接收端可以根据协议规范对接收到的数据进行验证,例如检查数据长度、数据类型或其他应用层约定的字段。)
A类地址:
A类地址的表示范围为:0.0.0.0~126.255.255.255,默认网络掩码为:255.0.0.0;A类地址分配给规模特别大的网络使用。A类网络用第一组数字表示网络本身的地址,后面三组数字作为连接于网络上的主机的地址。分配给具有大量主机(直接个人用户)而局域网络个数较少的大型网络。例如IBM公司的网络。
B类地址 :
B类地址的表示范围为:128.0.0.0~191.255.255.255,默认网络掩码为:255.255.0.0;B类地址分配给一般的中型网络。B类网络用第一、二组数字表示网络的地址,后面两组数字代表网络上的主机地址。
C类地址 :
C类地址的表示范围为:192.0.0.0~223.255.255.255,默认网络掩码为:255.255.255.0;C类地址分配给小型网络,如一般的局域网和校园网,它可连接的主机数量是最少的,采用把所属的用户分为若干的网段进行管理。C类网络用前三组数字表示网络的地址,最后一组数字作为网络上的主机地址。
应综合考虑函数的用途、系统的需求以及稳定性要求。通过合理设计返回值,可以使得中断处理更加高效、安全,同时也能提高程序的可维护性和可读性。
man手册
会造成内存泄漏
1、栈的长度不能超过预设的最大长度,否则会导致栈上溢,程序崩溃。因此,在实现栈的时候,需要预留一定的空间,以避免栈的长度超出范围。
2、栈的长度较小时,可以考虑使用静态数组来实现栈,这样可以避免频繁的动态内存分配和释放,提高程序的效率。
3、若栈的长度较小,需要根据具体的应用场景来选择合适的存储结构和算法,以保证程序的性能和效率。
4、在使用栈的时候,需要注意栈的空间利用率,避免出现空间浪费的情况。如果栈的长度较小,可以考虑使用链式结构来实现栈,这样可以灵活地利用空间。
5、需要注意栈的安全性,防止栈溢出等问题。在使用栈的时候,需要检查栈的长度和栈顶指针,避免出现越界访问的情况。
数组应用场景:
链表应用场景:
I2C通过向总线广播从机地址来进行寻址,SPI通过向对应从机发送使能信号寻址
栈是由程序自己开辟,自动释放。堆是由自己手动开辟,手动释放。
空间大小:栈的空间小、堆的空间大。
栈是向低地址扩展,而堆是向高地址扩展。
排队打饭、买票、取钱等等
1、 new/delete是C++关键字,需要编译器支持。malloc/free是库函数,需要头文件支持;
2、 使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。而malloc则需要显式地指出所需内存的尺寸。
3、 new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。而malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。
4、 new内存分配失败时,会抛出bad_alloc异常。malloc分配内存失败时返回NULL。
5、 new会先调用operator new函数,申请足够的内存(通常底层使用malloc实现)。然后调用类型的构造函数,初始化成员变量,最后返回自定义类型指针。delete先调用析构函数,然后调用operator delete函数释放内存(通常底层使用free实现)。malloc/free是库函数,只能动态的申请和释放内存,无法强制要求其做自定义类型对象构造和析构工作。
6、new是封装了malloc,直接free不会报错,但是这只是释放内存,而不会析构对象。
通过关键字__attribute__
#include
__attribute__((constructor)) void func()
{
printf("hello world\n");
}
__attribute__((deconstructor)) void func()
{
printf("hello world\n");
}
int main()
{
printf("main\n"); //从运行结果来看,并没有执行main函数
}
C #ifndef _HEADERNAME_H
#define _HEADERNAME_H
...//(头文件内容)
#endif
C++ #prama once
extern “C”
前置运算符的效率比后置运算符的效率要高
小于等于 或则大于等于 精度误差就相等
ps、top
答:多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。
1.flash有哪几种类型?你用过哪几种?
2.除了你写的这个外设?你用过哪些外设?
起始标志:SCL处于高电平状态、SDA从高电平跳变到低电平。
结束标志:SCL处于高电平状态、SDA从低电平跳变到高电平。
内存地址的别名
不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要⼀次访问。假设一个处理器总是从内存中取8个字节,则地址必须是8的倍数。如果我们能保证将所有的double类型的数据的地址都对齐成8的倍数,那么就可以用一个内存操作来读或者写值了。否则,我们可能需要执行两次内存访问,因为对象可能被分放在两个8字节内存块中。
总体来说:结构体的内存对齐是拿空间来换取时间的做法。
CPU在正常执行程序的过程中,由于内部/外部事件的触发或程序的预先安排引起CPU暂时中断当前正在运行的程序,而转去执行中断服务子程序,待中断服务子程序执行完毕后,CPU继续执行原来的程序,这一过程称为中断
起始位、数据位、校验位、终止位。
1、可以定义const常量,具有不可变性
2、便于进行类型检查,使编译器对处理内容有更多了解,消除了一些隐患。例如: void f(const int i) { …} 编译器就会知道i是一个常量,不允许修改;
3、可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。
4、节省时间和提高效率,编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
简单来说就是,现在当前文件中找有没有全局变量,没有找到,才会去其他文件中查找
一个前进先出、一个先进后出
答:yy p
grep
如果存储的数据不多,且需要长期通过下标访问元素应该使用数组。
如果存储的数据多,且需要长期进行添加和删除元素则使用链表。
串行外设接口,一共有四条线。MISO、MOSI、时钟线、CS。全双工
编译器无法识别变量
编译器在编译时需要知道每个变量的类型和内存分配。使用未定义的变量意味着编译器没有找到变量的声明,因此无法确定如何处理该变量。
作用域问题
变量的作用域决定了变量在哪些代码区域内是可见的。如果你在一个作用域中使用了在另一个作用域中定义的变量(或在没有定义的情况下使用),编译器将无法找到该变量的定义。
拼写错误
有时候,未定义的变量错误是由于拼写错误造成的。例如,你可能在代码中写错了变量名,导致编译器无法找到该变量的定义。
缺少头文件或库
在C/C++中,变量或函数的声明可能依赖于特定的头文件。如果缺少必要的头文件,编译器将无法识别这些变量或函数。
未初始化的变量
即使你定义了变量,但如果没有正确初始化,使用这些变量也可能导致逻辑错误。虽然这种情况不一定会导致编译时错误,但可能在运行时导致未定义的行为。
根本区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位。
影响关系:一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。
内存分配:同一进程的线程共享本进程的地址空间和资源,而进程之间的地址空间和资源是相互独立的。
共享内存是一种进程间通信的机制,即不同进程的虚拟内存空间(虚拟内存地址不需要相同),映射到相同的物理内存中。如果某个进程向共享内存写入数据,所做的改动将【立即影响到】【可以同时访问】(加了锁的就不算“同时可以访问")同一段共享内存的任何其他进程。
管道(pipe)、命名管道(FIFO)、消息队列(MessageQueue)、共享存储(SharedMemory)、信号量(Semaphore)、套接字(Socket)、信号 ( sinal )
105、手撕代码(简单,但是忘记了,好像是求素数)
a=b-a; b=b-a;a=a+b;
奇偶校验码、CRC校验、应用层协议检查
1. Little endian:将低序字节存储在起始地址
2. Big endian:将高序字节存储在起始地址
相同函数:bind和close函数。
不同函数:TCP(connect、listen、accept、send、recv)、UDP(sendto、recvfrom)。
答:波特率、起始位、数据位、校验位、停止位
自电容式(可实现单点+手势),互电容式(可实现多点)
情况,包括团队成员、客户或利益相关者的反馈,及对项目效果的评估。
7. 后续计划:
相同函数:bind和close函数。
不同函数:TCP(connect、listen、accept、send、recv)、UDP(sendto、recvfrom)。
答:波特率、起始位、数据位、校验位、停止位
自电容式(可实现单点+手势),互电容式(可实现多点)