Linux驱动开发基础知识
驱动开发
确定主设备号 定义file_operations结构体 实现对应的open/read/write函数
在内核里注册程序register_chrdev 入口函数 出口函数 提供设备信息、自动创建设备节点(module_init、module_exit) MODULE_LICENSE(“GPL”)必须遵守GPL协议
chrdevs类似数组,其实不是数组
misc内核经典 字符驱动程序
copy_from_user函数copy数据至内核、用户空间
init中注册驱动、创建class、创建device
insmod 开发板上装驱动程序。驱动程序是xxx.ko
lsmod 查看已经装载的驱动程序
rmmod 卸载驱动程序
dmeg查看内核打印的东西 printk内核打印 printf是app打印的
普通GPIO操作方法
使能GPIO模块
设置引脚模式选择
方向设置
设置数据
读写寄存器,不要影响其他位 所以要先读出来,设置后再写回去。如果直接写入,会影响其他位
imx6uL GPIO操作方法
CCM(18章):时钟控制单元 使能端口
设计IO ...
两数之和
1. 两数之和1. 两数之和 - 力扣(LeetCode)
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
思路本题不能用滑动窗口来做!滑动窗口只适用于找连续的元素!!!!比如说,找数组中长度最小的子数组。
本题有两种解法,一种是用map,一种是用set。个人理解的,set的做法和map的差不多。如果用map来做,需要了解:
pair是结构体,用于将两个不同类型的数据组合在一起,常用于STL中的map或函数值返回。
访问pair中的元素分别为 first、second。
用法:pair<type,type>(n,n)
auto: 自动获取变量的类型。例如 auto n = (int) a。此时n的数据类 ...
快乐树
快乐树,你真的快乐吗?
第202题. 快乐数编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
示例 1:
1234567输入:n = 19输出:true解释:12 + 92 = 8282 + 22 = 6862 + 82 = 10012 + 02 + 02 = 1
示例 2:
12输入:n = 2输出:false
思路本题看上去是数学题?错了。看完题目,注意题目说了,会无限循环。
一说到无限循环找交点,首先应该想到快慢指针,就像链表一样,有圆定能相遇。
做法1:
因此做法一的思路就很明确了,定义快慢指针,让快指针每次做两次运算,慢指针做一次运算,他们一定会在某处相遇。相遇的地点为1的话,就是快乐树了。因为做的运算的相同的,因此可以把这个运算封装成一个函数进行调用。做法1见如下C语言代码。
做法 ...
两个数组的交集
349. 两个数组的交集349. 两个数组的交集 - 力扣(LeetCode)
示例 1:
12输入:nums1 = [1,2,2,1], nums2 = [2,2]输出:[2]
示例 2:
123输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]输出:[9,4]解释:[4,9] 也是可通过的
提示:
1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000
说明: 输出结果中的每个元素一定是唯一的。 我们可以不考虑输出结果的顺序
思路这道题目,主要要学会使用一种哈希数据结构:unordered_set,这个数据结构可以解决很多类似的问题。
第二种解法使用c语言实现,见下文。
使用数组来做哈希的题目,是因为题目都限制了数值的大小。如果没有限制数值的大小,就无法使用数组来做哈希表了。而且如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。此时就要使用另一种结构体set。
关于set,C++ 给提供了如下三种可用的数据结构:
...
Linux应用开发基础知识
main函数中的两个参数:
argc argv 参数个数 存储数组
主要是传递参数用。
gcc 是c语言的编译工具
使用Linux-arm-gcc 编译完arm可执行程序后重新后,Ubuntu通过nfs网络文件系统传输文件至开发板,进行编译调试。
挂载指令:(数据传输)mount -t nfs -o nolock,vers=3 192.168.3.40:/home/alienteek/linux/nfs get/
-t nfs : 网络文件系统
-o nolock 不带锁的,ver=3(nfs版本是3.0) 地址是xxx.xxx.xxx.xxx:Ubuntu的nfs目录 开发板存储目录
上面的指令意思是,把服务器上nfs里的文件挂载到开发板get文件夹里。
0若文件夹不存在,则要创建文件夹,使用mkdir get
.h 申明 ->在系统目录中(工具链目录),或者自己指定
.c实现
用户态 user
内核态kernel
硬件
GCC编译器
预处理 编译 汇编 链接
程序错误是在编译时检查,预处理不检查
gcc -o
gcc -c -o xxx.o ...
有效的字母异位词
242.有效的字母异位词242. 有效的字母异位词 - 力扣(LeetCode)
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
示例 1: 输入: s = “anagram”, t = “nagaram” 输出: true
示例 2: 输入: s = “rat”, t = “car” 输出: false
说明: 你可以假设字符串只包含小写字母。
思路错误思路:本题不可以对两个字符串中的字符asc码分别相加,判断是否相等来做。因为字符串中的字符不相等,asc码相加的结果也可能是相同的。
正确思路:构建hash表,构建hash function,一个字符串写入数据,另一个字符串删除数据,判断hash表中的元素是否为0。(前提是hash初始化,存储的所有元素都为0)
本题所需要构造的hash表较小,且数据范围也小,因此使用数组来构建hash表。
c语言代码实现如下:
1234567891011121314151617bool isAnagram(char* s, char* t) { int i ; ...
hash表学习
hash实现快速插入和快速查找(时间复杂度都为O(1))
对于data构造一个函数,得到data的hash值,存入hash表中。
和函数一样,一个输入都有对应的输出。
hash扩容负载因子 = 实际存放元素/数组容量
式子右边大于负载因子时候需要扩容,把所有元素重新插入到新的hash表中
hash碰撞(多个输入对应同一个输出)使用二次hash
线性探测法
增:在数组中查找空位,存放数据。
查:查找的时候,若在原本的值的位置没有,就往下遍历查找,一直查找到空为止。
删:要把对于位置赋值为-1(相当于伪删除)。如果不给值的话,在查找的时候就找不到删除元素之后的元素。
开放探测法
随机探测法
使用链表
数组、值小,范围可控
set、数组很大
map、k对应有value
环形链表Ⅱ
142.环形链表II142. 环形链表 II - 力扣(LeetCode)
题意: 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
思路判断链表是否有环 可以使用快慢指针法,分别定义 fast 和 slow 指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。
fast 走两个节点,slow走一个节点,有环的话,一定会在环内相遇,而不是永远的错开。因为fast是一个节点一个节点的追赶slow的,因此不会错开的。
因此,fast指针一定先进入环中,如果fast指针和slow指针相遇的话,一定是在环中相遇。
如果有环,如何找到这个环的入口相遇时: slow指针走过的节点数为: x + y, fast指针走过的节点数:x + y + n (y + z),n为fast指针在环内走了n圈才遇到slow指针, (y+z) ...
链表相交
面试题 02.07. 链表相交面试题 02.07. 链表相交 - 力扣(LeetCode)
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
ps:链表相交并不是说两个链表中的元素相等而已,而是指链表交点的指针(就是说两个链表中,存在某一元素存储的地址是一致的),并且从这个地址之后的所有元素都相等。
思路暴力解法:(c语言实现)
个人第一次解的时候使用的方法,使用两个循环,查找地址相同的两个节点,并且指向的下一个地址也相同,则就是两个链表的交点。
巧妙解法:(C++实现)
得出两个链表长度
计算链表长度差gap(C++中可以用swap(a,b),快速交换a和b的值)
长链表指针先移动gap位,使得两个链表尾部对齐
开始同时遍历长链表和短链表,找到相同的地址节点后返回
这么做的话也就是说,两个链表要是相交的话,一定从短链表中的元素开始的。
c语言代码如下:
123456789101112131415161718192021222324252627/** * Definition for s ...
删除链表的倒数第N个节点
19.删除链表的倒数第N个节点19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
进阶:你能尝试使用一趟扫描实现吗?
思路本题思路有二:
第一种:
自己的做法。
使用虚拟头节点对链表进行反转操作
用cnt从前遍历n个,然后删除该节点
再次使用虚拟头节点对链表进行反转
第二种:
双指针、虚拟头节点法做。
为什么要用虚拟头节点的方法做?
因为用虚拟头节点做的话可以不用考虑删除的元素是否为头节点。虚拟头节点一直指向的是链表的头节点的位置,就算链表的头结点变了,虚拟头节点还是可以link到新的头节点的位置。
使用一个快指针前进n+1个节点
快、慢指针同时向前走,直到快指针遍历结束
此时慢指针指向n-1元素的位置,直接删除第n个元素即可
以下c语言的做法就是用的第一种方法做的。
12345678910111213141516171819202122232425262728293031323334353637383940/** * Definition for singly-linked list. * s ...