W801单片机学习笔记——SDK的启动流程,例程使用

家电修理 2023-07-16 19:16www.caominkang.com电器维修

目录

1.前言

2.SDK的启动流程

3.挖坑


1.前言

W801的SDK需要配套的CDK集成开发环境进行开发,该SDK具有W801单片机所有硬件的驱动程序,FreeRTOS操作系统,基于蓝牙和WiFi功能的上层应用,以及各种功能的例程,可以通过例程测试硬件并模仿例程编写自己所需要的功能。

该篇文章主要以SDK启动的启动流程,例程的使用,以及SDK中部分文件在实际使用中的修改尝试。

2.SDK的启动流程

W801在上电后先通过复位电路复位,并使用内部振荡器开始工作。此后单片机先进入启动扇区即地址为0x0000_0000,启动扇区检测BOOT0引脚,若需要更新固件则开始从串口接收数据开始更新固件;若无需更新固件,则引导单片机从FLASH启动地址为0x0800_0000。至此就进入了汇编编写的启动文件。Start.S,这个文件与STM32的startup_stm32.s类似,主要有这几个部分

罗列中断向量表(具体数量以处理器支持的中断数为准)DATA区域初始化(代码中给定初始值的全局变量和静态变量的初始值在FLASH中,这个操作将拷贝到SRAM中,以备使用)BBS区域初始化(代码中没有给的初值的全局变量和静态变量将在这个操作中清零)系统初始化(一般调用SystemInit函数,设置中断向量寄存器指向中断向量表,设置FLASH延迟,设置倍频器的一些基础参数等等,不同芯片的SDK不同)跳转到主函数(跳转到main函数开始运行)

至于start.S文件的具体内容后期将会单独出一篇文章介绍。

现在主要理清晰W801的启动过程,故现在只看如下图部分

W801多了一个板级初始化(board_init)功能的调用 内容如下

 是串口的初始化,该功能是配合W801的SDK的控制台使用的,而且W801的SDK已经将printf函数重新定向到串口,在自己的程序中直接调用printf即可在串口助手上看到内容。

接下来看main函数,main函数的具体位置在m_main.c文件中,内容如下

int main(void)
{
 u32 value = 0;
 
 tls_pmu_clk_select(0);
#if (TLS_CONFIG_HOSTIF&&TLS_CONFIG_UART)
	
	tls_uart_set_at_cmd_port(TLS_UART_1);
#endif
 
 value = tls_reg_read32(HR_PMU_BK_REG);
 value &= ~(BIT(19));
 tls_reg_rite32(HR_PMU_BK_REG, value);
 value = tls_reg_read32(HR_PMU_PS_CR);
 value &= ~(BIT(5));
 tls_reg_rite32(HR_PMU_PS_CR, value);
	
 
 value = tls_reg_read32(HR_CLK_base_ADDR);
 value &= ~0x3fffff;
 value |= 0x1a02;
 tls_reg_rite32(HR_CLK_base_ADDR, value);


 tls_sys_clk_set(CPU_CLK_240M);
 tls_os_init(NULL);

 
 tls_os_sem_create(&libc_sem, 1);

 
	csi_vic_set_akeup_irq(SDIO_IRQn);
 csi_vic_set_akeup_irq(MAC_IRQn);
 csi_vic_set_akeup_irq(SEC_IRQn);
 csi_vic_set_akeup_irq(DMA_Channel0_IRQn);
 csi_vic_set_akeup_irq(DMA_Channel1_IRQn);
 csi_vic_set_akeup_irq(DMA_Channel2_IRQn);
 csi_vic_set_akeup_irq(DMA_Channel3_IRQn);
 csi_vic_set_akeup_irq(DMA_Channel4_7_IRQn);
 csi_vic_set_akeup_irq(DMA_BRUST_IRQn);
 csi_vic_set_akeup_irq(I2C_IRQn);
 csi_vic_set_akeup_irq(ADC_IRQn);
 csi_vic_set_akeup_irq(SPI_LS_IRQn);
	csi_vic_set_akeup_irq(SPI_HS_IRQn);
 csi_vic_set_akeup_irq(GPIOA_IRQn);
 csi_vic_set_akeup_irq(GPIOB_IRQn);
 csi_vic_set_akeup_irq(UART0_IRQn);
 csi_vic_set_akeup_irq(UART1_IRQn);
 csi_vic_set_akeup_irq(UART24_IRQn);
 csi_vic_set_akeup_irq(BLE_IRQn);
 csi_vic_set_akeup_irq(BT_IRQn);
 csi_vic_set_akeup_irq(PWM_IRQn);
 csi_vic_set_akeup_irq(I2S_IRQn);
	csi_vic_set_akeup_irq(SIDO_HOST_IRQn);
 csi_vic_set_akeup_irq(SYS_TICK_IRQn);
 csi_vic_set_akeup_irq(RSA_IRQn);
 csi_vic_set_akeup_irq(CRYPTION_IRQn);
 csi_vic_set_akeup_irq(PMU_IRQn);
 csi_vic_set_akeup_irq(TIMER_IRQn);
 csi_vic_set_akeup_irq(WDG_IRQn);
 
	TaskStartStk = tls_mem_alloc(sizeof(u32)TASK_START_STK_SIZE);
	if (TaskStartStk)
 {
  tls_os_task_create(&tststarthdl, NULL,
         task_start,
         (void )0,
         (void )TaskStartStk,    
         TASK_START_STK_SIZE  sizeof(u32), 
         1,
         0);
	   tls_os_start_scheduler();
 }
	else
	{
		hile(1);
	}	

 return 0;
}

这个文件无需全部看明白,只需要知道干了什么事情,和几句我们需要修改的着重了解一下即可。这个main函数干了如下事情

初始化时钟填写中断向量表(把中断函数地址填写到中断向量表,没有定义的中断函数将填写弱定义的中断服务函数地址,这个套路和STM32一样)创建task_start进程并打开实时操作系统的调度器(后续将在此进程中执行)

上述代码中需要着重如下函数,其参数分别如下

tls_sys_clk_set(CPU_CLK_240M);//设置处理器工作速度
//参数如下
enum CPU_CLK{
	CPU_CLK_240M = 2,
	CPU_CLK_160M = 3,
	CPU_CLK_80M  = 6,
	CPU_CLK_40M  = 12,
	CPU_CLK_2M  = 240,		
};

这个函数将决定处理器的工作速度,此处在SDK中默认设置为80MHZ,故如果发现自己买的W801的CPU性能不佳不要怀疑国产芯片的实力,请来此处将其设置为240MHZ。

接下将会运行task_start进程,代码如下

void task_start (void data)
{
	u8 enable = 0;
 u8 mac_addr[6] = {0x00, 0x25, 0x08, 0x09, 0x01, 0x0F};

#if TLS_CONFIG_CRYSTAL_24M
 tls_l_h_using_24m_crystal();
#endif

	tls_mem_get_init_available_size();
 
 m_gpio_config();

 tls_irq_init();

#if TLS_CONFIG_HARD_CRYPTO
 tls_crypto_init();
#endif

#if (TLS_CONFIG_LS_SPI)
 tls_spi_init();
 tls_spifls_init();
#endif

 tls_fls_init();
 tls_fls_sys_param_postion_init();

 
 tls_ft_param_init();
 tls_param_load_factory_default();
 tls_param_init(); 

 tls_get_tx_gain(&tx_gain_group[0]);
 TLS_DBGPRT_INFO("tx gain ");
 TLS_DBGPRT_DUMP((char )(&tx_gain_group[0]), 27);
 if (tls_ifi_mem_cfg(WIFI_MEM_START_ADDR, 7, 7)) 
 {
  TLS_DBGPRT_INFO("l mem initial failuredn");
 }

 tls_get_mac_addr(&mac_addr[0]);
 TLS_DBGPRT_INFO("mac addr ");
 TLS_DBGPRT_DUMP((char )(&mac_addr[0]), 6);
 if(tls_l_init(NULL, &mac_addr[0], NULL) == NULL)
 {
  TLS_DBGPRT_INFO("l driver initial failuredn");
 }
 if (pa_supplicant_init(mac_addr))
 {
  TLS_DBGPRT_INFO("supplicant initial failuredn");
 }
	
	tls_ifi_set_tempp_flag(0);
	tls_ifi_set_psm_chipsleep_flag(0);
	tls_ifi_psm_chipsleep_cb_register(tls_pmu_chipsleep_callback, NULL, NULL);
 tls_ether_init();

#if TLS_CONFIG_BT
 tls_bt_entry();
#endif

 tls_sys_init();
#if TLS_CONFIG_ONLY_FACTORY_ATCMD
	factory_atcmd_init();
#else
 
#if TLS_CONFIG_HOSTIF
 tls_hostif_init();

#if (TLS_CONFIG_HS_SPI)
 tls_hspi_init();
#endif

#if TLS_CONFIG_UART
 tls_uart_init();
#endif

#if TLS_CONFIG_HTTP_CLIENT_TASK
 http_client_task_init();
#endif

#endif

	tls_param_get(TLS_PARAM_ID_PSM, &enable, TRUE);	
	if (enable != TRUE)
	{
	 enable = TRUE;
	 tls_param_set(TLS_PARAM_ID_PSM, &enable, TRUE);	  
	}

 UserMain();

 tls_sys_auto_mode_run();
#endif

 for (;;)
 {
#if MAIN_TASK_DELETE_AFTER_START_FTR
		if (tststarthdl)
		{
 		tls_os_task_del_by_task_handle(tststarthdl,task_start_free);
		}
  tls_os_time_delay(0x10000000);
#else
#if 1
		tls_os_time_delay(0x10000000);
#else
  //printf("start upn");
  extern void tls_os_disp_task_stat_info(void);
  tls_os_disp_task_stat_info();
  tls_os_time_delay(1000);
#endif		
#endif
 }
}

这个进程主要有中断及各类外设的初始化,其中包括W801的特色——蓝牙和WiFi功能的初始化。其初始化流程与STM32略有不同,STM32在初始化需要连接GPIO口的外设时,GPIO的设置将会与外设在同一个函数中初始化。而W801现在这个进程里单独初始化外设而不对应GPIO,在其后真的需要使用的时候再指定引脚(蓝牙和WiFi功能除外)。

此进程中的UserMain();是下一步,即用户进程,该函数再main.c文件中。具体路径如下

该文件SDK中默认有且只有一个函数,即 UserMain();内容如下

void UserMain(void)
{
	printf("n user task n");
#if DEMO_ConSOLE
	CreateDemoTask();
#endif
//用户自己的task

}

可见此函数中,打印”user task“,然后创建例程进程,是用户自定义代码的编写处。至于例程进程,可参考文件链接如下

链接https://pan.baidu./s/173Ek7qeY0i3ibqt9vvfuUg 
提取码SYHT

W801单片机SDK例程使用手册-单片机文档类资源-CSDN下载

至此,W801的启动流程分析完毕。

3.挖坑

下期分享W801的SDK中一些让人不爽的地方,并提出修改建议。

 

Copyright © 2016-2025 www.caominkang.com 曹敏电脑维修网 版权所有 Power by