摘要:
【简介】 Stack,栈结构,即传统的LIFO,后进先出,常用的实现方法有数组法和链表法两种。如果看过我上一篇文章《数据结构:二级指针与不含表头的单链表》,一定会看到其中的关键在于,利用void*指针将数据结构抽象出来,适用于任何数据类型。这次尝试利用void**,两级void指针,用数组法实现Stack的数据结构。 【Stack数据结构】 Stack 结构的申明如下(stack.c): 1... 阅读全文
2013年7月28日
摘要:
【简介】 对于最基础的数据结构,单链表,通常看到的做法是在存储链表的所有元素之时,除了有一个指向链表的变量之外,往往还存在一个指向表头的元素。通常二者其实都会指向链表的第一个元素。这么做的原因是为了链表操作方便,当进行链表的插入操作时,若在某一元素后面插入新元素时没什么问题,但当要求在某一元素的前面插入新元素时就会存在问题。即,若需要在表头的前面插入新元素,会比较麻烦。所以前面存在两个变量,一个... 阅读全文
2013年5月12日
摘要:
【@.1 简介】数据结构与内存管理是不可分割的,特别是在C语言中,对于指针的处理必须非常小心。通常我们在用动态内存分配时会调用malloc()函数为指针分配内存,但是在嵌入式编程时我并不喜欢使用malloc系列函数,宁可自己建立一个数组,需要使用时从数组里面分配空间。我曾经的博客《uCOS-II中的内存管理--C语言构建完整的微型动态内存管理机制》一文中介绍了在uCOS中的动态内存管理机制,那种方法的确十分好用,而且实际上我们也经常这样用。现在考虑自己构建一个简单的内存管理,主要用于对链表进行内存分配。下面循序渐进地介绍了几种方法来实现设计双向链表时的内存分配。【方法一:简单的数组】最简单的方 阅读全文
2013年4月22日
摘要:
【@.1 简介】 如果是做底层嵌入式开发的人,对于函数的可重入性在多任务系统下的理解应该是比较深刻的,如果不理解清楚任务是如何调度的,任务之间的通讯机制是怎样的,那之后的系统设计就无从下手。如果是经常做上层开发的人,可能不需要去搞清楚界面的主函数里到底干了什么,也不需要搞懂开始多线程之后对函数本身的可重入性有什么要求。所以我在着手写了上一篇博客《Windows平台下Glade+GTK开发环境的搭... 阅读全文
2013年4月16日
摘要:
【@.1 MVVM设计模式与Glade】 做上层软件开发的程序员可能对于MVVM模式比较熟悉,这是一种经典的软件设计模式,很好的将用户界面与后台处理之间分层开,通过属性、事件绑定这种统一的"接口"将软件重新组装起来,将原本看上去很混乱很冗余的软件开发流程抽象出来,以一种统一而又合理的思想来组织软件开发。下面截自wiki的一幅图简单说明了MVVM模式的组织结构。 View层提供了人机交互界面,... 阅读全文
2013年4月1日
摘要:
【@.1 任务调度时机】 之前的一篇文章分析了具体的uCOS-II中的任务切换机制,是从函数调用的角度上分析的。这次我具体从整个程序运行的时间上来看,分析多种任务调度发生的时机。以下所有图片均可点击放大观察。 所有图中红色箭头表示中断级的任务切换,蓝色箭头表示任务级的中断切换。 1.仅有一个任务,这种情况最简单。假设时钟节拍是1000次每秒,由定时中断产生,当节拍的时钟服务程序结束时会... 阅读全文
2013年3月28日
摘要:
【@.1 移植步骤】 网上关于STM32的移植工程很多,不过实际上很多移植工程其中的中断都不能用的,因为没有把STM32中断入口地址与uCOS-II的中断管理机制联系在一起。估计很多移植工程只是简单的写了些跑马灯就好了,没有具体写中断函数测试。这里的移植过程跟我之前做过的LPC2119移植过程类似,也是改文件,改函数名,但是还是那句话,如果你不了解CPU的内核机制,中断机制,以及OS的任务调度原... 阅读全文
摘要:
【@.1 移植准备】 目标CPU:LPC2119。ARM7TDMI,最高主频60MHz,Flash128KB,RAM20KB,ARM7系列的中断机制可以参考我的这篇文章<uCOS-II的中断-ARM7实现中断嵌套的方法探究>。 OS:uCOS-II,具体内核版本参考官网。应该已经出到2.90以上了,不过移植时的版本可能没这么高。对于uCOS-II的任务切换机制可以参考我的这篇文章<uCOS-I... 阅读全文
摘要:
【@.1 函数周期与死循环】 一般函数的生命周期很简单,从开始调用函数起,直到函数返回,即结束。这样一来就完成了这个函数的使命,它也就不再需要了。对于一般的函数就是这样,但是回过头想想,对于一个系统、OS、或者工业控制中的一个控制器重的系统个,函数返回是很轻易很随便的就能返回吗?返回就意味着函数结束,死亡,若是想系统这样一个很大的函数,它的返回就意味着系统结束。因此,对于系统的函数返... 阅读全文
2013年3月27日
摘要:
【@.1 中断嵌套与CPU支持】 在uCOS-II,或者是任何一个可剥夺型OS系统中,中断嵌套是一个必须要解决的问题。从结论上来说,并不是所有的CPU都支持中断嵌套的,即便是ARM系列内核。对于ARM7系列,例如LPC2xxx系列芯片,硬件上是不支持中断嵌套的,而对于新的CortexM3系列,中断嵌套是可配置的,但是中断嵌套时保存现场的操作并不完整,并没有把R0~R15所有寄存器都保存到堆栈中,... 阅读全文
2013年3月26日
摘要:
【@.1 指针与动态内存管理】 在C语言中的指针若不经过初始化是无法进行操作的,在编译时甚至不会报错,但是一旦运行到这里时就会出现程序错误死机。所以对于指针的操作一定要首先初始化再赋值。考虑如下代码: void foo1(void){ unsigned char * pdata; ... *pdata = 0x0f;}当运行到pdata赋值时由于没有初始化,程序必死。当然这还... 阅读全文
2013年1月4日
摘要:
【@.1 可变形参个数函数】 C语言中,即使使用void*作为形参,也只能起到扩展形参类型的作用,而如果想要改变形参的个数呢?如果是C++的话就会很方便的通过函数的多态来实现这一功能,但是在C语言中实现起来就比较麻烦了。但并不是不可以实现,而是一般C编程没多少人用而已。考虑一个求平均数的函数,形参随便传入任意多个int类型的数,返回他们的平均值,用C语言应该怎么实现?这就需要用到可变形参个数的函... 阅读全文
2012年12月6日
摘要:
【@.1 结构体对齐】 @->1.1 如果你看过我的这一篇博客,一定会对字节的大小端对齐方式有了重新的认识。简单回顾一下,对于我们常用的小端对齐方式,一个数据类型其高位数据存放在地址高位,地位数据在地址低位,如下图所示↓ 这种规律对于我们的基本数据类型是很好理解的,但是对于像结构、联合等一类聚合类型(Aggregate)来说,存储时在内存的排布是怎样的?大小又是怎样的?我们来做实验。... 阅读全文
2012年12月2日
摘要:
【@.1 从位带操作开始】 初接触STM32的人一定花了不少时间用于理解其位带操作(bit banding)的原理与步骤。位带操作允许编程人员以字的单位读/写单一bit位。回想我们平时对于一个bit位的操作比如:↓ @-> PIN0 |= (1<<3); @-> PIN0 &= ~(1<<5); 虽然这只是一行代码,但是实际上这一行做了好几步的工作。比如第一行,首先读出当前PIN0... 阅读全文
2012年11月24日
摘要:
_【@. 目录】 @.1 开篇 @.2 MDK工程建立 @.3 Visual Studio工程建立 @.4 Eclipse工程建立 @.5 工程模板实例:标准库GPIO实例讲解、仿真、下载 @.6 工程模板下载 【@.3 Visual Studio工程建立】 这里用Visual Studio绝对是那大炮打蚊子,浪费资源。谁会专门为了写几句代码安装一个庞大的Visual St... 阅读全文