CH395_FreeRTOS例程

官方例程下载链接:CH395EVT.ZIP - 南京沁恒微电子股份有限公司


沁恒官方对CH395的例程做了优化更新,发现新增了FreeRTOS例程,对比常规例程,可以看到在主程序main.c中,主要多了一下四个task,分别是:

(1)CH395_Init_Task,如下

可以看到,总体是常规动作:复位--读版本号--初始化395,唯一区别多了15、17行的FreeRTOS操作动作。

15行的动作则是设置初始化CH395完成这一事件位,17行删除此任务释放资源。

 1 void CH395_Init_Task()
 2 {
 3     UINT8 i;
 4     CH395Reset();
 5     vTaskDelay(200);
 6 #if (CH395_OP_INTERFACE_MODE == CH395_UART_MODE)
 7     CH395SetUartBaudRate(921600);
 8 #endif
 9     printf("CH395 initialize start\r\n");
10     i = CH395CMDGetVer();
11     printf("CH395VER : %2x\r\n", (UINT16)i);
12     InitCH395InfParam(); /* Initialize CH395Inf parameters */
13     i = CH395Init();     /* Initialize the CH395 */
14     mStopIfError(i);
15     xEventGroupSetBits(xCH395_Status, Event_CH395_Ready);
16     printf("CH395 initialize success\r\n");
17     vTaskDelete(NULL);
18 }

(2)CH395_InterruptPolling_Task,如下

第3行,等待初始化CH395完成标志,满足则往下执行,否则阻塞;

第7行,等待CH395的中断INT脚拉低,是低电平则往后执行查询中断状态值(代码中设置主控的PA8与CH395的INT脚相连)

第24行,在PHY_Change中断中,检测到PHY的协商状态为连接,则设置link_Success事件位;

第29行,在PHY_Change中断中,如PHY未协商成功,则清除位,重置事件状态;

第37、41、45......行,产生对应socket中断,则置相应事件位;

 1 void CH395_InterruptPolling_Task()
 2 {
 3     xEventGroupWaitBits(xCH395_Status, Event_CH395_Ready, pdFALSE, pdFALSE, portMAX_DELAY);
 4     while (1)
 5     {
 6         vTaskDelay(1);
 7         if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8) == 0)
 8         {
 9             UINT16 init_status;
10 
11             init_status = CH395CMDGetGlobIntStatus();
12 
13             if (init_status & GINT_STAT_UNREACH) /* Unreachable interrupt,to read unreachable information */
14             {
15             }
16             if (init_status & GINT_STAT_IP_CONFLI) /* IP address conflict interrupted,advice to change the IP address of the CH395 again and initialize the CH395 */
17             {
18             }
19             if (init_status & GINT_STAT_PHY_CHANGE) /* PHY change interrupt */
20             {
21                 if (CH395CMDGetPHYStatus() != 1)
22                 {
23                     printf("PHY Link Suc\r\n");
24                     xEventGroupSetBits(xCH395_Status, Event_CH395_Link_SUC);
25                 }
26                 else
27                 {
28                     printf("PHY Link Down\r\n");
29                     xEventGroupClearBits(xCH395_Status, Event_CH395_Link_SUC);
30                 }
31             }
32             if (init_status & GINT_STAT_DHCP)
33             {
34             }
35             if (init_status & GINT_STAT_SOCK0)
36             {
37                 xEventGroupSetBits(xCH395_Socket_Status[0], CH395CMDGetSocketInt(0));
38             }
39             if (init_status & GINT_STAT_SOCK1)
40             {
41                 xEventGroupSetBits(xCH395_Socket_Status[1], CH395CMDGetSocketInt(1));
42             }
43             if (init_status & GINT_STAT_SOCK2)
44             {
45                 xEventGroupSetBits(xCH395_Socket_Status[2], CH395CMDGetSocketInt(2));
46             }
47             if (init_status & GINT_STAT_SOCK3)
48             {
49                 xEventGroupSetBits(xCH395_Socket_Status[3], CH395CMDGetSocketInt(3));
50             }
51             if (init_status & GINT_STAT_SOCK4)
52             {
53                 xEventGroupSetBits(xCH395_Socket_Status[4], CH395CMDGetSocketInt(4));
54             }
55             if (init_status & GINT_STAT_SOCK5)
56             {
57                 xEventGroupSetBits(xCH395_Socket_Status[5], CH395CMDGetSocketInt(5));
58             }
59             if (init_status & GINT_STAT_SOCK6)
60             {
61                 xEventGroupSetBits(xCH395_Socket_Status[6], CH395CMDGetSocketInt(6));
62             }
63             if (init_status & GINT_STAT_SOCK7)
64             {
65                 xEventGroupSetBits(xCH395_Socket_Status[7], CH395CMDGetSocketInt(7));
66             }
67         }
68     }
69 }

(3)CH395_Socket0_TCPclient_Loopback_Task,如下

第6行,等待初始化CH395完成标志,满足则往下执行,否则阻塞;

第11行,等待PHY_Link成功标志,满足则往下执行,否则阻塞;

第17行,等待产生接收中断,接收到数据标志,否则阻塞;

第25行,等待产生SendBuf_Free标志,等到此状态标志则执行后续的send发送,否则阻塞;

 1 void CH395_Socket0_TCPclient_Loopback_Task()
 2 {
 3     u8 i = 0;
 4     u16 totallen = 0, len = 0;
 5     // Wait for CH395 initialization to complete
 6     xEventGroupWaitBits(xCH395_Status, Event_CH395_Ready, pdFALSE, pdFALSE, portMAX_DELAY);
 7     printf("Socket0 create\n");
 8     InitSocket0Param();
 9     CH395Socket0InitOpen();
10 
11     xEventGroupWaitBits(xCH395_Status, Event_CH395_Link_SUC, pdFALSE, pdFALSE, portMAX_DELAY);
12     i = CH395CMDTCPConnect(0);
13     mStopIfError(i);
14     printf("Socket0 create SUC\n");
15     while (1)
16     {
17         xEventGroupWaitBits(xCH395_Socket_Status[0], SINT_STAT_RECV, pdTRUE, pdTRUE, portMAX_DELAY);
18         totallen = CH395CMDGetRecvLength(0); /* Gets the length of data in the current buffer */
19         printf("Socket0 receive\n");
20         while (totallen > 0)
21         {
22             len = (totallen > SocketSendBufferSizes[0]) ? SocketSendBufferSizes[0] : totallen;
23             totallen -= len;
24             CH395CMDGetRecvData(0, len, MyBuffer);
25             xEventGroupWaitBits(xCH395_Socket_Status[0], SINT_STAT_SENDBUF_FREE, pdTRUE, pdTRUE, portMAX_DELAY);
26             CH395CMDSendData(0, MyBuffer, len);
27             vTaskDelay(1);
28         }
29         vTaskDelay(1);
30     }
31 }

(4)CH395_Socket1_UDPServer_broadcast_Task,如下

第4行,等待初始化CH395完成标志,满足则往下执行,否则阻塞;

第12行,等待产生SendBuf_Free标志,等到此状态标志则执行后续的send发送,否则阻塞;

 1 void CH395_Socket1_UDPServer_broadcast_Task()
 2 {
 3     // Wait for CH395 initialization to complete
 4     xEventGroupWaitBits(xCH395_Status, Event_CH395_Ready, pdFALSE, pdFALSE, portMAX_DELAY);
 5     printf("Socket1 create\n");
 6     InitSocket1Param();
 7     CH395Socket1InitOpen();
 8     printf("Socket1 create SUC\n");
 9     while (1)
10     {
11         vTaskDelay(500);
12         xEventGroupWaitBits(xCH395_Socket_Status[1], SINT_STAT_SENDBUF_FREE, pdTRUE, pdTRUE, portMAX_DELAY);
13         printf("Socket1 send\n");
14         CH395CMDSendData(1, MyBuffer, 100);
15     }
16 }

 

主程序main.c中,如下:

第22行,创建互斥信号量,用于保护对CH395命令的访问,确保同一时间只有一个任务可以发送命令给CH395;

第23行,创建一个事件组,用于记录CH395的整体状态;

第24行,循环为8个socket分别创建事件组,记录相应socket的事件状态;

第31行,初始化socket时,设置事件组的位SINT_STAT_SENDBUF_FREE,表示发送缓冲区空闲;

第34、41、48、55行,分别创建4个任务,并将初始化CH395的任务优先级设置最高(设置为6),查中断任务优先级设置为最低(设置为1);

第62行,启动FreeRTOS内核调度器,开始按照优先级调度任务执行,程序将在此处进入任务调度循环。

 1 int main(void)
 2 {
 3     SystemCoreClockUpdate();
 4     Delay_Init();
 5     USART_Printf_Init(115200);
 6     printf("SystemClk:%d\r\n", SystemCoreClock);
 7     printf("FreeRTOS Kernel Version:%s\r\n", tskKERNEL_VERSION_NUMBER);
 8 
 9     /*
10     CH395 supports three interface modes: SPI, serial, and parallel.
11     When using different interfaces, refer to the interface configuration instructions in 'CH395DS1.pdf'
12     and ensure that the corresponding .c file is included in the compilation.
13     Additionally, define CH395_OP_INTERFACE_MODE in 'CH395INC.h' to match the selected interface.
14     For example, when using the SPI interface, the TXD pin should be grounded, the SEL pin should be floating or pulled high,
15     and the 'CH395SPI_HW.c' file should be included in the compilation.
16     Furthermore,CH395_OP_INTERFACE_MODE should be set to CH395_SPI_MODE in 'CH395INC.h'.
17     */
18 
19     CH395_PORT_INIT();
20     CH395_GPIO_INIT();
21 
22     xCH395cmd_Mutex = xSemaphoreCreateMutex();
23     xCH395_Status = xEventGroupCreate();
24     for (u8 val = 0; val < 8; val++)
25     {
26         xCH395_Socket_Status[val] = xEventGroupCreate();
27         /*
28         The socket interrupt value should be set to SINT_STAT_SENDBUF_FREE during initialization,
29         as there will be no send buffer idle interrupt before any data packet is sent.
30         */
31         xEventGroupSetBits(xCH395_Socket_Status[val], SINT_STAT_SENDBUF_FREE);
32     }
33     /* create two task */
34     xTaskCreate((TaskFunction_t)CH395_Init_Task,
35                 (const char *)"CH395_Init",
36                 (uint16_t)128,
37                 (void *)NULL,
38                 (UBaseType_t)6,
39                 (TaskHandle_t *)&CH395_init_Task_Handler);
40 
41     xTaskCreate((TaskFunction_t)CH395_InterruptPolling_Task,
42                 (const char *)"CH395_InterruptPolling",
43                 (uint16_t)128,
44                 (void *)NULL,
45                 (UBaseType_t)1,
46                 (TaskHandle_t *)&CH395_InterruptPolling_Task_Handler);
47 
48     xTaskCreate((TaskFunction_t)CH395_Socket0_TCPclient_Loopback_Task,
49                 (const char *)"CH395_Socket0_TCPclient_Loopback",
50                 (uint16_t)128,
51                 (void *)NULL,
52                 (UBaseType_t)4,
53                 (TaskHandle_t *)&CH395_Socket0_TCPclient_Loopback_Task_Handler);
54 
55     xTaskCreate((TaskFunction_t)CH395_Socket1_UDPServer_broadcast_Task,
56                 (const char *)"CH395_Socket1_UDPServer_broadcast",
57                 (uint16_t)128,
58                 (void *)NULL,
59                 (UBaseType_t)3,
60                 (TaskHandle_t *)&CH395_Socket1_UDPServer_broadcast_Task_Handler);
61 
62     vTaskStartScheduler();
63 
64     while (1)
65     {
66         printf("shouldn't run at here!!\n");
67     }
68 }

 

posted on 2025-10-09 10:41  Lqqq123  阅读(50)  评论(0)    收藏  举报

导航