转载:MQX串口使用

该文章转自: https://blog.csdn.net/wangwenxue1989/article/details/49081337  若有不便本人将立即删除!

串口最常用的两个功能就是查询方式发送数据和中断方式接收数据。
在MQX该如何实现呢?
以FRDM_K64f +Freescale_MQX_4_1_FRDMK64F 为例来说明。
实现的功能是:
1)UART0 用作printf
2)UART1 实现查询发送和中断接收
中断接收的过程我采用的方法是:在MQX uart驱动的基础上增加callback函数,在callback函数中通过lwsem手段通知另外一个读串口数据的任务

UART1使用的是PTC3和PTC4,开发板上的接口如下:
转载:MQX串口使用

实现步骤如下:
1)user_config.h 中

#define BSPCFG_ENABLE_TTYB       1   // wenxue 0->1 
#define BSPCFG_ENABLE_ITTYB      1  // wenxue 0->1 
  • 1
  • 2

2)在 serinprv.h 中增加一个回调函数
先声明

typedef void (_CODE_PTR_  UART_NOTIFICATION_FPTR)(void *); // wenxue 2015-10-12 
  • 1

在io_serial_int_device_struct 这个结构中加入

/* UART Notification Callback wenxue 2015-10-12 */
UART_NOTIFICATION_FPTR DEV_RX_TX_CALLBACK;
  • 1
  • 2

3)serl_int_kuart.c 中的_kuart_int_rx_tx_isr 函数中加入回调函数的调用

   if (stat & UART_S1_RDRF_MASK) {
      // reading 'D' register performs also cleanup of 'S1'
      c = sci_ptr->D;
      if (!_io_serial_int_addc(int_io_dev_ptr, c)) {
          sci_info_ptr->RX_DROPPED_INPUT++;
      }
      sci_info_ptr->RX_CHARS++;
      /* call UART CALL Back function if installed  wenxue         2015-10-12*/
      if(int_io_dev_ptr->DEV_RX_TX_CALLBACK != NULL)
           int_io_dev_ptr->DEV_RX_TX_CALLBACK(int_io_dev_ptr);
   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

4)serl_int.c和serial.h 增加ioctl 安装回调函数的支持
_io_serial_int_ioctl 中

   /* add IO_IOCTL_SERIAL_SET_RXTX_CALLBACK wenxue 2015-10-12 */    
     case IO_IOCTL_SERIAL_SET_RXTX_CALLBACK:
         int_io_dev_ptr->DEV_RX_TX_CALLBACK = (UART_NOTIFICATION_FPTR)param_ptr;
         break;
  • 1
  • 2
  • 3
  • 4
#define IO_IOCTL_SERIAL_SET_RXTX_CALLBACK      _IO(IO_TYPE_SERIAL, 0x1F)
  • 1

以上修改完成后,重新编译bsp工程

5)在原hello 工程中做修改,完成应用程序

/*HEADER**********************************************************************
*
* Copyright 2008 Freescale Semiconductor, Inc.
* Copyright 1989-2008 ARC International
*
* This software is owned or controlled by Freescale Semiconductor.
* Use of this software is governed by the Freescale MQX RTOS License
* distributed with this Material.
* See the MQX_RTOS_LICENSE file distributed for more details.
*
* Brief License Summary:
* This software is provided in source form for you to use free of charge,
* but it is not open source software. You are allowed to use this software
* but you cannot redistribute it or derivative works of it in source form.
* The software may be used only in connection with a product containing
* a Freescale microprocessor, microcontroller, or digital signal processor.
* See license agreement file for full license terms including other
* restrictions.
*****************************************************************************
*
* Comments:
*
*   This file contains the source for the hello example program.
*
*
*END************************************************************************/



#include <mqx.h>
#include <bsp.h> 
#include <fio.h>


#if ! BSPCFG_ENABLE_IO_SUBSYSTEM
#error This application requires BSPCFG_ENABLE_IO_SUBSYSTEM defined non-zero in user_config.h. Please recompile BSP with this option.
#endif


#ifndef BSP_DEFAULT_IO_CHANNEL_DEFINED
#error This application requires BSP_DEFAULT_IO_CHANNEL to be not NULL. Please set corresponding BSPCFG_ENABLE_TTYx to non-zero in user_config.h and recompile BSP with this option.
#endif


/* Task IDs */
#define HELLO_TASK 5
#define READ_TASK    6

extern void hello_task(uint32_t);
extern void read_task(uint32_t initial_data);

MQX_FILE_PTR uart1_int_dev = NULL;

void uart1_rx_callback(void *param);

LWSEM_STRUCT   uart1_frame_received; // wenxue

const TASK_TEMPLATE_STRUCT  MQX_template_list[] = 
{ 
    /* Task Index,   Function,   Stack,  Priority, Name,     Attributes,          Param, Time Slice */
    { HELLO_TASK,   hello_task, 1500,   8,        "hello",  MQX_AUTO_START_TASK, 0,     0 },
    { READ_TASK,    read_task,  1000,   8,          "read",     MQX_AUTO_START_TASK, 0,     0 }, // added by wenxue
    { 0 }
};


/*TASK*-----------------------------------------------------
* 
* Task Name    : hello_task
* Comments     :
*    This task prints " Hello World "
*
*END*-----------------------------------------------------*/
void hello_task
    (
        uint32_t initial_data
    )
{  
   (void)initial_data; /* disable 'unused variable' warning */
    uint32_t result;
    MQX_FILE_PTR uart1_dev = NULL;
    int buad = 115200;
    char data_buffer[]="I Love Beijing\r\n";

    printf("Hello World\n");  // uart0 

    uart1_dev=fopen( "ttyb:", NULL);

    if( uart1_dev == NULL )
    {
      /* device could noFt be opened */
      _task_block();
    }

    /* Set baud as 115200 */
    result = ioctl(uart1_dev,IO_IOCTL_SERIAL_SET_BAUD,&buad);

   if( result == IO_ERROR_INVALID_IOCTL_CMD )
   {
      /* ioctl not supported, use newer MQX version */
      _task_block();
   }

   /* send data to uart */
   write( uart1_dev, data_buffer, strlen(data_buffer));

   /* wait for transfer complete flag */
   result = ioctl( uart1_dev, IO_IOCTL_SERIAL_WAIT_FOR_TC, NULL );
   if( result == IO_ERROR_INVALID_IOCTL_CMD )
   {
      /* ioctl not supported, use newer MQX version */
      _task_block();
   }

   fclose(uart1_dev);



   uart1_int_dev=fopen( "ittyb:", NULL);
   if( uart1_dev == NULL )
    {
      /* device could not be opened */
      _task_block();
   }

  result = ioctl( uart1_int_dev, IO_IOCTL_SERIAL_SET_RXTX_CALLBACK, (void*)uart1_rx_callback ); 

  if( result == IO_ERROR_INVALID_IOCTL_CMD )
   {
      /* ioctl not supported, use newer MQX version */
      _task_block();
   }

   /* Create the lightweight semaphores */
   result = _lwsem_create(&uart1_frame_received, 0);
   if (result != MQX_OK) {
      printf("\nCreating read_sem failed: 0x%X", result);
      _task_block();
   }

  /* Has already called _int_install_isr(sci_init_ptr->RX_TX_VECTOR, _kuart_int_rx_tx_isr, int_io_dev_ptr); wenxue*/
  //_int_install_isr(INT_UART1_RX_TX, UART1_RX_ISR,NULL); 

   _task_block();

}


void uart1_rx_callback(void *param)
{
   _lwsem_post(&uart1_frame_received); 
}


/*TASK*--------------------------------------------------------
*
* Task Name : read_task
* Comments  : This task used to read uart data
*            
*END*--------------------------------------------------------*/

void read_task 
   (
      uint32_t initial_data
   )
{
   uint32_t  bytesRead; 
   int num=0;
   char data_buffer[100];

   printf("\n read task created: 0x%lX", initial_data);
   while (TRUE) {
      if (_lwsem_wait(&uart1_frame_received) != MQX_OK) {
         printf("\n_lwsem_wait failed");
         _task_block();
      }
   /* read  data */ 
   bytesRead= fread(data_buffer, 1, 1, uart1_int_dev);

   /* write data */ 
   fwrite(data_buffer,1,bytesRead,uart1_int_dev);

   }
}
/* EOF */
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186

另外需要说明的是:
bytesRead= fread(data_buffer, 1, 1, uart1_int_dev);默认打开方式是blocking 方式,所以如果想通过fread 读取多字节数据,这时会阻塞住,直到读取完成再返回。
也可以uart1_int_dev=fopen( “ittyb:”, (char const *) IO_SERIAL_NON_BLOCKING); 以Non blocking方式打开,这时fread可以立刻返回。

实验现象是:
UART1 先输出 I Love Beijing
在UART1 接收到一个字符后,通过UART1再输出。

相关资料下载:链接: 链接: http://pan.baidu.com/s/1qW7ph3e 密码: nffd

--------------------- 本文来自 若风飘茫 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/wangwenxue1989/article/details/49081337?utm_source=copy