[交流][拍砖]新版驱动接口风格调查(三):信号系统
本帖最后由 Gorgon_Meducer 于 2014-5-20 16:16 编辑说在前面的话
这次是关于中断系统的接口……默默等待房产……
解释下:现在的格式是这样的,
SIGNAL_CFG(
SINGLE(<中断向量:SIGNAL0..SIGNAL31>, <信号源:手动信号 / 外设信号>, <信号用途:触发中断 / 触发外设功能>,
<信号源的检测方式:上升沿,下降沿,双边沿,高电平,低电平,每xx次才触发一次>|<是否产生中断,其它属性>),
...
)
我关心的是对用户来说,这种方式是否灵活,易用。
比如,你可以吐槽我的例子比较渣,但是你立即就知道,并且有自己的欲望去实现一个自己的例子,关键就是你立即就知道如何自己去做
这是新版本编码规范的一个范例代码,包含对应的驱动模型和接口规范,我希望在不提供进一步解说的情况下听听大家
的意见,并提供以下信息:
1、第一眼给你的感受,是喜欢 恐惧 还是 茫然无措
2、顺次阅读代码后,代码要表达的意思你是否已经了解大概,表意是否清晰
3、有什么你觉得疑惑的地方?
4、有什么改进意见?
5、任何批评意见都是非常欢迎的
如果可能,希望大家能在回帖中描述下你理解的代码的行为。
这个库的目标就是要让代码使用起来简单,不仅仅要屏蔽底层的寄存器操作,还要做到功能和意义一目了然。
参与的人,即便自觉是菜鸟,也不用觉得自己水平不够之类的,因为你们就是最终的用户,你们是最有发言权的!
非常感谢大家的参与。
P.S: 这个库将是未来一个实质性的半导体产品的系统库。
范例一:USART数据接收完成中断
SIGNAL_CFG(
//! 一旦USART0的接收缓冲区中有数据(Data Available),就产生中断,并复位TIMER0
SINGLE( SIGNAL0, USE_SIGNAL_USART0_RX_FIFO_DAVL, TO_TRIGGER(INTERRUPT_REQUEST , TIMER0_RESET), EVERY_TIME ),
//! 如果很久没有发生USART0的接收事件,导致TIMER0溢出了,就认为发生了接收超时,触发中断处理程序
SINGLE( SIGNAL1, USE_SIGNAL_TIMER0_OVF, TO_TRIGGER(INTERRUPT_REQUEST), EVERY_TIME),
);
ISR(SIGNAL0_vect)
{
//! Signal0 的中断处理程序,当USART的接收缓冲区中存在数据时,该中断被触发
}
ISR(SIGNAL1_vect)
{
//! Signal1 的中断处理程序, 定时器0的溢出事件触发,表示USART通信超时,用TIMER0的TOP值设置超时范围
}
范例二:用DMA从USART接收数据
这是直接用DMA的例子,当USART0的缓冲区中有数据可用的时候,自动触发DMA进行搬运
#define USART0_RX_BUFFER_SIZE 256
static uint8_t s_chUSARTBuffer;
static void start_usart_dma_transfer(void)
{
DMA_CHN_CFG(
DMA_CHANNEL0, //!< 使用DMA的通道0
DMA_CHN_BURST_TRANSFER | //!< 分多次完成数据传输
DMA_CHN_BURST_SIZE_1, //!< 每次传输一个数据(数据类型由DMA_TSF_CFG指定)
//! 配置一次传输
DMA_TSF_CFG (
DMA_TSF_MODE_PERIPHRAL_TO_MEMORY, //!< 从外设到内存的搬运方式
DMA_TSF_DATA_BITS_BYTE, //!< 每次搬运的数据类型是字节
&GSP_USART0.RBR_THR_DLL.RBR.Value,//!< 源地址
s_chUSARTBuffer //!< 目标地址
)
);
}
void app_init(void)
{
...
SIGNAL_CFG(
//! 一旦USART0的接收缓冲区中有数据(Data Available),就触发DMA通道0从USART版运数据
SINGLE( SIGNAL0, USE_SIGNAL_USART0_RX_FIFO_DAVL, TO_TRIGGER(DMA0_CHN0_TSF), EVERY_TIME ),
//! 当DMA完成指定数量数据的搬运后,触发中断,由中断来配置下一次的DMA
SINGLE( SIGNAL1, USE_DMA_CHN0_FINAL_TSF, TO_TRIGGER(INTERRUPT_REQUEST), EVERY_TIME),
);
//! 配置USART0
USART_CFG(
USART0,
USART_8_BIT_LENGTH| //!< 8数据位
USART_1_STOPBIT | //!< 1停止位
USART_NO_PARITY, //!< 无校验
9600 //!< 9600波特率
);
//! 配置DMA进行USART的数据传输
start_usart_dma_transfer();
...
}
ISR(SIGNAL1_vect)
{
//! 配置下一次DMA传输
start_usart_dma_transfer();
}
范例三:外中断
SELECT_PIN_SIGNAL_SOURCE(PIN_CHN0, PA6);
SELECT_PIN_SIGNAL_SOURCE(PIN_CHN1, PA7);
SELECT_PORT_GROUP_SIGNAL_SOURCE(PORT_GROUP_CHN0, PB0_MSK | PB1_MSK | PB2_MSK | PB3_MSK)
SIGNAL_CFG(
//! 在PA6的第61个上升沿产生一个中断
SINGLE(SIGNAL0, USE_SIGNAL_PIN_CHN0, TO_TRIGGER(INTERRUPT_REQUEST), ON_RAISING_EDGE | EVERY_61_TIME),
//! 在PA7每保持低电平32个系统周期,产生一个中断
SINGLE(SIGNAL1, USE_SIGNAL_PIN_CHN1, TO_TRIGGER(INTERRUPT_REQUEST), ON_LOW_LEVEL | EVERY_32_TIME),
//! PB0, PB1, PB2, PB3 任何一个引脚的双边沿产生一个中断
SINGLE(SIGNAL2, USE_SIGNAL_PORT_GROUP_CHN0, TO_TRIGGER(INTERRUPT_REQUEST), ON_BOTH_EDGE},
)
ISR(SIGNAL0_vect)
{
//! Signal0 的中断处理程序,
}
ISR(SIGNAL1_vect)
{
//! Signal1 的中断处理程序,
}
ISR(SIGNAL2_vect)
{
//! Signal2 的中断处理程序,
}
占位…… 最近也想做个类似的系统,正好看看中断怎么封装 学习一下 为什么手机神马代码也看不到 zhexuejia 发表于 2013-11-16 13:47 static/image/common/back.gif
为什么手机神马代码也看不到
切换到电脑版就可以看到了 这样写,能看懂。
只要所有库的书写和变量命名保持一致就可以。 SIGNAL_CFG(
//! 使用USART0接收完成事件产生中断,因为USART有16字节的FIFO,所以我们配置该事件每8次才触发一次中断
{ SIGNAL0, USE_USART0_RX_CPL, TO_GENERATE_INTERRUPT, EVERY_8_TIMES, ENABLE_INTERRUPT },
//! 用USART0接收完成事件来复位定时器到0
{ SIGNAL1, USE_USART0_RX_CPL, TO_TRIGGER_TIMER0_RESET},
//! 用定时器0的溢出事件来产生中断,这个中断实际上表示很久没有发生通信了,是一个通信超时中断
{ SIGNAL2, USE_TIMER0_OVF, TO_GENERATE_INTERRUPT, EVERY_TIME, ENABLE_INTERRUPT},
)
----------------------------------------------------------------------------------------------------------------------------------------------------
这一段看不懂;
不知道信号和中断有啥关系,中断不是硬件本身的属性吗?中断向量在单片机的地址也都是固定的吧?信号是楼主自定义的数据结构吧?这两个有必然的联系吗?
ISR(SIGNAL0)
{
//! Signal0 的中断处理程序,每8个USART0接收完成事件触发一次
}
----------------------------------------------------------------------------------------------------------------------------------------------------
这个如果是中断处理程序我觉得并不够明确,如果不看前面一段,只看通过括号里的SIGNAL0并不能知道是啥中断,还要考函数里的注释才能知道,还不如用一个有意义的函数名表示来的清晰,我是菜鸟,理解的比较浅,吐槽完毕。另外第21行是不是应该改成Signal2? sbk100 发表于 2013-11-16 22:41 static/image/common/back.gif
SIGNAL_CFG(
//! 使用USART0接收完成事件产生中断,因为USART有16字节的FIFO,所以我们配置该事件 ...
SIGNAL不是一个数据结构,是一个硬件概念,SIGNAL可以用来产生中断,也可以用来直接触发
外设的动作而不经过内核的干预。我的这个系统中,中断向量表是用户自己定义的,可以选择任
何自己感兴趣的信号来产生中断,所以中断处理程序是以Signal为单位的。 Gorgon_Meducer 发表于 2013-11-16 23:00 static/image/common/back.gif
SIGNAL不是一个数据结构,是一个硬件概念,SIGNAL可以用来产生中断,也可以用来直接触发
外设的动作而不 ...
上面仁兄抓了个虫子:范例一第21行,注释Signal1应该改成Signal2. 什么是“默默等待房产”? catwill 发表于 2013-11-17 16:40 static/image/common/back.gif
什么是“默默等待房产”?
砖头数量多到可以盖房子啊 yiming988 发表于 2013-11-17 15:04 static/image/common/back.gif
上面仁兄抓了个虫子:范例一第21行,注释Signal1应该改成Signal2.
谢谢提醒,已经更正 无槽可吐肿么办? 竟然看懂了 。。。。{:victory:} zhexuejia 发表于 2013-11-18 15:15 static/image/common/back.gif
竟然看懂了 。。。。
要的就是这个效果哈 老帖了,表示也看懂了,感觉封装以后,考虑东西就清晰了,因为很多底层不需要关心。可能我的比喻不恰当,就好像Arduino把底层封装好,只有一个setup和一个loop似的。{:smile:} 我也看懂了,很开心,可以不用关心很多底层的配置,造福于民啊! didadida 发表于 2014-5-18 20:51
老帖了,表示也看懂了,感觉封装以后,考虑东西就清晰了,因为很多底层不需要关心。可能我的比喻不恰当,就 ...
这个接口又更新了,更简单,更强大。明天(周一)我来更新这个帖子。 更新了SIGNAL系统的范例。 MARK...................... 居然看懂了!
这么写的好处就是可以十分简洁明了地配置中断,同时也使得逻辑十分直接。用户只需要要知道自己想干什么,不需要知道具体实现的细节。配置过程直接描述了行为。
本帖最后由 dongfo 于 2014-5-19 15:21 编辑
但是,往往这样写了,也就意味着用户需要知道配置函数里面那些参数的意义,和使用范围。
看懂了容易,用起来的时候需要熟知命名规则。
正确的配置方法看起来会很和谐,如果用户想要自己配置的时候,可能会出现一些参数之间的组合,没有示例,也不知道具体的寄存器配置动作,就不知道这样是否可行。
还有就是,这样直接由用户指定中断向量的方式确很方便。但是好像没有提及中断优先级。 dongfo 发表于 2014-5-19 15:04
但是,往往这样写了,也就意味着用户需要知道配置函数里面那些参数的意义,和使用范围。
看懂了容易,用起 ...
我的理解是:这类代码都必须是代码生成器提供的,我应该有责任提供一套好用的图形化代码配置工具。
这类代码的生成应该是代码生成器来产生,产生的代码应该做到容易读懂。
同时,必要的说明文档来给用户提供培训也是必须的。你觉得呢?
中断优先级的问题其实是ARM的NVIC统一配置的,不过你提醒的对,我应该提供一个统一的配置接口。 向楼主致敬 Gorgon_Meducer 发表于 2014-5-19 15:59
我的理解是:这类代码都必须是代码生成器提供的,我应该有责任提供一套好用的图形化代码配置工具。
这类 ...
哈哈,最低的门槛,给“最懒”的用户。让一个只有十分有限知识基础的用户用上复杂的处理器。让世界更美很重要,让世界变简单也很重要----懒人自白。
是的图形界面,培训文档很重要。
这种写法比STM32的固件库人性化,STM32库函数很多,相互之间关联不是那么明显。
初学者往往会觉得使用库函数太复杂,和直接用寄存器相比没有太大的优势。如果没有示例,往往用户还是会直接去看手册,根据手册自己配置。
dongfo 发表于 2014-5-19 22:54
哈哈,最低的门槛,给“最懒”的用户。让一个只有十分有限知识基础的用户用上复杂的处理器。让世界更美很 ...
我会努力的
mark up 默默等待房产 崩盘?? 表示看不懂 太高升了!!!!!!!!!
页:
[1]