ifconfig · 2021年12月29日

【XR806开发板试用】硬件定时器与OS定时器使用+注意问题

学习一款MCU,首先习惯学习它的外设,这里XR806的外设有一些Demo是在device\xradio\xr806\xr_skylark\project\example目录下的,但是直接编译这个目录下的例程,是会有问题的,也把问题发在了全志的论坛:问题

但目前没有解决,所以,就把相应的例程移植到led的例程中可以编译成功.

先上代码.

main的代码如下:

#include <stdio.h>
#include "ohos_init.h"
#include "kernel/os/os.h"
#include "iot_gpio.h"
#include "kernel/os/os_timer.h"
//#include "driver/chip/hal_gpio.h"
#include "driver/chip/hal_timer.h"
#include "driver/chip/hal_i2c.h"

static OS_Thread_t g_main_thread;

#define GPIO_ID_PA21 21

#define TIMERID TIMER0_ID
#define HFCLOCK 24000000 /*External clock frequency (Hz)*/
#define CLK_PRESCALER 4     /*clock prescale*/
#define COUNT_TIME 1     /*timer count down time (second)*/
uint32_t sec_count;

#define IIC_ID I2C0_ID
#define IIC_FREQ 200000
#define IIC_AT24C16_ADDR 0x50
#define IIC_AT24C16_PAGE_SIZE (16)

OS_Timer_t os_timer;//=0x1234;
uint32_t os_sec_count=0;
void os_timer_callback(void *arg)
{
    os_sec_count++;
    printf("os timer irq: %d\n\r", (int)os_sec_count);
    IoTGpioSetOutputVal(12, os_sec_count%2);
}
void os_timer_test(void)
{
    OS_Status status = OS_OK;
    status = OS_TimerCreate(&os_timer, OS_TIMER_PERIODIC, os_timer_callback, NULL, 1000);
    printf("os timer int error %d\n", status);
    status = OS_TimerStart(&os_timer);
    printf("os timer int error %d\n", status);
}
#if 1
void timer_callback(void *arg)
{
    sec_count++;
    printf(" timer irq: %d\n\r", sec_count);
    IoTGpioSetOutputVal(11, sec_count%2);
}
int timer_init(void)
{
    HAL_Status status = HAL_ERROR;
    TIMER_InitParam param;

    param.arg = NULL;
    param.callback = timer_callback;
    param.cfg = HAL_TIMER_MakeInitCfg(TIMER_MODE_REPEAT,      /*timer mode*/
                                      TIMER_CLK_SRC_HFCLK,      /*HFCLOCK*/
                                      TIMER_CLK_PRESCALER_4); /*CLK_PRESCALER*/
    param.isEnableIRQ = 1;
    param.period = COUNT_TIME * (HFCLOCK / CLK_PRESCALER);

    status = HAL_TIMER_Init(TIMERID, &param);
    if (status != HAL_OK)
        printf("timer int error %d\n", status);

    return status;
}

int timer_deinit(void)
{
    HAL_Status status = HAL_ERROR;

    status = HAL_TIMER_DeInit(TIMERID);
    if (status != HAL_OK)
        printf("timer deinit error %d\n", status);

    return status;
}
#endif
static void MainThread(void *arg)
{
    printf("LED test start\r\n");
    IoTGpioInit(GPIO_ID_PA21);
    IoTGpioSetDir(GPIO_ID_PA21, IOT_GPIO_DIR_OUT);

    IoTGpioInit(11);
    IoTGpioSetDir(11, IOT_GPIO_DIR_OUT);

    IoTGpioInit(12);
    IoTGpioSetDir(12, IOT_GPIO_DIR_OUT);



    timer_init();
    HAL_TIMER_Start(TIMERID);
    os_timer_test();
    while (1)
    {
        IoTGpioSetOutputVal(21, 1);
        OS_MSleep(500);
        IoTGpioSetOutputVal(21, 0);
        OS_MSleep(500);
    }
}

void LEDMain(void)
{
    printf("LED Test Start\n");
    if (OS_ThreadCreate(&g_main_thread, "MainThread", MainThread, NULL,
                        OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK)
    {
        printf("[ERR] Create MainThread Failed\n");
    }
}

SYS_RUN(LEDMain);

这个程序烧到板子上,发现两个定时器的时间不一样,串口输出如下 .
image.png

这就很奇怪了,例程中都是定时1s,于是都翻转个IO口进行测试.
波形如下,可以看到os定时器的时间是对的,硬件定时器的时间小于1S
IMG_20211229_170813.jpg
IMG_20211229_170738.jpg

于是在程序开始的地方,注意到

#define HFCLOCK 24000000

但XR806的晶振是40M才对.所以,修改后

#define HFCLOCK 40000000 

定时器时间才对上了.

image.png

不知道这个是例程的bug,还是这个例程原来是针对的是其他的板子的.

疑问

目前这个芯片折腾了有一段时间了,感觉整个的SDK的架构不是很明晰,在例程中直接使用鸿蒙的系统中的一些函数,却无法使用,如鸿蒙OS的定时器使用的是OsSwtmrTaskCreate,但在SDK中使用的是OS_TimerCreate,这个源码是在:

xr806_openharmony/device/xradio/xr806/xr_skylark/src/kernel/os/FreeRTOS

这看上去是FreeRTOS的内核中的函数,而不是鸿蒙的.而且看源码中的前面的注释,也真不是鸿蒙的.

/**
 * @file os_timer.c
 * @author XRADIO IOT WLAN Team
 */

/*
 * Copyright (C) 2017 XRADIO TECHNOLOGY CO., LTD. All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *    1. Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *    2. Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the
 *       distribution.
 *    3. Neither the name of XRADIO TECHNOLOGY CO., LTD. nor the names of
 *       its contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

真正的鸿蒙的内核源码应该是在:

/xr806_openharmony/kernel/liteos_m/kernel/src

但在这个目录下,并没有发现 .d与.o的文件,说明这里的文件是没有编译的.

所以.这里所说的支持鸿蒙,到底是支持的哪些,有一些搞不懂了.

推荐阅读
关注数
13126
内容数
140
全志XR806开发板相关的知识介绍以及应用专栏。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息