个人建站教程,棋牌游戏网站怎么做,唐山网站建设价格,小程序开发教程pdf目录
uCOSIII简介#xff1a;
准备工作#xff1a;
准备基础工程#xff1a;
UCOSIII工程源码#xff1a;
UCOSIII移植#xff1a;
向基础工程中添加相应的文件夹
向工程中添加分组
常见问题#xff1a;
下载验证#xff1a;
uCOSIII简介#xff1a;
UCOS-I…目录
uCOSIII简介
准备工作
准备基础工程
UCOSIII工程源码
UCOSIII移植
向基础工程中添加相应的文件夹
向工程中添加分组
常见问题
下载验证
uCOSIII简介
UCOS-III 是UCOS系统的第三代内核。 可剥夺式任务管理总是执行当前就绪任务中优先级最高的任务。同优先级任务的时间片轮转调度UCOS-III允许一个任务优先级被多个任务使用当这个优先级处在最高就绪态的时候操作系统会轮流的调度处在这个优先级级别里面的所有任务让优先级里面的每一个任务运行由用户指定的一段时间长度这个时间通常称为时间片。这个特性也是UCOS-III与UCOS-II的一个重要区别。II中不支持一个优先级内多个任务。极短的中断时间UCOS-III采用的是锁定内核调度的方式而不是关中断的方式来保护临界区代码段这样就可以把关中断的时间降至最低使得UCOS-III能够非常快速的响应中断请求。任务数目不受限制UCOS-III自己本身是没有任务数目的限制的。但是实际情况下任务数目会受到硬件比如CPU的影响不可能是无限制的。每个任务都占用数据结构内存优先级数目不受限制UCOS-III本身支持无限大的任务优先级。内核对象数目不受限制UCOS-III允许定义任意数目的内核对象。内核对象常见的包括任务互斥信号量事件标志组消息队列定时器和存储块等等。软件定时器用户可以任意定义“单次”和“周期”型定时器定时器是一个递减计数器递减到零就会执行预先定义好的操作。每个定时器都可以指定所需操作周期型定时器在递减到零时会执行指定操作并自动重置计数器值。同时等待多个内核对象UCOSIII允许一个任务同时等待多个事件也就是说一个任务能够挂起多个信号量或者消息队列上当其中任何一个等待的时间发生时等待任务就会被唤醒。直接向任务发送信号UCOSIII允许中断或者任务直接给另一个任务发送信号避免创建和使用诸如信号量或者事件标志等内和对象作为向其他任务发送信号的中介该特征有效的提高了系统的性能。直接向任务发送信息UCOSIII 允许中断或任务直接给另一个任务发送消息避免创建和使用消息队列作为中介。任务寄存器每个任务都可以设定若干个“任务定时器”任务寄存器和 CPU 硬件寄存器是不同的主要用来保存各个任务的错误信息ID 识别信息中断关闭时间的测量结果等。任务级时间节拍处理UCOSIII的时钟节是通过一个专门的任务完成的定时中断仅触发该任务。将延时处理和超时判断放在任务级代码完成。极大的减少了中断延时时间。防止锁死所有UCOSIII的 等待功能都提供了一个超时检测机制有效的避免了锁死。时间戳UCOSIII需要一个16位或者32位的自由运行的计数器时基计数器来实现时间测量在系统运行时可以通过读取该计数器来测量某一个时间信息。 准备工作
准备基础工程 首先需要准备一个移植的基础工程使用库函数版本的跑马灯实验。 UCOSIII工程源码 在移植uCOS-III之前首先要获取它的源码。其源码可以从Micrium 的官方网站www.micrium.com得到。μC/OS-III 是一个操作系统其实也可以理解成一个软件库它可以移植到多种硬件平台如 M3、M4、M7 内核的 STM32或者 ARM9 等等其他芯片。核心代码肯定是一致的但是针对不同的处理器肯定要不同的实现部分。若要从 0 开始移植 μC/OS-III 到目标硬件平台需要极大的精力和软件水平。为了方便移植我们建议直接下载官网上移植好的基于目标平台的例子。 打开UCOSIII源码的压缩包 EvalBoards: 主要内容是基于评估板厂商的板子的应用实现在我们移植中有部分文件是可以用来使用的在路径红色方框中我们可以看到官方移植的评估板芯片是STM32F107,但是不影响我们在STM32F103开发板上进行移植 另一个红色方框中的八个文件就是我们所需要添加到工程中的文件 uC-CPU: 这是和 CPU 紧密相关的文件里边的一些文件很重要都是我们需要使用的 cpu_core.h文件中包含了适用于所有CPU架构的C代码也就是常说的通用代码。这是一个很重要的文件主要包含的函数都是通过CPU进行命名的时间戳的计算等等跟CPU底层的移植没有太大依靠硬件实现这里采用C语言方式以防止某些CPU不支持前导零指令该文件还包含用来监测中断关闭事件的函数(中断关闭和打开分别由 CPU_CRITICAL_ENTER()和 CPU_CRITICAL_EXIT()两个宏实现)。cpu_core.h 文件包含 cpu_core.c 中函数的原型声明以及其他的一些变量的定义。cpu_def.h 文件包含 uC/CPU 模块使用的各种#define 常量。 在 ARM-Cortex-M3文件夹下存在 cpu_c.c 一些对不同编译器移植相关的文件有 GNU、IAR、RealView里面都有一些很重要的文件目前我们使用的开发环境是 MDKkeil所以我们选择 RealView 文件夹。 点击ARM-cortex-M3文件夹中常用MDK开发故选择Realview可以看到如下所示 cpu.h文件中包含了一些类型的定义使用UCOSIII和其他的模块可以CPU架构和编译器子宽无关。cpu_a.asm 文件包含了一些用汇编语言编写的函数可用来开中断和关中断计算前导零(如果 CPU支持这条指令)以及其他一些只能用汇编语言编写的与 CPU 相关的函数这个文件中的函数可以从 C 代码中调用。cpuc.c 文件包含了一些基于特定 CPU 架构但为了可移植而用 C 语言编写的函数 C 代码 uC-LIB 文件夹是Micrium 公司提供的官方库诸如字符串操作、内存操作等接口可用可不用。一般能用于代替标准库中的一些函数使得在嵌入式中应用更加方便安全。 uCOS-III 该文件夹是操作系统的内核文件夹都是系统核心文件。这些文件是我们全部需要的。文件这个文件夹中有两个文件Ports 和 Sourece μC/OS 是软件我们的开发板是硬件软硬件必须有桥梁来连接这些与处理器架构相关的代码可以称之为 RTOS 硬件接口层它们位于 μC/OS-III-Ports 文件夹下在不同的编译器中选择的是不同的我们不需要去理会官方已经帮我们写好了。 Source 文件夹里面为 UCOSIII 3.0.3的源码 各个文件的作用如下表所示在学习的过程中慢慢了解 UCOSIII移植
向基础工程中添加相应的文件夹
在基础工程文件夹中新建一个UCOSIII文件夹然后将我们下载的官方移植工程中的uC-CPU、uC-LIB 和 UCOS-III 这三个文件复制到工程中 在UCOSIII文件中在建立两个文件夹UCOS_BSP和UCOS_CONFIG 将下边路径下的八个文件放到UCOS_CINFIG中 同样复制 Micrium 官方移植好的工程中的相关文件到 UCOS_BSP 文件下需要复制的文件路径为Micrium\Software\EvalBoards\Micrium\uC-Eval-STM32F107\BSP将下边两个文件移植到自己的所建的UCOSIII_BSP的目录当中。 向工程中添加分组
根据个人习惯向目录中添加6个分组 工程中的分组建立完了之后我们就要向新建的各个分组当中添加文件了
UCOSIII_BSP添加路径UCOSIII\UCOS_BSP里的bsp.c添加进去UCOSIII_CPU添加路径UCOSIII\UCOS_CPU里的cpu_core.c添加进去并继续进入目录ARM-Cortex-M4\RealView选择cpu_a.sam\cpu_c.c两个文件添加进去UCOSIII_LIB添加路径:UCOSIII\uC-LIB里的继续点击Ports\ARM-Cortex-M4\RealView,选择All file,添加lib_mem_a.asm文件UCOSIII_CORE添加路径UCOSIII\uCOS-III\Source添加所有文件UCOSIII_PORT添加路径UCOSIII\uCOS-III\Ports\ARM-Cortex-M4\Generic\RealView选择All file,添加所有文件UCOS_CONFIG添加路径UCOSIII\UCOS_CONFIG选择All file,添加所有文件
注意此时有的文件会带一把钥匙表示不能修改修改方法返回工程文件点击属性把只读去掉即可进入工程对其修改
上面完成了对.c文件的添加然后是.h头文件路径的添加 做完这一步我们编辑一下整个工程结果显示很多错误
常见问题
下边是正点原子对一些错误的解释 这里我还要补充一个错误就是下边这个问题 这个问题我推荐看一下这篇博客http://t.csdnimg.cn/E9VvQ
最后一步就是在注意在os_cpu_c.c中添加#include includes.h //添加头文件 移植完成后就需要编写测试软件测试我们移植是否正确我们建立 3 个任务其中两个任务分别用于 LED0 和 LED1 闪烁另外一个任务用于测试浮点计算。
例程main.c #include led.h
#include delay.h
#include sys.h
#include usart.h
#include includes.h
//UCOSIII中以下优先级用户程序不能使用ALIENTEK
//将这些优先级分配给了UCOSIII的5个系统内部任务
//优先级0中断服务服务管理任务 OS_IntQTask()
//优先级1时钟节拍任务 OS_TickTask()
//优先级2定时任务 OS_TmrTask()
//优先级OS_CFG_PRIO_MAX-2统计任务 OS_StatTask()
//优先级OS_CFG_PRIO_MAX-1空闲任务 OS_IdleTask()
//技术支持www.openedv.com
//淘宝店铺http://eboard.taobao.com
//广州市星翼电子科技有限公司
//作者正点原子 ALIENTEK//任务优先级
#define START_TASK_PRIO 3
//任务堆栈大小
#define START_STK_SIZE 512
//任务控制块
OS_TCB StartTaskTCB;
//任务堆栈
CPU_STK START_TASK_STK[START_STK_SIZE];
//任务函数
void start_task(void *p_arg);//任务优先级
#define LED0_TASK_PRIO 4
//任务堆栈大小
#define LED0_STK_SIZE 128
//任务控制块
OS_TCB Led0TaskTCB;
//任务堆栈
CPU_STK LED0_TASK_STK[LED0_STK_SIZE];
void led0_task(void *p_arg);//任务优先级
#define LED1_TASK_PRIO 5
//任务堆栈大小
#define LED1_STK_SIZE 128
//任务控制块
OS_TCB Led1TaskTCB;
//任务堆栈
CPU_STK LED1_TASK_STK[LED1_STK_SIZE];
//任务函数
void led1_task(void *p_arg);//任务优先级
#define FLOAT_TASK_PRIO 6
//任务堆栈大小
#define FLOAT_STK_SIZE 128
//任务控制块
OS_TCB FloatTaskTCB;
//任务堆栈
__align(8) CPU_STK FLOAT_TASK_STK[FLOAT_STK_SIZE];
//任务函数
void float_task(void *p_arg);int main(void)
{OS_ERR err;CPU_SR_ALLOC();delay_init(); //延时初始化NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组配置uart_init(115200); //串口波特率设置LED_Init(); //LED初始化OSInit(err); //初始化UCOSIIIOS_CRITICAL_ENTER();//进入临界区//创建开始任务OSTaskCreate((OS_TCB * )StartTaskTCB, //任务控制块(CPU_CHAR * )start task, //任务名字(OS_TASK_PTR )start_task, //任务函数(void * )0, //传递给任务函数的参数(OS_PRIO )START_TASK_PRIO, //任务优先级(CPU_STK * )START_TASK_STK[0], //任务堆栈基地址(CPU_STK_SIZE)START_STK_SIZE/10, //任务堆栈深度限位(CPU_STK_SIZE)START_STK_SIZE, //任务堆栈大小(OS_MSG_QTY )0, //任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息(OS_TICK )0, //当使能时间片轮转时的时间片长度为0时为默认长度(void * )0, //用户补充的存储区(OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项(OS_ERR * )err); //存放该函数错误时的返回值OS_CRITICAL_EXIT(); //退出临界区 OSStart(err); //开启UCOSIIIwhile(1);
}//开始任务函数
void start_task(void *p_arg)
{OS_ERR err;CPU_SR_ALLOC();p_arg p_arg;CPU_Init();
#if OS_CFG_STAT_TASK_EN 0uOSStatTaskCPUUsageInit(err); //统计任务
#endif#ifdef CPU_CFG_INT_DIS_MEAS_EN //如果使能了测量中断关闭时间CPU_IntDisMeasMaxCurReset();
#endif#if OS_CFG_SCHED_ROUND_ROBIN_EN //当使用时间片轮转的时候//使能时间片轮转调度功能,时间片长度为1个系统时钟节拍既1*55msOSSchedRoundRobinCfg(DEF_ENABLED,1,err);
#endif OS_CRITICAL_ENTER(); //进入临界区//创建LED0任务OSTaskCreate((OS_TCB * )Led0TaskTCB, (CPU_CHAR * )led0 task, (OS_TASK_PTR )led0_task, (void * )0, (OS_PRIO )LED0_TASK_PRIO, (CPU_STK * )LED0_TASK_STK[0], (CPU_STK_SIZE)LED0_STK_SIZE/10, (CPU_STK_SIZE)LED0_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,(OS_ERR * )err); //创建LED1任务OSTaskCreate((OS_TCB * )Led1TaskTCB, (CPU_CHAR * )led1 task, (OS_TASK_PTR )led1_task, (void * )0, (OS_PRIO )LED1_TASK_PRIO, (CPU_STK * )LED1_TASK_STK[0], (CPU_STK_SIZE)LED1_STK_SIZE/10, (CPU_STK_SIZE)LED1_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )err); //创建浮点测试任务OSTaskCreate((OS_TCB * )FloatTaskTCB, (CPU_CHAR * )float test task, (OS_TASK_PTR )float_task, (void * )0, (OS_PRIO )FLOAT_TASK_PRIO, (CPU_STK * )FLOAT_TASK_STK[0], (CPU_STK_SIZE)FLOAT_STK_SIZE/10, (CPU_STK_SIZE)FLOAT_STK_SIZE, (OS_MSG_QTY )0, (OS_TICK )0, (void * )0, (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR * )err); OS_TaskSuspend((OS_TCB*)StartTaskTCB,err); //挂起开始任务 OS_CRITICAL_EXIT(); //进入临界区
}//led0任务函数
void led0_task(void *p_arg)
{OS_ERR err;p_arg p_arg;while(1){LED00;OSTimeDlyHMSM(0,0,0,200,OS_OPT_TIME_HMSM_STRICT,err); //延时200msLED01;OSTimeDlyHMSM(0,0,0,500,OS_OPT_TIME_HMSM_STRICT,err); //延时500ms}
}//led1任务函数
void led1_task(void *p_arg)
{OS_ERR err;p_arg p_arg;while(1){LED1~LED1;OSTimeDlyHMSM(0,0,0,500,OS_OPT_TIME_HMSM_STRICT,err); //延时500ms}
}//浮点测试任务
void float_task(void *p_arg)
{CPU_SR_ALLOC();static float float_num0.01;while(1){float_num0.01f;OS_CRITICAL_ENTER(); //进入临界区printf(float_num的值为: %.4f\r\n,float_num);OS_CRITICAL_EXIT(); //退出临界区delay_ms(500); //延时500ms}
}下载验证
编译下载之后打开串口助手我们可以看到LED1和led0按照设定好的时间闪烁串口有信息输出以0.01递增 例程
链接https://pan.baidu.com/s/1x1foTZvqQjdjv3QAsGX5QQ 提取码k9jr
正点原子的UCOSIII开发手册
链接https://pan.baidu.com/s/1Za1q0H8giaA-Xkjpcw7Wrg 提取码wt2f