Tencentos Tiny EVB MX板学习第一篇Hello_world解析

得意时要看淡,失意时要看开。不论得意失意,切莫大意;不论成功失败,切莫止步。志得意满时,需要的是淡然,给自己留一条退路;失意落魄时,需要的是泰然,给自己觅一条出路Tencentos Tiny EVB MX板学习第一篇Hello_world解析,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

关于TencentOS tiny 基础内核实验

本次介绍的是关于TencentOS tiny 基础内核实验 ——hello_world实验

#Tiny EVB 板拿到以后会有两个途径学习
[Tencentos Tiny官网](https://gitee.com/TencentOS/TencentOS-tiny)和公众号IOTCluB获取官方资料

TencentOS tiny官方开源仓下载源码,地址为: https://github.com/Tencent/TencentOS-tiny
进入 <TencentOS_tiny\board\TencentOS_tiny_EVB_MX_Plus\KEIL\hello_world> 目录,打开
TencentOS_tiny.uvprojx 工程TencentOS_tiny.uvprojx 工程
:就可以编辑下载运行。官方给出运行结果:在 PC 的串口助手中可以看到 TencentOS tiny 的两个任务交替运行,打印消息并完成任务计数,如下图所示:运行结果
当然它屏幕也显示了LOGO。但是作为要学习的小白,这就能打发我们吗?不行!!!
来一起看看运行原理——为啥打印这些,要怎么做到这些,懂做才懂改。
#一个从源头查起,main.c
main.c
#主要看 int main函数:

board_init();	//板子初始化
    printf("Welcome to TencentOS tiny\r\n");	//串口打印
    osKernelInitialize(); // TOS Tiny kernel initialize   TOS Tiny内核初始化
    osThreadCreate(osThread(application_entry), NULL); // Create TOS Tiny task创建TOS Tiny任务
    osKernelStart(); // Start TOS Tiny    TOS Tiny开始

#先看board_init(); //板子初始化:
<TencentOS_tiny\board\TencentOS_tiny_EVB_MX_Plus\BSP\Src\mcu_onit.c>文件中44行左右有相关函数,这里我对它进行了简单标注方便阅读:

				void board_init(void)
					{
					  char *str = "TencentOS tiny";			//定义字符串
					
					  HAL_Init();												//HAL库初始化
					  SystemClock_Config();						//系统时钟配置
					  MX_GPIO_Init();									//GPIO配置
					  //MX_ADC1_Init();								//ADC初始化
					  //MX_DAC1_Init();								//DAC初始化
					  //MX_I2C1_Init();								//IIC初始化
					  //MX_LPUART1_UART_Init();				//串口1初始化
					 // MX_USART2_UART_Init();				//串口2初始化
					 MX_USART3_UART_Init();						//串口3初始化
					  MX_TIM6_Init();									//计时器6初始化
					  //MX_SPI1_Init();								//SPI1初始化
					  //MX_SPI3_Init();								//spi3初始化
					  //DHT11_Init();									//外设DHT11初始化	
					  OLED_Init();										//OLED显示屏幕初始化
					  OLED_Clear();										//OLED清屏
					  OLED_ShowChinese(0,0,0);				//OLED显示字体
					  OLED_ShowChinese(18,0,1);
					  OLED_ShowChinese(36,0,2);
					  OLED_ShowChinese(54,0,3);
					  OLED_ShowChinese(72,0,4);
					  OLED_ShowChinese(90,0,5);
					  OLED_ShowString(0,2,(uint8_t*)str,16); //调用字符串显示
					}

去掉它注解掉的函数,就能很清晰的看出来它用了几种功能:GPIO配置,串口初始化,定时器初始化,OLED初始化与显示。
注:这里的初始化,就是对一些基础设置,跟STM32基础一致,网上资料较全,不在累述。而OLED显示部分,在这里显示字符串,跟串口打印函数相似:OLED_ShowString(X坐标,Y坐标,需要显示的字符串); OLED_ShowChinese(X坐标,Y坐标,显示的字体在字库的位置);
下面看看OLED_ShowChinese函数代码:
//显示汉字

void OLED_ShowChinese(uint8_t x,uint8_t y,uint8_t no)
{      			    
	uint8_t t,adder=0;
	OLED_Set_Pos(x,y);   //定位XY
	for(t=0;t<16;t++)//打印
	{
		OLED_WR_Byte(Hzk[2*no][t],OLED_DATA); 
		adder+=1;
	}
	OLED_Set_Pos(x,y+1);
	for(t=0;t<16;t++)
	{
		OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
		adder+=1;
	}
}

而Hzk字库在oleddfont.h中

{0x40,0x3C,0x10,0xFF,0x10,0x10,0x20,0x10,0x8F,0x78,0x08,0xF8,0x08,0xF8,0x00,0x00},
{0x02,0x06,0x02,0xFF,0x01,0x01,0x04,0x42,0x21,0x18,0x46,0x81,0x40,0x3F,0x00,0x00},/*"物",0*/
/* (16 X 16 , 宋体 )*/

{0x02,0xFE,0x92,0x92,0xFE,0x02,0x00,0x10,0x11,0x16,0xF0,0x14,0x13,0x10,0x00,0x00},
{0x10,0x1F,0x08,0x08,0xFF,0x04,0x81,0x41,0x31,0x0D,0x03,0x0D,0x31,0x41,0x81,0x00},/*"联",1*/
/* (16 X 16 , 宋体 )*/

{0x00,0xFE,0x02,0x22,0x42,0x82,0x72,0x02,0x22,0x42,0x82,0x72,0x02,0xFE,0x00,0x00},
{0x00,0xFF,0x10,0x08,0x06,0x01,0x0E,0x10,0x08,0x06,0x01,0x4E,0x80,0x7F,0x00,0x00},/*"网",2*/
/* (16 X 16 , 宋体 )*/

{0x00,0x80,0x60,0xF8,0x07,0x00,0xFE,0x52,0x52,0x52,0x52,0x52,0xFE,0x00,0x00,0x00},
{0x01,0x00,0x00,0xFF,0x08,0x88,0x4F,0x29,0x09,0x09,0x09,0x29,0x4F,0x88,0x08,0x00},/*"俱",3*/
/* (16 X 16 , 宋体 )*/

{0x00,0x00,0xE0,0x9C,0x84,0x84,0x84,0xF4,0x82,0x82,0x83,0x82,0x80,0x80,0x00,0x00},
{0x00,0x20,0x10,0x08,0x06,0x40,0x80,0x7F,0x00,0x00,0x02,0x04,0x08,0x30,0x00,0x00},/*"乐",4*/
/* (16 X 16 , 宋体 )*/

{0x40,0x44,0x54,0x65,0x46,0x44,0x64,0x54,0x44,0x40,0xFE,0x02,0x22,0xDA,0x06,0x00},
{0x00,0x00,0x7E,0x22,0x22,0x22,0x22,0x7E,0x00,0x00,0xFF,0x08,0x10,0x08,0x07,0x00},/*"部",5*/
/* (16 X 16 , 宋体 )*/

可设置里面数组用工具(PctoLCD2002网上可免费下载)取模;
现在为止,屏幕显示已经明确,分析完 board_init();函数。
printf(“Welcome to TencentOS tiny\r\n”); //串口打印
就是让串口打印字符串

那么 osKernelInitialize(); 内核初始化做了什么?

Cmsis_os.c (osal\cmsis_os)中 :

	osStatus osKernelInitialize(void)
	{
		 return errno_knl2cmsis(tos_knl_init());
	}

同样Cmsis_os.c (osal\cmsis_os)中:

	static osStatus errno_knl2cmsis(k_err_t err)
	{
	 return err == K_ERR_NONE ? osOK : osErrorOS;   返回  K_ERR_NONE 是否错误?是:否
	}

就是反馈K_ERR_NONE 变量是否异常。
#osThreadCreate(osThread(application_entry), NULL); // Create TOS Tiny task
Cmsis_os.c (osal\cmsis_os)中:

					/**

						*@brief创建一个线程并将其添加到活动线程,然后将其设置为state READY。
						
						*@param[in]thread \u def用osThread引用的线程定义。
						
						*@param[in]参数指针,作为开始参数传递给线程函数。
						
						*@return thread ID供其他函数引用,出错时返回NULL。
						
						*/ 调用数组线程,将数据传给线程 *argument->*thread_def
	osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *argument)
						{
						    k_err_t err;
						
						    if (!thread_def) {
						        return NULL;
						    }
						
								#if TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u     //TOS_CFG_TASK_DYNAMIC_CREATE_EN  = 0u
								    if (!thread_def->stackbase && !thread_def->task) {
								        k_task_t *task;
								        err = tos_task_create_dyn(&task, thread_def->name, (k_task_entry_t)thread_def->pthread,
								                                argument, priority_cmsis2knl(thread_def->tpriority),
								                                thread_def->stacksize, thread_def->timeslice);
						        return err == K_ERR_NONE ? task : NULL;
						    }
								#endif																		//error
								
								    err = tos_task_create((k_task_t *)thread_def->task, thread_def->name, (k_task_entry_t)thread_def->pthread,
								                            argument, priority_cmsis2knl(thread_def->tpriority), thread_def->stackbase,
								                            thread_def->stacksize, thread_def->timeslice);
								
								    return err == K_ERR_NONE ? thread_def->task : NULL;
						}
				
						

而之中变量osThread(application_entry)

#define osThread(name)  \
    				&os_thread_def_##name        ##把&os_thread_def_和name连接起来,相当于&os_thread_def_name变量	

application_entry函数在Hello_world.c (examples\hello_world):中:

void application_entry(void *arg)
{
    printf("***I am task\r\n");
    osThreadCreate(osThread(task1), NULL); // Create task1
    osThreadCreate(osThread(task2), NULL); // Create task2
}

同文件中

#define TASK1_STK_SIZE          1024
void task1(void *arg);
osThreadDef(task1, osPriorityNormal, 1, TASK1_STK_SIZE);

#define TASK2_STK_SIZE          1024
void task2(void *arg);
osThreadDef(task2, osPriorityNormal, 1, TASK2_STK_SIZE);

#关于osThreadDef(name, priority, instances, stacksz)定义如下:

#define osThreadDef(name, priority, instances, stacksz)  \
    k_task_t task_handler_##name; \
    k_stack_t task_stack_##name[(stacksz)]; \
    const osThreadDef_t os_thread_def_##name = \
        { #name, (os_pthread)(name), (osPriority)(priority), (instances), \
        (&((task_stack_##name)[0])), (stacksz), ((k_timeslice_t)0u), (&(task_handler_##name)) }

总体总结为:创建结构体,给结构体命名,重装初值
而task函数为:

void task1(void *arg)
{
#if TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u
    osThreadId task_dyn_created;

    osThreadDynamicDef(task3, osPriorityNormal, 1, TASK3_STK_SIZE);
    task_dyn_created = osThreadCreate(osThread(task3), NULL);

    int count = 0;
#endif

    while (1) {
        printf("###I am task1\r\n");
        osDelay(2000);

#if TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u
        if (count++ == 3) {
            printf("###I am task1, kill the task3(dynamic created)\r\n");
            osThreadTerminate(task_dyn_created);
        }
#endif
    }
}

除去判断功能就是为了 printf(“###I am task1\r\n”); 输出;
而且在main函数中

extern void application_entry(void *arg); //引用函数名
osThreadDef(application_entry, osPriorityNormal, 1, APPLICATION_TASK_STK_SIZE);//从做结构体

#最后一句 osKernelStart(); // Start TOS Tiny
// ==== Kernel Control Functions ====

					osStatus osKernelStart(void)
					{
					    return errno_knl2cmsis(tos_knl_start());
					}   //开启

与内核初始化相同,是一种判断返回。

本文用代码反推形式说明功能实现,具体修改相应的修改可以进行两个地方的简单修改:
1、把腾讯的LOGO改掉,用字库软件从新生成字符库。在oleddfont.h的Hzk[]的库中
2、把打印数据改掉,可以直接改在Hello_world.c (examples\hello_world):的task函数中: printf(“###I am task1\r\n”);
两种数据传出方式,为之后的传感器传出数据建立基础。

小白学习大神望指点,指出错误共同学习

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/156093.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!