This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2642R: uart 写回调模式,不能连续使用UART_write() ;

Part Number: CC2642R
Other Parts Discussed in Thread: CC2640R2F

将串口写设置成写回调模式,回调函数不进行任何操作。连续使用两个UART_write() ,只有1个被打印,系统貌似已经崩溃。

设置为阻塞模式,可以实现连续2个串口写操作。

查看uart.h,串口写是可以设置成回调模式的。难道连续两个UART_write() ,间隔时间太短,系统反应不过来。

In #UART_MODE_CALLBACK, %UART_write() does not block task execution.
* Instead, a callback function specified by UART_Params::writeCallback is
* called when the transfer is finished. The buffer passed to UART_write()
* in #UART_MODE_CALLBACK is not copied. The buffer must remain coherent
* until all the characters have been sent (ie until the tx callback has
* been called with a byte count equal to that passed to UART_write()).
* The callback function can occur in the caller's task context or in a HWI or
* SWI context, depending on the device implementation.

但是相同的程序是可以在cc2640r2f上实现。cc2640r2f的sdk是simplelink_cc2640r2_sdk_1_40_00_45;CC2642R的SDK是simplelink_cc13x2_26x2_sdk_4_30_00_54

  • 我会在明天检查这个,在此之前,需要提供具体是如何实现的,将这部分代码传上来

    另外,debug单步运行看能否执行到第二个UART_write() 

  • static void SimpleCentral_init(void)
    {
    ......
    
    //TEST CODE
        TaskUARTWrite("sample_uart",11);
        TaskUARTWrite("sample_uart",11);
        TaskUARTdoWrite("sample_uart\r\n",13,"%s%d\r\n",NULL,NULL);
        TaskUARTdoWrite(NULL,NULL,"%s%d\r\n","task_Printf_NO.",1);
    
        TaskUARTPrintf("%s%d\r\n","task_Printf_NO.",1);
    }
    
    
    /*    task_uart.c               */
    #include <stdio.h>
    #include <string.h>
    
    #include <xdc/std.h>
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Semaphore.h>
    #include <ti/sysbios/knl/Queue.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Event.h>
    
    #include "board.h"
    #include <ti/drivers/uart/UARTCC26XX.h>
    #include "task_uart.h"
    /*********************************************************************
     * LOCAL PARAMETER
     */
    // Task configuration
    #define UART_TASK_PRIORITY                     2
    #define UART_TASK_STACK_SIZE                   644
    Task_Struct uartTask;
    Char uartTaskStack[UART_TASK_STACK_SIZE];
    
    // Uart configuration
    UART_Handle UARTHandle;
    UART_Params UARTparams;
    uint8_t Uart_RxTempBuf[200];
    uint8_t Uart_TxTempLen;
    uint8_t Uart_TxTempBuf[200];
    // Uart -> App  Callback
    GY_UartRxBufCallback GY_UartReviceDataCallback;
    
    // Event used to control the UART thread
    static Event_Struct uartEvent;
    static Event_Handle hUartEvent;
    
    #define UARTTASK_RX_EVENT      Event_Id_00 
    
    #define UARTTASK_TX_EVENT      Event_Id_01 
    
    #define UARTTASK_EVENT_ALL ( UARTTASK_RX_EVENT | UARTTASK_TX_EVENT )
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    void TaskUART_taskInit(void);   
    void TaskUART_taskFxn(UArg a0, UArg a1);
    void Uart_WriteCallback(UART_Handle handle, void *txBuf, size_t size);
    void Uart_ReadCallback(UART_Handle handle, void *rxBuf, size_t size);
    void TaskUARTWrite(uint8_t *buf, uint16_t len);  //打印字符串
    void TaskUARTPrintf(const char* format, ...);   //printf打印
    
    /*********************************************************************
     * @fn      TaskUART_createTask
     *
     * @brief   Task creation function for the uart.
     *
     * @param   None.
     *
     * @return  None.
     */
    void TaskUART_createTask(void)
    {
      Task_Params taskParams;
    
      // Configure task
      Task_Params_init(&taskParams);
      taskParams.stack = uartTaskStack;
      taskParams.stackSize = UART_TASK_STACK_SIZE;
      taskParams.priority = UART_TASK_PRIORITY;
    
      Task_construct(&uartTask, TaskUART_taskFxn, &taskParams, NULL);
    }
    
    /*********************************************************************
     * @fn      TaskUART_taskInit
     *
     * @brief   串口初始化
     *
     * @param   None
     *
     * @return  None.
     */
    void TaskUART_taskInit(void)
    {
      UART_init();                                      //初始化模块的串口功能
      UART_Params_init(&UARTparams);                    //初始化串口参数
      UARTparams.baudRate = 115200;                     //串口波特率115200
      UARTparams.dataLength = UART_LEN_8;               //串口数据位8
      UARTparams.stopBits = UART_STOP_ONE;              //串口停止位1
      UARTparams.readDataMode = UART_DATA_BINARY;       //串口接收数据不做处理
      UARTparams.writeDataMode = UART_DATA_TEXT;        //串口发送数据不做处理
      UARTparams.readMode = UART_MODE_CALLBACK;         //串口异步读
      UARTparams.writeMode = UART_MODE_CALLBACK;        //串口异步写
      UARTparams.readEcho = UART_ECHO_OFF;              //串口不回显
      UARTparams.readReturnMode = UART_RETURN_NEWLINE;  //当接收到换行符时,回调
      UARTparams.readCallback = Uart_ReadCallback;      //串口读回调
      UARTparams.writeCallback = Uart_WriteCallback;    //串口写回调
      
      UARTHandle = UART_open(Board_UART0, &UARTparams); //打开串口通道
      UART_control(UARTHandle, UARTCC26XX_RETURN_PARTIAL_ENABLE,  NULL);   //允许接收部分回调
      
      UART_read(UARTHandle, Uart_RxTempBuf, 200);       //打开一个串口读
    }
    
    /*********************************************************************
     * @fn      TaskUART_taskFxn
     *
     * @brief   串口任务处理
     *
     * @param   None
     *
     * @return  None.
     */
    void TaskUART_taskFxn(UArg a0, UArg a1)
    { 
      Event_Params evParams;
      Event_Params_init(&evParams);
      Event_construct(&uartEvent, &evParams);
      hUartEvent = Event_handle(&uartEvent);
      
      TaskUART_taskInit();
    
      while(1)
      {
        UInt events;
        events = Event_pend(hUartEvent,Event_Id_NONE, UARTTASK_EVENT_ALL, BIOS_WAIT_FOREVER);
        
        if(events & UARTTASK_RX_EVENT)
        {
          UART_read(UARTHandle, Uart_RxTempBuf, 200);     //再次打开一个串口读
        }
        
        if(events & UARTTASK_TX_EVENT)
        {
          TaskUARTWrite(Uart_TxTempBuf, Uart_TxTempLen);  //串口打印数据
        }
      }
    }
    
    /*********************************************************************
     * @fn      Uart_ReadCallback
     *
     * @brief   串口读回调
     *
     * @param   handle -> 串口通道
     *          rxBuf -> 串口接收数据的指针
     *          size -> 串口接收数据的长度
     *
     * @return  None.
     */
    void Uart_ReadCallback(UART_Handle handle, void *rxBuf, size_t size)
    { 
      //UART_write(UARTHandle, rxBuf, size);       //回显打印
      //Event_post(hUartEvent, UARTTASK_RX_EVENT);
      UART_read(handle, Uart_RxTempBuf, 200);    //再次打开一个串口读
      if ( GY_UartReviceDataCallback )
      {
        GY_UartReviceDataCallback(rxBuf, size);  //给app任务一个串口读回调
      }
    }
    
    /*********************************************************************
     * @fn      Uart_WriteCallback
     *
     * @brief   串口写回调
     *
     * @param   handle -> 串口通道
     *          txBuf -> 串口发送数据的指针
     *          size -> 串口发送数据的长度
     *
     * @return  None.
     */
    void Uart_WriteCallback(UART_Handle handle, void *txBuf, size_t size)
    {
      
    }
    
    /*********************************************************************
     * @fn      GY_UartTask_Write
     *
     * @brief   串口写函数
     *
     * @param   buf -> 需要写的数据指针
     *          len -> 需要写的数据长度
     *
     * @return  None.
     */
    void TaskUARTWrite(uint8_t *buf, uint16_t len)
    {
      UART_write(UARTHandle, buf, len);
    }
    
    /*********************************************************************
     * @fn      GY_UartTask_Printf
     *
     * @brief   串口写函数(类似系统printf)
     *
     * @param   format -> 不定参数标志位,例如%d,%s等
     *          ... -> 不定参数
     *
     * @return  None.
     */
    void TaskUARTPrintf(const char* format, ...)
    {
      va_list arg;
      va_start(arg,format);
      uint8_t buf[200];
      uint16_t len;
      len = vsprintf((char*)buf, format, arg);
      UART_write(UARTHandle, buf, len);
    }
    
    /*********************************************************************
     * @fn      HwUARTdoWrite
     *
     * @brief   串口写函数(留给APP打印使用)
     *
     * @param   buf -> 数据buf
     *          len -> 数据len
     *          format -> 不定参数标志位,例如%d,%s等
     *          ... -> 不定参数
     *
     * @return  None.
     *
     *          注意:buf与len为字符串打印,format与...为printf打印,不支持同时使用
     */
    void TaskUARTdoWrite(uint8_t *buf, uint16_t len, const char* format, ...)
    {
      if(buf == NULL)
      {
        va_list arg;
        va_start(arg,format);
        uint8_t pbuf[200];
        uint16_t plen;
        plen = vsprintf((char*)pbuf, format, arg);
        Uart_TxTempLen = plen;
        memcpy(Uart_TxTempBuf, pbuf, plen);
      }
      else
      {
         Uart_TxTempLen = len;
         memcpy(Uart_TxTempBuf, buf, len);
      }
      Event_post(hUartEvent, UARTTASK_TX_EVENT);
    }
    
    /*********************************************************************
     * @fn      GY_UartTask_RegisterPacketReceivedCallback
     *
     * @brief   注册串口接收回调任务(将串口接收的数据传给app任务去处理)
     *
     * @param   callback -> 串口接收数据回调(包括数据buf及len)
     *
     * @return  None.
     */
    void GY_UartTask_RegisterPacketReceivedCallback(GY_UartRxBufCallback callback)
    {
      GY_UartReviceDataCallback = callback;
    }
    
    
    /*         task_uart.h*/
    #ifndef SERIAL_UART_H
    #define SERIAL_UART_H
    
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    
    /*****************************************************
     * 串口任务初始化
    */  
    void TaskUART_createTask(void);
    
    /*****************************************************
     * 串口写函数
    */
    void TaskUARTdoWrite(uint8_t *buf, uint16_t len, const char* format, ...);
    
    /*****************************************************
     * 串口接收数据回调(包括数据buf及len)
    */
    typedef void (*GY_UartRxBufCallback)(uint8_t *buf, uint16_t len);
    
    /*****************************************************
     * 注册串口接收回调任务(将串口接收的数据传给app任务去处理)
    */
    void GY_UartTask_RegisterPacketReceivedCallback(GY_UartRxBufCallback callback);
    
    
    #ifdef __cplusplus
    {
    #endif // extern "C"
    
    #endif // end of SERIAL_UART_H definition

    int main()
    {
    ......
    
      SimpleCentral_createTask();
      TaskUART_createTask();
    
      /* enable interrupts and start SYS/BIOS */
      BIOS_start();
    
    ......
    }

  • 参考这里的debug指南和ROV部分监控任务https://dev.ti.com/tirex/content/simplelink_cc13xx_cc26xx_sdk_5_30_01_01/docs/ble5stack/ble_user_guide/html/ble-stack-5.x-guide/debugging-index.html

    另外,debug单步运行看能否执行到第二个UART_write() 

    这个测试了吗

    不使用蓝牙例程单独测一下只有一个任务的串口程序试试是否正常

  • debug单步运行看能否执行到第二个UART_write() 

    单步调试到第一个UART_write()就崩溃了。

  • 看下是不是任务调度的问题,参考上面链接中的调试步骤

    另外单独测试uart部分看是否有问题