搜索
bottom↓
回复: 17

这样的uart框架怎么样?

[复制链接]

出0入8汤圆

发表于 2020-10-24 12:02:42 | 显示全部楼层 |阅读模式
以前是使用类似linux的,open/read/write/control等函数
但是发现每次设置参数时不够直观,往往要去查看代码
早上大概写写串口的API,发上来让大家指点一下。


  1. #ifndef _RTS_UART_H
  2. #define _RTS_UART_H
  3. #include "stdint.h"

  4. struct
  5. {
  6.     uint8_t poll_send:1;
  7.     uint8_t poll_read:1;

  8. }capability_t;

  9. typedef struct
  10. {
  11.     uint8_t tt;
  12. }rts_uart_t;



  13. void rts_uart_init(rts_uart_t *dev);
  14. void rts_uart_uninit(rts_uart_t *dev);
  15. void rts_uart_control(uint32_t control,uint32_t arg);

  16. void rts_uart_poll_send(rts_uart_t *dev,uint8_t *buffer,uint16_t len);
  17. void rts_uart_poll_read(rts_uart_t *dev,uint8_t *buffer,uint16_t len);

  18. void rts_uart_intterput_send(rts_uart_t *dev,uint8_t *buffer,uint16_t len);
  19. void rts_uart_set_intterput_read_callback(rts_uart_t *dev,void (*callback)(uint8_t data));


  20. void rts_uart_dma_send(rts_uart_t *dev,uint8_t *buffer,uint16_t len);
  21. void rts_uart_set_dma_read_callback(rts_uart_t *dev,uint8_t *dmabuffer,uint16_t size,void (*callback)(uint8_t *buf,uint16_t len));


  22. void rts_uart_queue_send(rts_uart_t *dev,uint8_t *buffer,uint16_t len);
  23. void rts_uart_queue_read(rts_uart_t *dev,uint8_t *buffer,uint16_t len);

  24. #endif
复制代码

出100入85汤圆

发表于 2020-10-24 12:08:47 | 显示全部楼层
把实现也开放会更赞

出0入0汤圆

发表于 2020-10-24 12:09:12 | 显示全部楼层
很好的轮子。

出0入36汤圆

发表于 2020-10-24 12:09:35 来自手机 | 显示全部楼层
这能看出来啥?

出0入8汤圆

 楼主| 发表于 2020-10-24 12:15:02 | 显示全部楼层
whatcanitbe 发表于 2020-10-24 12:08
把实现也开放会更赞

实现还没有写

出0入8汤圆

 楼主| 发表于 2020-10-24 12:17:14 | 显示全部楼层

总觉得自己的轮子好用些
像CMSISI driver/ AMetal /rt-thread 总是用不习惯

出0入8汤圆

 楼主| 发表于 2020-10-24 12:40:53 | 显示全部楼层
又改了一下,使用函数指针来做

  1. #ifndef _RTS_UART_H
  2. #define _RTS_UART_H
  3. #include "stdint.h"

  4. #define RTS_UART_VERSION    "0.0.1"

  5. typedef struct
  6. {
  7.     char *   name;
  8.     uint32_t type;
  9.     uint32_t api_ver;
  10.     void *   api;
  11. }rts_device_t;


  12. typedef struct
  13. {
  14.     struct
  15.     {
  16.         uint32_t poll_send:1;
  17.         uint32_t poll_read:1;
  18.     };

  19.     void (*init)(rts_uart_t *dev);
  20.     void (*uninit)(rts_uart_t *dev);
  21.     void (*control)(uint32_t control,uint32_t arg);

  22.     void (*poll_send)(rts_uart_t *dev,uint8_t *buffer,uint16_t len);
  23.     void (*poll_read)(rts_uart_t *dev,uint8_t *buffer,uint16_t len);

  24.     void (*intterput_send)(rts_uart_t *dev,uint8_t *buffer,uint16_t len);
  25.     void (*intterput_read_set_callback)(rts_uart_t *dev,void (*callback)(uint8_t data));

  26.     void (*dma_send)(rts_uart_t *dev,uint8_t *buffer,uint16_t len);
  27.     void (*dma_read_set_callback)(rts_uart_t *dev,uint8_t *dmabuffer,uint16_t size,void (*callback)(uint8_t *buf,uint16_t len));

  28.     void (*queue_send)(rts_uart_t *dev,uint8_t *buffer,uint16_t len);
  29.     void (*queue_read)(rts_uart_t *dev,uint8_t *buffer,uint16_t len);

  30. }rts_uart_api_t;



  31. #endif
复制代码

出0入10汤圆

发表于 2020-10-24 15:00:26 | 显示全部楼层
lindabell 发表于 2020-10-24 12:40
又改了一下,使用函数指针来做

用第二种吧   封装太狠 都不好用    第二种移植性也比较好 我写的和你有点区别的是  read  , write, flush,RX_dispatch    .这几个函数都是固定的 非阻塞 。通过传入串口端口指针 来进行不同的收发。你的这种的话其实和我的差不多。唯一的不同的就是 每一路串口你都需要写一个 read  write等 给函数指针

出0入0汤圆

发表于 2020-10-24 20:13:08 | 显示全部楼层
不错,我也用不习惯各种系统自带的。
有段时间也自己搞了一套,不过都是基于中断的,主要考虑基本上有串口的mcu肯定可以中断,而不一定都可以用dma。

出0入8汤圆

 楼主| 发表于 2020-10-25 01:46:13 | 显示全部楼层
又改了一下,比较完整一点

  1. #ifndef _RTS_DRIVER_H
  2. #define _RTS_DRIVER_H
  3. #include "stdint.h"

  4. /*

  5.   |=======================================|
  6.   | app                     |             |
  7.   |-------------------------|             |
  8.   | rts_driver | middleware |functionware |
  9.   |---------------------------------------|
  10.   | hardware                              |
  11.   |=======================================|
  12. */


  13. typedef enum
  14. {
  15.     RTS_DRIVER_TYPE_UNKNOW=0,
  16.     RTS_DRIVER_TYPE_UART,
  17.     RTS_DRIVER_TYPE_SPI,
  18.     RTS_DRIVER_TYPE_I2C,
  19.     RTS_DRIVER_TYPE_I2S,
  20.     RTS_DRIVER_TYPE_SDIO,
  21.     RTS_DRIVER_TYPE_USB,
  22.     RTS_DRIVER_TYPE_FLASH,
  23.     RTS_DRIVER_TYPE_RTC,
  24.     RTS_DRIVER_TYPE_WATCHDOG,
  25.     RTS_DRIVER_TYPE_ADC,
  26.     RTS_DRIVER_TYPE_PIN,
  27.     RTS_DRIVER_TYPE_EEPROM,
  28.     RTS_DRIVER_TYPE_PWM,
  29.     RTS_DRIVER_TYPE_TIMER,
  30.     RTS_DRIVER_TYPE_DAC,
  31.     RTS_DRIVER_TYPE_CRC,
  32.     RTS_DRIVER_TYPE_DMA,

  33. }rts_driver_type_t;

  34. typedef struct
  35. {
  36.     const char *              name;
  37.     const rts_driver_type_t   type;
  38.     const uint32_t            api_ver;
  39.     const void *              api;
  40. }rts_driver_t;


  41. #define RTS_DRIVER_API_VER(x,y,z)   (((0x##x)<<24)|((0x##y)<<8)|(0x##z))

  42. const char *rts_driver_get_type_str(const rts_driver_t *dev);


  43. #if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && __ARMCC_VERSION >= 6000000)
  44. #define RTS_DRIVER_SECTION(x)                  __attribute__((section(x)))
  45. #elif defined(__ICCARM__)
  46. #define RTS_DRIVER_SECTION(x)                  @ x
  47. #elif defined(__GNUC__)
  48. #define RTS_DRIVER_SECTION(x)                  __attribute__((section(x)))
  49. #else
  50. #define RTS_DRIVER_SECTION(x)
  51. #endif

  52. #define     RTS_DRIVER_REGISTER(_name,_type,_api_ver,_api)                                          \
  53.             static const rts_driver_t rts_driver_##_name RTS_DRIVER_SECTION("RTS_DRIVER_LIST")=     \
  54.             {                                                                                       \
  55.                 .name=#_name,                                                                       \
  56.                 .type=_type,                                                                        \
  57.                 .api_ver=_api_ver,                                                                  \
  58.                 .api=_api                                                                           \
  59.             }


  60. #endif
复制代码

  1. #ifndef _RTS_UART_H
  2. #define _RTS_UART_H
  3. #include "stdint.h"
  4. #include "rts_driver.h"

  5. #define RTS_UART_API_VERSION    RTS_DRIVER_API_VER(0,0,1)

  6. //error codes
  7. typedef enum
  8. {
  9.     RTS_UART_SUCCESS=0,
  10.     RTS_UART_ERROR,
  11.     RTS_UART_BUSY,
  12.     RTS_UART_UNSUPPORT_BAUDRATE,
  13.     RTS_UART_UNSUPPORT_DATA_BITS,
  14.     RTS_UART_UNSUPPORT_PARITY,
  15.     RTS_UART_UNSUPPORT_STOP_BITS,
  16.     RTS_UART_UNSUPPORT_APIS
  17. }rts_uart_err_t;


  18. //control cmd lists
  19. #define RTS_UART_BAUDRATE           (1<<0)      //arg: baud rate(dafault:9600)

  20. #define RTS_UART_DATA_BITS_5        (1<<1)
  21. #define RTS_UART_DATA_BITS_6        (1<<2)
  22. #define RTS_UART_DATA_BITS_7        (1<<3)
  23. #define RTS_UART_DATA_BITS_8        (1<<4)      //default
  24. #define RTS_UART_DATA_BITS_9        (1<<5)

  25. #define RTS_UART_PARITY_EVEN        (1<<6)
  26. #define RTS_UART_PARITY_NONE        (1<<7)      //default
  27. #define RTS_UART_PARITY_ODD         (1<<8)

  28. #define RTS_UART_STOP_BITS_1        (1<<9)      //default
  29. #define RTS_UART_STOP_BITS_2        (1<<10)
  30. #define RTS_UART_STOP_BITS_1_5      (1<<11)
  31. #define RTS_UART_STOP_BITS_0_5      (1<<12)

  32. #define RTS_UART_POLL_SEND          (1<<13)     //default
  33. #define RTS_UART_POLL_READ          (1<<14)
  34. #define RTS_UART_INTTERPUT_SEND     (1<<15)
  35. #define RTS_UART_INTTERPUT_READ     (1<<16)     //defalut
  36. #define RTS_UART_DMA_SEND           (1<<17)
  37. #define RTS_UART_DMA_READ           (1<<18)
  38. #define RTS_UART_QUEUE_SEND         (1<<19)
  39. #define RTS_UART_QUEUE_READ         (1<<20)


  40. #pragma anon_unions
  41. struct rts_uart
  42. {
  43.     struct
  44.     {
  45.         uint32_t support_poll_send:1;
  46.         uint32_t support_poll_read:1;
  47.         uint32_t support_intterput_send:1;
  48.         uint32_t support_intterput_read:1;
  49.         uint32_t support_dma_send:1;
  50.         uint32_t support_dma_read:1;
  51.         uint32_t support_queue_send:1;
  52.         uint32_t support_queue_read:1;
  53.     };

  54.     rts_uart_err_t (*init)(struct rts_uart *dev);
  55.     void (*uninit)(struct rts_uart *dev);
  56.     rts_uart_err_t (*control)(struct rts_uart *dev,uint32_t control,uint32_t arg);

  57.     uint32_t (*poll_send)(struct rts_uart *dev,uint8_t *buffer,uint32_t len);
  58.     uint32_t (*poll_read)(struct rts_uart *dev,uint8_t *buffer,uint32_t size);

  59.     uint32_t (*intterput_send)(struct rts_uart *dev,uint8_t *buffer,uint32_t len);
  60.     void (*intterput_read_set_callback)(struct rts_uart *dev,void (*callback)(uint8_t data));

  61.     uint32_t (*dma_send)(struct rts_uart *dev,uint8_t *buffer,uint32_t len);
  62.     void (*dma_read_set_callback)(struct rts_uart *dev,uint8_t *dmabuffer,uint32_t size,void (*callback)(uint8_t *buf,uint32_t len));

  63.     uint32_t (*queue_send)(struct rts_uart *dev,uint8_t *buffer,uint32_t len);
  64.     uint32_t (*queue_read)(struct rts_uart *dev,uint8_t *buffer,uint32_t len);

  65. };

  66. //rts uart api
  67. inline rts_uart_err_t rts_uart_init(struct rts_uart *dev);
  68. inline void rts_uart_uninit(struct rts_uart *dev);
  69. inline rts_uart_err_t rts_uart_control(struct rts_uart *dev,uint32_t control,uint32_t arg);

  70. inline uint32_t rts_uart_poll_send(struct rts_uart *dev,uint8_t *buffer,uint32_t len);
  71. inline uint32_t rts_uart_poll_read(struct rts_uart *dev,uint8_t *buffer,uint32_t size);

  72. inline uint32_t rts_uart_intterput_send(struct rts_uart *dev,uint8_t *buffer,uint32_t len);
  73. inline void rts_uart_intterput_read_set_callback(struct rts_uart *dev,void (*callback)(uint8_t data));

  74. inline uint32_t rts_uart_dma_send(struct rts_uart *dev,uint8_t *buffer,uint32_t len);
  75. inline void rts_uart_dma_read_set_callback(struct rts_uart *dev,uint8_t *dmabuffer,uint32_t size,void (*callback)(uint8_t *buf,uint32_t len));

  76. inline uint32_t rts_uart_queue_send(struct rts_uart *dev,uint8_t *buffer,uint32_t len);
  77. inline uint32_t rts_uart_queue_read(struct rts_uart *dev,uint8_t *buffer,uint32_t len);

  78. #endif
复制代码


  1. #include "rts_uart.h"
  2. #include "stdint.h"

  3. inline rts_uart_err_t rts_uart_init(struct rts_uart *dev)
  4. {
  5.     return dev->init(dev);
  6. }
  7. inline void rts_uart_uninit(struct rts_uart *dev)
  8. {
  9.     dev->uninit(dev);
  10. }
  11. inline rts_uart_err_t rts_uart_control(struct rts_uart *dev,uint32_t control,uint32_t arg)
  12. {
  13.     return dev->control(dev,control,arg);
  14. }

  15. inline uint32_t rts_uart_poll_send(struct rts_uart *dev,uint8_t *buffer,uint32_t len)
  16. {
  17.     if(!dev->support_poll_send) return 0;

  18.     return dev->poll_send(dev,buffer,len);
  19. }
  20. inline uint32_t rts_uart_poll_read(struct rts_uart *dev,uint8_t *buffer,uint32_t len)
  21. {
  22.     if(!dev->support_poll_read)return 0;

  23.     return dev->poll_read(dev,buffer,len);
  24. }

  25. inline uint32_t rts_uart_intterput_send(struct rts_uart *dev,uint8_t *buffer,uint32_t len)
  26. {
  27.     if(!dev->support_intterput_send)return 0;

  28.     return dev->intterput_send(dev,buffer,len);
  29. }
  30. inline void rts_uart_intterput_read_set_callback(struct rts_uart *dev,void (*callback)(uint8_t data))
  31. {
  32.     if(!dev->support_intterput_read)return;

  33.     dev->intterput_read_set_callback(dev,callback);
  34. }

  35. inline uint32_t rts_uart_dma_send(struct rts_uart *dev,uint8_t *buffer,uint32_t len)
  36. {
  37.     if(!dev->support_dma_send)return 0;

  38.     return dev->dma_send(dev,buffer,len);
  39. }
  40. inline void rts_uart_dma_read_set_callback(struct rts_uart *dev,uint8_t *dmabuffer,uint32_t size,void (*callback)(uint8_t *buf,uint32_t len))
  41. {
  42.     if(!dev->support_dma_read)return;

  43.     dev->dma_read_set_callback(dev,dmabuffer,size,callback);
  44. }

  45. inline uint32_t rts_uart_queue_send(struct rts_uart *dev,uint8_t *buffer,uint32_t len)
  46. {
  47.     if(!dev->support_queue_send)return 0;

  48.     return dev->queue_send(dev,buffer,len);
  49. }
  50. inline uint32_t rts_uart_queue_read(struct rts_uart *dev,uint8_t *buffer,uint32_t len)
  51. {
  52.     if(!dev->support_queue_read)return 0;

  53.     return dev->queue_read(dev,buffer,len);
  54. }
复制代码

出0入4汤圆

发表于 2020-10-25 12:58:13 来自手机 | 显示全部楼层
用C++吧,你会发现你想要的有更完美的实现。

出0入8汤圆

 楼主| 发表于 2020-10-25 15:24:14 | 显示全部楼层
xiaoergao 发表于 2020-10-25 12:58
用C++吧,你会发现你想要的有更完美的实现。

给点思路呗

出0入0汤圆

发表于 2020-10-25 16:22:44 来自手机 | 显示全部楼层
使用类,应该是很容易的吧

出0入8汤圆

 楼主| 发表于 2020-10-25 16:57:31 | 显示全部楼层
way2888 发表于 2020-10-25 16:22
使用类,应该是很容易的吧

类一些函数不用的话,不能优化掉吧?

出0入0汤圆

发表于 2020-10-25 18:02:52 来自手机 | 显示全部楼层
你测一下就知道了,应该会优化调吧

出0入4汤圆

发表于 2020-10-25 21:34:27 | 显示全部楼层
本帖最后由 xiaoergao 于 2020-10-25 21:40 编辑


定义成类,不同的对象只是成员变量占内存,所有的对象共用方法。我贴个我写的usart的头文件抛砖引玉一下。
class USART: public StringIO{
        public:
                USART(USART_TypeDef *USARTx, Gpio *pTx, Gpio * tRx);
                void init(u32 baud);
                void init(u32 baud, u8 dataBit, u8 parity, float stopBit);
                void send(u8* pBuf, u16 size);
                void sendString(char* pStr);
                void sendInt(int num);
                void putChar(char c);
                int isTxBusy();
                virtual                void printf(const char *fmt, ...);
       
                void rxReset();
                virtual                char* getRxBufferAddr();
                virtual                int getRxLength();
                virtual                char* getRxString();
                char* getTxBufferAddr();

                static u32 pSelfObjectArr[6];
                static void _IRQCallBack(u32 pCallerObject);
       
                void attach(void (*hook)(void));
               
                template<typename T>
                void attach(T *pObject, void (T::*member)(void));
        private:
                char                                recieveBuf[256];
                USART_TypeDef *         USARTx;
                Gpio*                                 pTx;
                Gpio*                                pRx;
                Dma*                                pTxDma;
                Dma*                                pRxDma;
                char                                sendBuf[256];
                CallBack*                        pCB;
};


使用的时候
void handle(){
        uart1.rxReset();
        memcpy(&buf,uart1.getRxBufferAddr(),uart1.getRxLength());
        LED.toggle();
}

void serialInit(){
        uart1.init(115200);
        uart1.printf("uart1 init,baud is %d",115200)
        uart1.attach(handle);
}

出0入4汤圆

发表于 2020-10-25 21:40:15 | 显示全部楼层
1、第一行类的声明使用了继承,可以先忽略。
2、attach()方法那里,我为了回调对象的方法使用了C++模板的语法,如果只是调用函数的话也可以忽略。

出100入85汤圆

发表于 2020-10-25 23:56:38 来自手机 | 显示全部楼层
xiaoergao 发表于 2020-10-25 21:40
1、第一行类的声明使用了继承,可以先忽略。
2、attach()方法那里,我为了回调对象的方法使用了C++模板的语 ...

干脆共享下你造的这个轮子呗
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-19 14:05

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表