OS-ucos

本文详细介绍了一种基于44b0x处理器的uCos-II实时操作系统移植方法,涵盖系统时钟配置、中断处理、任务管理、内存分配等方面的技术要点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于44b0xucos开发,网上开源很多,可以参考,但是最有益的是一切从头自己搭建,自己调试!环境基于ADS+wiggler调试。

平台最主要的是清晰,一目了然,而且换不同cpu不同的os,代码结构不需要重大更改,比如ucos升级到新的版本,直接替换相应目录即可;比如如果应用比较大,需要更换操作系统,kernel的系统api做封装就不用担心了;比如cpu芯片更换或者升级,只需要更换相应的bsp;总之改动做到最小

搭建的环境目录如下:

ucos目录是官方os代码

bsp/common目录是ucos的基于ARM7的官方SDK

bsp/cpu目录是三星44b0x的官方SDK包,增加bsp.c文件,包含系统的外部中断处理函数,以及系统时钟的实现,延时函数,当然cpu的初始化函数port_init也在此实现

kernel目录是提供os的系统API封装,printfudelay

app目录是main函数入口,主要是多任务调度以及消息队列

file://D:/ucos2    (7 folders, 2 files, 445.72 KB, 4.46 MB in total.)

ucos.elf    234.92 KB

ucos2.mcp    210.81 KB

├─app    (0 folders, 2 files, 15.86 KB, 15.86 KB in total.)

main.c    7.64 KB

main.c.bak    8.22 KB

├─bsp    (2 folders, 0 files, 0 bytes, 125.74 KB in total.)

├─cpu    (2 folders, 0 files, 0 bytes, 67.50 KB in total.)

│├─src    (0 folders, 5 files, 37.76 KB, 37.76 KB in total.)

││44binit.s    13.63 KB

││44blib.c    8.38 KB

││bsp.c    4.87 KB

││bsp.c.bak    3.00 KB

││rtl8019.c    7.88 KB

│└─inc    (0 folders, 11 files, 29.73 KB, 29.73 KB in total.)

│44b.h    15.28 KB

│44blib.h    1.54 KB

│bsp.h    460 bytes

│bsp.h.bak    486 bytes

│def.h    434 bytes

│includes.h    1.30 KB

│Memcfg.s    2.49 KB

│Option.h    837 bytes

│Option.s    1.22 KB

│rtl8019.h    5.02 KB

│types.h    751 bytes

└─common    (3 folders, 0 files, 0 bytes, 58.24 KB in total.)

├─src    (2 folders, 1 files, 11.97 KB, 31.38 KB in total.)

│os_cpu_c.c    11.97 KB

│├─arm    (0 folders, 1 files, 9.95 KB, 9.95 KB in total.)

││os_cpu_a.S    9.95 KB

│└─gcc    (0 folders, 1 files, 9.46 KB, 9.46 KB in total.)

│os_cpu_a.Sgcc    9.46 KB

├─arm    (0 folders, 1 files, 4.04 KB, 4.04 KB in total.)

│ac_halt.c    4.04 KB

└─inc    (0 folders, 5 files, 22.82 KB, 22.82 KB in total.)

armdefs.h    2.21 KB

def.h    2.59 KB

halt.h    2.57 KB

os_cfg.h    8.15 KB

os_cpu.h    7.30 KB

├─kernel    (0 folders, 2 files, 502 bytes, 502 bytes in total.)

xkernel.c    223 bytes

xkernel.h    279 bytes

├─lwip-1.1.0    (2 folders, 4 files, 22.65 KB, 659.37 KB in total.)

.......

├─shell    (0 folders, 3 files, 36.02 KB, 36.02 KB in total.)

cmds.c    15.17 KB

shell.c    18.83 KB

shell.h    2.01 KB

├─ucos    (0 folders, 10 files, 294.83 KB, 294.83 KB in total.)

os_core.c    43.44 KB

os_flag.c    43.76 KB

os_mbox.c    23.29 KB

os_mem.c    13.79 KB

os_mutex.c    27.26 KB

os_q.c    33.79 KB

os_sem.c    19.04 KB

os_task.c    35.21 KB

os_time.c    9.68 KB

ucos_ii.h    45.59 KB

└─

1.        移植流程

内部时钟:先搭好ucosbsp,不需要修改任何文件,新建main.c,新建两个task看能否在之间调度;显然是不可能的,所以动手写的第一行代码就是系统时钟函数,新建bsp.c,作为三星的SDK的补充来用,用timer0做系统tick,定时会产生内部中断,__vT0Interrupt是中断处理函数,这里挂ucosBSPAPI就行,当然别忘记了rINTMSK = ~(BIT_GLOBAL |BIT_TIMER0); 打开timer0中断,至于中断方式是向量中断还是非向量中断方式,在interrupt文章中记录,具体配置参考注释

rTCFG0=(MCLK>>1)/1000000-1;

/* 此为预分频值,MCLK为外部时钟频率 */

rTCFG1=0x00000000;

/* mux0 = 1/2 */

/* 定时器0输入时钟频率=MCLK/(预分频值+1)/mux0,=MCLK/[(MCLK>>1)/1000000-1 + 1]/(1/2),计算得输入时钟频率为1M */

/* 实际应用中是根据需要的输入时钟频率来赋值1000000 */      

rTCNTB0= 1000000/OS_TICKS_PER_SEC;

/* 每一秒有OS_TICKS_PER_SECtick产生,这个根据实际需要更改 */ 

rTCMPB0= 0x0;

rTCON=0x2;           

rTCON=0x9;

/* 内部中断控制寄存器配置 */         

pISR_TIMER0= (unsigned)__vT0Interrupt;

 

中断:有点小复杂,单独新开一篇中断的总结

中断函数添加之后,调试用的printf,就是一个最基础的驱动了

int printf(const char* pbFmt, ...)

{

    va_list pArg;

    char abString[256];

    int rv;

 

    va_start(pArg, pbFmt);

    /* 根据最后一个固定参数取可变参数表的首地址,以后可以根据该首地址逐一取各变量地址;此时pArg指向第一个可变参数 */

    rv = vsprintf(abString, pbFmt, pArg);

    /* sprintf一样*/

    Uart_SendString(abString);

    /* 调底层驱动 */

    va_end(pArg);

 

    return rv;

}

 

串口接收就需要起一个dbg_entrytask,为了方便调试,这里是porting一个命令行过来,这几个函数是从RTEMS移植过来的,可以自行添加调试命令,Uart_GetString(line)函数也可以实现记忆小功能,包括上下左右等键

 

void dbg_entry(void* Id)

{

    unsigned char line[MAX_COUNT];

    unsigned char * dbg_prompt_s ;

 

    dbg_prompt_s = (unsigned char *) "dbg> " ;

    printf("OSPrioCur = %d/n", OSPrioCur);

 

    memset(line, 0, sizeof(line));

 

    shell_add_cmd(NULL, NULL, NULL, NULL); /* init the chain list*/

    /* 这个就是porting过来的一个命令行调试函数 */

    for (; ;)

    {

        printf((char *) dbg_prompt_s);

        if (Uart_GetString(line) < 0)    /* 底层驱动函数 */

            break;         

        if ((line[0] == 0) || (line[0] == '/n'))

            continue;

        process_line(line);

        /* 这个也是porting过来的解析命令行调试函数 */

    }

}

 

内存分配:挂接预先分配好的44b0x的堆的首地址和尾地址

延时函数,因为OSTimeDly是基于tick数目来的,所以做一个封装,转换成ms可读性强的API

 

 

 

void udelay(unsigned short ms)

{

    unsigned short ucos_timeout;

 

    if(ms)

    {

        ucos_timeout = (ms * OS_TICKS_PER_SEC)/1000;

 

        if(ucos_timeout < 1)

            ucos_timeout = 1;

        else if(ucos_timeout > 65535)

            ucos_timeout = 65535;

    }

    else

    {

        ucos_timeout = 0;

    }

    OSTimeDly(ucos_timeout);

 

}

ucos的系统api,因为ucos相对简单,任务间通信不复杂的平台采用它最好不过了,任务状态也相对简单----休眠,等待,就绪,运行

首先在os_cfg.h中使能需要用到的api,这里配置至少需要任务,事件,信号量,消息队列,系统心跳数以及时钟函数

#define OS_MAX_TASKS             63    /* Max. number of tasks in your application ...                 */

#define OS_FLAG_EN                1    /* Enable (1) or Disable (0) code generation for EVENT FLAGS    */

#define OS_SEM_EN                 1    /* Enable (1) or Disable (0) code generation for SEMAPHORES     */

#define OS_Q_EN                   1    /* Enable (1) or Disable (0) code generation for QUEUES         */

 

#define OS_TICKS_PER_SEC        200    /* Set the number of ticks in one second                        */

#define OS_TIME_GET_SET_EN        1    /*     Include code for OSTimeGet() and OSTimeSet()             */

 

接下来就创建任务间需要传递的信号量和消息队列,当然任务也根据需要创建,注释代码如下

 

    OS_EVENT* RecTcpQFlag;   

    RecPackedFlag = OSSemCreate(0);

    /* 创建一个信号量 */

    RecUdpQFlag = OSQCreate(&RecUdpQ[0], Q_Max_Size);

    /* 创建一个消息队列,RecUdpQFlag是这个消息队列对应的事件 */

    OSTaskCreate(task1, (void *) &Id1, (OS_STK *) &Stack1[STACKSIZE - 1], 1);

    OSTaskCreate(task2, (void *) &Id2, (OS_STK *) &Stack2[STACKSIZE - 1], 2);

    /* 创建两个任务,STACKSIZE是他们的栈大小,这个时候任务处于休眠状态 */

    FRMWRK_vStartTicker(OS_TICKS_PER_SEC);  /* os_cfg.h */

    /* 起系统的tick */

    OSStart();

    /* 任务非休眠状态了,或等待或就绪或运行 */

 

task1通过UdpTemp = OSQPend(RecUdpQFlag, 0, &eer);处于等待状态,在等待在RecUdpQFlag事件,task2处于运行状态,如果这个时候task2调用一个发送消息队列的函数OSQPost(RecUdpQFlag, (void *) send_buf);task可以顺利的接收数据到UdpTemp

如果这个task2也等待一个事件,并且是在task1中发送的,那么这样就死锁了     

 

void task1(void* Id)

{

    void* UdpTemp;

    U8 eer;

    printf("OSPrioCur = %d/n", OSPrioCur);

 

 

    for (; ;)

    {

        UdpTemp = OSQPend(RecUdpQFlag, 0, &eer);

        /* 0代表tick数,最好的方法是利用(ms * OS_TICKS_PER_SEC)/1000转换一下,ms代表n毫秒,超时后如果还没有得到消息则恢复成就绪状态,并返回error,如果该值设置成零则表示任务将持续地等待消息 */

        if (eer == OS_NO_ERR)

        {

            printf("UdpTemp:0x%x", UdpTemp);

            eer = eer;

        }

    }

}

 

再结合外围接口的驱动代码和文件系统,这样整个平台就搭建起来了,就可以开工写应用代码了,用ucos做应用也只用到这些API了,也足够应付一个普通平台的设计了

 

2.        ucos的移植分析

        EXPORT  OSStartHighRdy

        EXPORT  OSCtxSw

        EXPORT  OSIntCtxSw

        EXPORT  UCOS_IRQHandler   

 

和底层相关的压栈,出栈,挂接中断函数后的处理

 

3.        小结

买公司性质的板子,服务配套好,读书时候的板子是周立功的,平台几乎都帮你搭好了,省了很多事;相反山寨一切都要自己弄,不过更能锻炼人,对整个平台细节都非常清晰

ADS中为了编写烧入flash跑的bin,采用-info totals -ro-base 0 -first 44binit.o(init) 这样烧入不成功的,跳了好久呢,没搞清楚 rorw的不同

MCLK要根据实际硬件来,要不然配置串口的时候波特率后,串口打的是乱码

OS_Q_EN默认的没开启,需要使能,要不然编译出错

uart_initportinit之前就做,因为我中断函数加了打印信息,中断初始化后中断马上来了,这个时候串口没来得及初始化

 

 

内容概要:本文详细探讨了基于MATLAB/SIMULINK的多载波无线通信系统仿真及性能分析,重点研究了以OFDM为代表的多载波技术。文章首先介绍了OFDM的基本原理和系统组成,随后通过仿真平台分析了不同调制方式的抗干扰性能、信道估计算法对系统性能的影响以及同步技术的实现与分析。文中提供了详细的MATLAB代码实现,涵盖OFDM系统的基本仿真、信道估计算法比较、同步算法实现和不同调制方式的性能比较。此外,还讨论了信道特征、OFDM关键技术、信道估计、同步技术和系统级仿真架构,并提出了未来的改进方向,如深度学习增强、混合波形设计和硬件加速方案。; 适合人群:具备无线通信基础知识,尤其是对OFDM技术有一定了解的研究人员和技术人员;从事无线通信系统设计与开发的工程师;高校通信工程专业的高年级本科生和研究生。; 使用场景及目标:①理解OFDM系统的工作原理及其在多径信道环境下的性能表现;②掌握MATLAB/SIMULINK在无线通信系统仿真中的应用;③评估不同调制方式、信道估计算法和同步算法的优劣;④为实际OFDM系统的设计和优化提供理论依据和技术支持。; 其他说明:本文不仅提供了详细的理论分析,还附带了大量的MATLAB代码示例,便于读者动手实践。建议读者在学习过程中结合代码进行调试和实验,以加深对OFDM技术的理解。此外,文中还涉及了一些最新的研究方向和技术趋势,如AI增强和毫米波通信,为读者提供了更广阔的视野。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值