自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(40)
  • 收藏
  • 关注

原创 硬件开发(8)—IMX6ULL裸机—UART通信

通信双方的角色完全固定,一方仅作为 “发送端”(只能向外发送数据),另一方仅作为 “接收端”(只能接收数据),数据只能沿单一方向传输,无法反向交互。

2025-09-15 21:35:34 524

原创 硬件开发(7)—IMX6ULL裸机—led进阶、SDK使用(蜂鸣器拓展)、BSP工程目录

/GPIO相关寄存器#define GPIO1_DR *((volatile unsigned int *)0x0209C000) // 数据寄存器:控制引脚输出高低电平#define GPIO1_GDIR *((volatile unsigned int *)0x0209C004) // 方向寄存器:配置引脚为输出// 引脚复用与电气属性寄存器(GPIO1_IO03引脚)

2025-09-11 21:40:18 836

原创 硬件开发(6)—IMX6ULL裸机—led灯

arm-linux-gnueabihf-gcc -c start.S -o start.o -g //-c 只汇编不链接,-g 保留调试信息。orr r1, r1, #(1 << 3)// 将 bit3 置 1(GPIO1_IO03 对应 bit3,1=输出)ldr pc, =_start_handler //复位异常(唯一会执行的异常入口)ldr pc, =_irq_handler //IRQ 中断(外设常用)ldr pc, =_svc_handler //SVC 异常(软中断)

2025-09-10 20:50:31 946

原创 硬件开发(5)—ARM汇编基础知识

汇编伪操作并非处理器指令,而是用于指导汇编器组织代码段、指定指令集等,是构建启动代码的 “骨架”。启动代码的标准开头由以下伪操作组成:示例:立即数:准确的说这里所指的是12位立即数imm12。先说怎么判断某数是不是12位立即数,12位立即数的条件是:把某个数展开成2进制,该数必须存在一种循环右移(偶数位),使得移位后高24位全0,低8位即为有效imm8(最高位1与最低位1如果大于8,则不可能是立即数)LDR<c> <Rt>, <label> (非立即数使用)STR<c> <Rt>, <label> (将

2025-09-09 20:26:45 828

原创 硬件开发(4)—ARM裸机体系结构

嵌入式系统是以应用为中心、以计算机技术为基础,软硬件可裁剪的专用计算机系统。它会根据用户对功能、体积、可靠性等需求进行定制。从组成来看,软件层面包含系统软件(如操作系统)和应用软件;硬件基本构成有运算器、控制器、存储器、输入设备、输出设备。MPU(微处理器):偏向处理复杂任务,像高端嵌入式设备的核心计算。MCU(微控制器):集成了处理器、存储器等,常用于单片机类简单控制场景。DSP(数字信号处理器):专为高度复杂数学运算设计,在音频、图像处理等领域广泛应用。SoC(片上系统)

2025-09-07 23:13:41 746

原创 硬件开发(3)—单片机(3)

通用异步收发器,2个串口(1个串口被用于ISP下载程序,1个串口被用于和主机之间的通信),RXD(接收信号线) TXD(发送信号线):bps(bit per second),每秒钟传输bit的数量,常见的波特率:2400,4800, 9600,115200。:校验位为'1',若数据位中'1'的个数加上校验位中的'1',保持'1'的个数为奇数个,则代表校验通过。:校验位为'0',若数据位中'1'的个数加上校验位中的'0',保持'1'的个数为偶数个,则代表校验通过。

2025-09-04 20:48:48 547

原创 硬件开发(2)—单片机(2)

8位自动重装载定时器:分为TL0和TH0两部分,1byte,实际参与计数的只有TL0,当TL0中的值加到255溢出后,再将TH0中的值重新装入到TL0中。1. 中断概念:CPU在执行一个任务时,被外界更为紧急的事件打断,转而去执行更为紧急的任务,执行完后再回到刚才的地方继续向下执行,这一过程叫做中断。(1)将TCON寄存器的bit1,IE0置1,代表向CPU发起中断请求,CPU响应完中断请求后,硬件清“0”5. 中断优先级:CPU再去处理中断任务时候,会去比较多个中断的优先级,优先去处理优先级高的中断。

2025-09-03 20:46:49 836

原创 硬件开发(1)—单片机(1)

此时发光二级管阳极会输出高电平(VCC 5V),如果发光二级阴极输出一个低电平(0V), 阳极和阴极之间会形成一个正向的电压差,满足发光二极管的单向导通性,所以电流就会从阳极流向阴极,发光二级就被点亮。:微控制器,集成度比较高,将所有功能集成到芯片中(CPU、RAM、ROM、定时器、UART、IO),简单控制, 成本低。:微处理器,集成度低,只有一块单独的CPU,需外接外设、存储模块,复杂应用领域,跑Linux操作系统,成本高。:将二进制中的对应位的bit进行比较,如果有一个bit为1,结果为1;

2025-09-02 20:21:05 1851

原创 网络编程(2)—多客户端交互

/监控表示 10个fd 2.添加要监控的文件描述符 //点对点聊天。//清除对应的客户端的fd。//设置和进程相关联。

2025-08-29 21:36:30 1974

原创 网络编程(1)——TCP、UDP

失败 -1&&errno。1 -- 我要通话 --> 1 //连接的请求。2 <--嗯,我知道了,你可以-- //对方接听电话 喂。3 -- 嗯,好的 --> //喂。SOCK_DGRAM //数据报套接字 ---udp。SOCK_STREAM //流式套接字 ---tcp。3.网络层 ----- 数据包 (packet)6.表示层 //加密传输的需要 --- 数据的格式化。

2025-08-25 21:17:41 976

原创 Linux软件编程(8)—进程间通信(2)消息队列、共享内存、信号灯

原型:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);原型:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);进程空间是独立的,共享内存是开辟一段内核空间,进程都映射到这一片空间上,实现空间的共享。原型:int semctl(int semid, int semnum, int cmd, ...);

2025-08-19 21:32:11 739

原创 Linux软件编程(8)—进程间通信(1)

9号信号(SIGKILL)和19号信号(SIGSTOP)不能被忽略和捕捉的。原型:int kill(pid_t pid, int sig);多个进程没有共享的用户空间,进程是操作系统资源分配的最小单元。读取数据时,如果管道中没有数据则阻塞等待有数据写入才能读出。Linux系统中的信号主要实现应用层和内核层之间的信号通知。3)两个进程可以通过向管道文件中读写数据实现进程的通信。应用层与内核层之间通信的信号根据含义分为很多不同的信号。写入数据时,会产生管道破裂的信号导致进程任务异常退出。

2025-08-18 20:18:23 957

原创 Linux软件编程(7)—线程(2)

原型:int pthread_mutex_destroy(pthread_mutex_t *mutex);原型:int pthread_mutex_unlock(pthread_mutex_t *mutex);原型:int pthread_mutex_lock(pthread_mutex_t *mutex);原型:int pthread_attr_init(pthread_attr_t *attr);如果信号量资源数为0,申请资源会阻塞等待,直到占用资源的任务释放资源,资源数不为0时。

2025-08-17 21:14:21 756

原创 Linux软件编程(6)—进程(2)、线程(1)

原型:int pthread_create(pthread_t *thread, const pthread_attr_t *attr,原型:pid_t waitpid(pid_t pid, int *wstatus, int options);原型:int pthread_join(pthread_t thread, void **retval);原型:pthread_t pthread_self(void);原型:pid_t wait(int *wstatus);

2025-08-15 21:04:24 1713

原创 Linux软件编程(5)—进程(1)

①父进程先结束,子进程会成为孤儿进程,孤儿进程被init进程收养,子进程再结束,init进程回收进程空间。产生原因:子进程结束后,父进程没有回收子进程空间,导致进程执行结束,空间依然被占用的状态,称为僵尸进程。进程是是程序动态执行的过程,包括创建、调度、消亡;父进程先结束,子进程会成为孤儿进程,被init进程收养。②子进程结束,父进程回收子进程空间,避免产生僵尸进程。创建一个新的进程,新的进程称为子进程,调用fork的进程称为父进程。多个进程空间在操作系统中存储时,空间是独立的(物理地址是独立的)

2025-08-14 21:56:38 680

原创 Linux软件编程(4)—文件IO(2)、目录IO、时间相关函数接口

原型:ssize_t write(int fd, const void *buf, size_t count);原型:ssize_t read(int fd, void *buf, size_t count);原型:struct tm *localtime(const time_t *timep);原型:char *getcwd(char *buf, size_t size);原型:char *ctime(const time_t *timep);原型:time_t time(time_t *tloc);

2025-08-13 20:47:17 704

原创 Linux软件编程(3)—标准IO(2)文件IO(1)

原型:size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE。原型:size_t fread(void *ptr, size_t size, size_t nmemb, FILE。思路:bmp格式的宽和高是在文件第18个字节后的8个字节存储的(分别四个字节),通过设置流的偏移量来读取数值。(1)标准IO是有缓存的IO,文件IO没有缓存,适合于通信、硬件设备操作。有三个特殊的文件描述符:标准输入(0)、标准输出(1)、标准错误(2)

2025-08-12 19:49:14 686

原创 Linux软件编程(2)- 标准IO(1)

原型:FILE *fopen(const char *pathname, const char *mode);原型:int fprintf(FILE *stream, const char *format, ...);原型:int fscanf(FILE *stream, const char *format, ...);原型:char *fgets(char *s, int size, FILE *stream);注意:gets会去掉从终端接收的\n字符,fgets不会去掉从终端接收的\n字符。

2025-08-12 00:42:49 518

原创 Linux软件编程(1)-Linux系统介绍及shell命令的使用

1.常见的Linux系统:Ubuntu、Debian、Redhat、CentOS等2.Linux操作系统是操作系统的核心,也称为内核,内核的主要功能为:①内存管理②多任务管理③文件系统管理④多任务间的通信⑤网络管理⑥硬件设备管理3.shell是操作系统的外壳,主要作用为:保护Linux内核,防止用户直接操作内核导致的异常问题命令解释器的作用,用户可以通过命令给到shell,并转换为对应的内核代码实现功能。

2025-08-10 21:01:55 861

原创 数据结构(6)—哈希表、数据排序和查找

本文介绍了哈希表和常见排序查找算法的实现原理。哈希表部分包括哈希算法、碰撞处理及基本操作实现(插入、遍历、查找、销毁),采用取模法处理0-100数据。排序算法对比分析了冒泡排序(O(n²)稳定)、选择排序(O(n²)不稳定)、插入排序(O(n²)稳定)、希尔排序(O(nlogn)不稳定)和快速排序(O(nlogn)不稳定)的时间复杂度及实现方法。查找算法重点介绍了折半查找(O(logn))的递归实现。各算法均附有C语言代码实现,涵盖从基本数据结构到典型算法的完整知识体系。

2025-08-08 18:50:27 258

原创 数据结构(5)-二叉树

本文系统介绍了树形结构的基本概念与应用。首先区分了线性结构与非线性结构,重点阐述了树形结构的节点类型(根节点、分支节点、叶子节点)、前驱后继关系、层数、高度深度等基本概念。其次详细讲解了二叉树的定义与分类,包括满二叉树和完全二叉树的特点。文章提供了完整的二叉树操作实现代码,包括创建完全二叉树、深度优先遍历(前序/中序/后序)、广度优先遍历、销毁二叉树等核心算法。特别介绍了非完全二叉树的创建方法,以及获取树高度/深度的递归实现。这些内容为理解和应用树形数据结构提供了系统性的技术指导。

2025-08-07 21:02:49 405

原创 数据结构(4)—栈和队列

使用链表的思想实现链式队列,参考单向链表节点定义,入队使用尾插法,出队返回链表第一个有效节点的值,并删除该节点,在主函数循环出栈队,销毁栈参考单向链表的销毁。使用链表的思想实现链式栈,参考单向链表节点定义,压栈使用头插法,出栈返回链表第一个有效节点的值,并删除该节点,在主函数循环出栈,销毁栈参考单向链表的销毁。//最多存放元素个数。1.栈只允许在栈顶位置入栈和出栈元素,链表可以在任意位置插入和删除元素,栈和队列只允许在指定位置插入和删除元素。空栈:栈针指向要入栈的位置 满栈:栈针指向栈顶元素的位置。

2025-08-06 20:52:14 832

原创 数据结构(3)—双向链表、循环链表

1. 头结点的ppre指向链表最后一个节点,最后节点的pnext指向第一个节点,可以通过头节点或尾节点定位到头节点和尾节点。插入:申请节点,并按照之前学习的循环链表插入即可(插入的链表节点首地址即数据节点首地。申请节点空间,对pnext和ppre赋值为NULL,返回空白节点地址。②让删除节点的前一个节点的pnext指向要删除节点的后一个节点。③让删除节点的后一个节点的ppre指向要删除节点的前一个节点。⑥如果有后一个节点,需要让后一个节点的ppre指向该节点。⑤将最后一个节点的pnext赋值为新申请节点。

2025-08-05 18:43:59 950

原创 数据结构(2)—单向链表(2)

本文介绍了链表的基本操作和常见算法实现,主要包括:1)查找节点(遍历比较);2)修改节点(查找后更新);3)尾插法(定位末尾插入);4)链表销毁(双指针释放);5)查找中间节点(快慢指针法);6)查找倒数第k个节点(快指针先走k步);7)无头节点删除(覆盖后删除);8)链表反转(头插法);9)排序(冒泡和选择排序实现);10)环检测(快慢指针判断环、计算环长及定位入口)。

2025-08-04 19:30:16 629

原创 数据结构(1)—基础概念、单向链表

1.(1)顺序表(数组)特点:存储空间连续,访问元素方便无法利用小的空间,必须连续的大空间,顺序表元素必须为有限的(不存在无限连续的空间)缺点:插入和删除效率低。(2)链表特点:存储空间不需要连续,可以利用一些小的存储空间,链表元素可以没有上限,插入和删除效率高 缺点:链表特点:访问元素不方便。创建一个空的链表节点,数据无需赋值,pnext必须赋值为NULL,此时该节点就为最后一个节点,将节点地址返回。//存放下一个节点地址。2.(1)单向链表:只能通过链表节点找到后一个节点,访问链表元素的方向是单向的。

2025-08-02 18:29:49 883

原创 c语言(14)—数据结构(2)内存管理

判断过程:union的字节长度是由内部数据类型最长长度决定的,char类型就会在较长数据类型的首地址位,可以通过这个原理判断。1. 共用体也称为联合体,共用体每个成员变量的空间共享的,结构体每个成员变量的空间是独立的,多用于函数传参使用。注:枚举常量均为int类型,且第一个枚举常量的值默认为0,后续枚举常量的值总是前一个常量的。3.内存泄漏:只申请空间,使用完毕后,不释放空间,导致可用空间越来越少,这样会产生内存泄露。1、 &按位与:与0得0,| 按位或:或1置1。^异或:相同为0,相异为1。

2025-07-30 18:26:29 651

原创 c语言(13)—指针(3)数据结构(1)

本文摘要: 数组指针:讲解了二维数组和指针数组的传参方式,演示了输入输出和排序操作的实现方法。 void*指针:说明其用于保存内存地址的特性,以及与其他指针类型的转换规则。 结构体:详细介绍了结构体的定义、初始化、成员访问、内存对齐规则和传参方式,包括传值和传地址两种方法,并提供了完整的示例代码。 重点强调了结构体传参时通常使用指针方式,以及memset函数在结构体初始化中的应用。 文章通过具体代码示例展示了各种指针和结构体的实际应用场景。

2025-07-29 18:25:40 301

原创 c语言(12)—指针(2)函数指针、二级指针、指针数组和数组指针

e.g. 思路:要将一个数组元素递减排序,先写出主函数,以及用指针写出两个被调函数(接收和打印)的程序,然后写一个冒泡排序的被调函数,函数中需要定义一个指针,一个数组长度,和一个函数指针,再写一个判断数组元素是否倒序的被调函数,在冒泡排序的if语句中引用函数指针,这个函数指针就指向用来判断的被调函数,最终在主函数中引用冒泡排序的函数是,第三个参量使用用来判断的被调函数的函数名,最终完成打印。定义一个指针变量q,占8个字节空间,指向一个指针变量空间,即指向一级指针变量的指针,也就是二级指针。

2025-07-28 19:33:24 394

原创 c语言(11)—指针(2)数组和字符串的传递

思路:在主函数中定义一个数组,并取地址使传入三个被调函数,在第一个被调函数中接收数组地址,注意接收使需要取地址;这种形式(const修饰p)指针变量p的值不能变,但可以利用指针p修改指向空间中的值,注意一定要记得初始化。这两种形式等价(const修饰*p),指针变量p的值(指向)可以改变,但是不能利用p修改指向空间中的值。这两种形式等价,指针变量p的值不能变,也不能通过p修改指向空间中的值。数组的数组名是指向数组第一个元素的指针常量。指针函数是函数,函数的返回值是指针。错,不能改变p指向空间的值。

2025-07-26 18:12:15 306

原创 c语言(10)—指针(1)基础概念及简单运算

本文系统介绍了指针的核心概念和应用。主要内容包括:1.指针基础:地址、指针和指针变量的定义,内存大小端概念;2.指针运算符(&和*)的功能及使用限制;3.指针变量的定义方法,区分野指针和空指针;4.指针算术运算规则及其与数据类型的关系;5.指针常见操作及注意事项;6.指针作为函数参数实现地址传递的应用实例,通过最大公约数和最小公倍数计算案例演示了指针参数的实际应用。全文重点阐述了指针与内存地址的关系、指针运算特性以及在函数参数传递中的重要作用。

2025-07-25 18:19:09 240

原创 c语言(9)—函数(3)

本文摘要: C语言编程知识要点包括:1.存储类型补充(extern用于多文件变量声明,static用于隐藏);2.函数传参方法(整型数组传参的两种方式及示例代码,字符数组传参应用);3.预处理命令(宏定义分类及特点,头文件包含规则,条件编译用法)。重点展示了四则运算、数组排序/倒置等案例的实现思路,对比了带参宏与函数的区别,并提供了模块化编程的工程结构建议。全文涵盖变量声明、函数参数传递、预处理指令等核心知识点,配有具体代码示例。

2025-07-24 17:33:38 990

原创 c语言(8)—函数(2)

思路:先在前面定义一个函数,这个函数中如果满足闰年条件(能被4整除且不是100的倍数或是400的倍数)就返回1,否则返回0,在主调函数中调用前面定义的函数,利用if语句输出接收的数字是否为闰年。②未初始化全局变量/静态变量区域(.bss):存放未初始化的全局变量和静态变量,在程序运行时会对.bss端初始化为0值。(1)存放全局变量和静态变量,未经初始化时会初始化为0值,程序编译时分配空间,程序结束时回收空间。形参改变,实参不会发生改变。栈区空间有上限的,默认(8M),不要定义太大空间,未经初始化值为0值。

2025-07-23 17:51:42 808

原创 c语言(7)—数组(3) 函数(1)

全部初始化:char str[5][32] = {{"hello"}, {"world"}, {"how"}, {"are"}, {"you"}};默认初始化:char str[][32] = {"hello", "world", "how", "are", "you"};strcpy:字符串拷贝函数,将字符串开头到\0的内容拷贝到目的空间(会拷贝\0)思路:利用while循环将\0前的每一个数分别赋值,在遇到\0后单独赋值完成输出。局部初始化:char str[5][32] = {0};

2025-07-22 18:26:01 324

原创 c语言(6)—数组(2)

本文介绍了数组排序和数组操作的基本知识。第一部分讲解两种排序算法:冒泡排序通过两两比较交换实现升序排列,使用双层循环结构;选择排序通过选出最小值放在前面实现排序,同样采用双层循环实现。第二部分阐述二维数组的定义、初始化(包括全部、局部和默认初始化)、存储特性(连续有序)以及数据接收方法。第三部分介绍一维字符数组的定义、元素访问、字符串打印(printf和puts)、初始化方式(全部、局部和默认初始化)以及字符串接收函数(scanf和gets)的区别。最后比较了strlen和sizeof在字符串处理中的不同作

2025-07-21 17:49:49 888

原创 c语言(5)—数组(1)

e.g. 首先接收五个数,多设置一个变量,将a[i]赋值给这个变量,然后把a[len-1-i]赋值给a[i],再把tmp赋值给a[len-1-i],以此循环,再将循环完成的数字依次输出,得到数组元素的倒置。设max为第一个数,进入第二个循环,分别与其他四个数比较,符合条件则赋值给max,最终输出max则为最大值。若将max变为最大值的角标,则需修改以上程序,在接收五个数后,设max=0,即第一个数的角标,如果第二个数大于a[max],则此时这个数的角标替换max,直至循环结束输出。

2025-07-19 18:19:28 688

原创 c语言(4)—流程控制

e.g.从终端接收一个字母,打印该字母在字典中的下一个字母,例如'a'打印'b', 'A'打印'B',如果是'z'或者'Z'打印'a'或者'A',如果不是字母则打印输入有误。e.g.从终端接收两个数,如果第一个数大于第二个数则打印第一个数,如果第一个数不大于第二个数,两者交换打印第一个数。(2)嵌套形式:break只能跳出一个switch,里层结束后,不加break,外层switch会继续向下执行。先执行A,接着判断B,符合语句后执行D,最后执行C,以此循环往复,直至不符合B语句,循环结束。

2025-07-18 18:19:58 642

原创 c语言(3)—输入输出函数

本文介绍了C语言中的输入输出函数和流程控制结构。输入输出部分详细讲解了printf和scanf函数,包括格式化字符串控制符(如%d、%f等)、特殊字符处理(如\n、\t等)以及多个变量的输入输出方法。流程控制部分阐述了逻辑表达式(关系运算符和逻辑运算符)、三目运算符以及if-else分支结构。文章还对比了puts/gets和printf/scanf在字符串处理上的区别,为C语言基础学习提供了重要参考。

2025-07-17 18:15:45 804

原创 c语言(2)—运算符、表达式

本文主要介绍了C语言的表达式、运算符和输入输出函数的使用要点。内容包括:1.变量初始化的重要性;2.表达式的组成及数据类型转换规则(自动转换和强制转换);3.各类运算符的使用(算术、赋值、逗号、sizeof)及其优先级;4.基本输入输出函数putchar和getchar的使用方法。重点强调了类型转换中的精度处理、运算符的运算规则以及简单字符IO操作。这些是C语言编程的基础知识要点。

2025-07-16 17:59:31 292

原创 c语言(1)—数据类型、常量与变量

本文系统介绍了C语言的基础知识,包括程序运行机制、数据存储单位及进制转换。重点讲解了C语言数据类型(整数、字符、浮点数、布尔型)及其存储方式、取值范围。详细说明了常量(整型、浮点型、字符、字符串、标识常量)和变量的定义与使用规则。文章强调掌握这些基础知识是学习C语言的重要起点,为后续进阶学习奠定基础。

2025-07-15 19:38:18 348

原创 linux基础知识及c语言开发基础

摘要:本文总结了嵌入式学习首日内容,主要包含三部分:1)开发环境搭建,包括VMware、VNCViewer安装及常用快捷键使用;2)Linux基础知识,涉及用户权限、文件目录操作(ls/mkdir/cd等命令)和路径管理;3)C语言开发流程,讲解vim编辑器使用和gcc编译四步骤(预处理-编译-汇编-链接)。这些内容构成了嵌入式开发的入门基础,为后续学习做好准备。

2025-07-14 21:49:46 270

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除