3672
- 收藏
- 点赞
- 分享
- 举报
Hi3515 UART2和UART3驱动加载
这里主要想讲下海思Hi3515的UART2和UART3是如何被加载到内核中的,因为正在做一个项目需要使用四个串口,但海思提供的linux源码中只加载了两个串口的驱动,找了一圈,发现源码中没有现成的UART2和UART3的代码可以使用,只能自己动手改啦啊。。。
首先关于linux硬件模块的加载可以参考下面这篇博文:
[url]http://hi.baidu.com/jackyu/blog/item/a89ba634e31418bcd1a2d3e5.html[/url]
好吧,我们进入正题,说说我做的过程:
Hi3515的UART驱动位于drivers/serial/amba-pl011.c
我们沿着pl011_init——amba_driver_register——driver_register——bus_add_driver——driver_attach——bus_for_each_dev往下走,找到bus_for_each_dev函数:
int bus_for_each_dev(struct bus_type * bus, struct device * start,
void * data, int (*fn)(struct device *, void *))
{
struct klist_iter i;
struct device * dev;
int error = 0;
if (!bus)
return -EINVAL;
klist_iter_init_node(&bus->klist_devices, &i,
(start ? &start->knode_bus : NULL));
while ((dev = next_device(&i)) && !error)
error = fn(dev, data);
klist_iter_exit(&i);
return error;
}
注意其中的
while ((dev = next_device(&i)) && !error)
error = fn(dev, data);
就是这两条语句依次加载了四个串口驱动,这里的fn是外层的__driver_attach函数。。。
既然找到了加载的地方,那就printk吧,发现这个循环只进行了两次,也就是说只加载了串口0和串口1,说明链表里面只有两个串口的信息,那到底在什么地方把另外两个串口的信息添加进链表呢,google一番,终于找到啦,在arch/arm/mach-hi3515v100/core.c中我们将另外两个串口的信息加进去,编译,烧写,启动,发现/dev目录下已经有了ttyAMA2和ttyAMA3,兴奋了一下,上应用程序,上示波器,悲剧鸟,仍然没有数据出来,蛋疼啊。。。
于是继续往下找,找到pl011_tx_chars函数,直接在这里printk,看看我们用串口2和串口3发数据的时候写的到底是哪个寄存器,结果还真是串口2和串口3的数据寄存器,看到这个我有预感离胜利不远了啊,但为啥既然写的地址是对的,就是写不进去呢。。。回头翻Hi3515的手册,奶奶的,串口2和串口3收发数据的四个引脚是复用的,必须得配置复用控制寄存器,好,搞定这个继续编译,烧写,运行,上应用程序,上示波器,数据果然出来啦,happy。。。
顺便提醒一下,写复用控制寄存器的时候要用重映射之后的地址哦,不然会出错滴。。。
首先关于linux硬件模块的加载可以参考下面这篇博文:
[url]http://hi.baidu.com/jackyu/blog/item/a89ba634e31418bcd1a2d3e5.html[/url]
好吧,我们进入正题,说说我做的过程:
Hi3515的UART驱动位于drivers/serial/amba-pl011.c
我们沿着pl011_init——amba_driver_register——driver_register——bus_add_driver——driver_attach——bus_for_each_dev往下走,找到bus_for_each_dev函数:
int bus_for_each_dev(struct bus_type * bus, struct device * start,
void * data, int (*fn)(struct device *, void *))
{
struct klist_iter i;
struct device * dev;
int error = 0;
if (!bus)
return -EINVAL;
klist_iter_init_node(&bus->klist_devices, &i,
(start ? &start->knode_bus : NULL));
while ((dev = next_device(&i)) && !error)
error = fn(dev, data);
klist_iter_exit(&i);
return error;
}
注意其中的
while ((dev = next_device(&i)) && !error)
error = fn(dev, data);
就是这两条语句依次加载了四个串口驱动,这里的fn是外层的__driver_attach函数。。。
既然找到了加载的地方,那就printk吧,发现这个循环只进行了两次,也就是说只加载了串口0和串口1,说明链表里面只有两个串口的信息,那到底在什么地方把另外两个串口的信息添加进链表呢,google一番,终于找到啦,在arch/arm/mach-hi3515v100/core.c中我们将另外两个串口的信息加进去,编译,烧写,启动,发现/dev目录下已经有了ttyAMA2和ttyAMA3,兴奋了一下,上应用程序,上示波器,悲剧鸟,仍然没有数据出来,蛋疼啊。。。
于是继续往下找,找到pl011_tx_chars函数,直接在这里printk,看看我们用串口2和串口3发数据的时候写的到底是哪个寄存器,结果还真是串口2和串口3的数据寄存器,看到这个我有预感离胜利不远了啊,但为啥既然写的地址是对的,就是写不进去呢。。。回头翻Hi3515的手册,奶奶的,串口2和串口3收发数据的四个引脚是复用的,必须得配置复用控制寄存器,好,搞定这个继续编译,烧写,运行,上应用程序,上示波器,数据果然出来啦,happy。。。
顺便提醒一下,写复用控制寄存器的时候要用重映射之后的地址哦,不然会出错滴。。。
我来回答
回答8个
时间排序
认可量排序
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币
Markdown 语法
- 加粗**内容**
- 斜体*内容*
- 删除线~~内容~~
- 引用> 引用内容
- 代码`代码`
- 代码块```编程语言↵代码```
- 链接[链接标题](url)
- 无序列表- 内容
- 有序列表1. 内容
- 缩进内容
- 图片
相关问答
-
2015-07-13 09:04:42
-
2015-04-20 13:17:14
-
2018-12-18 14:02:08
-
2017-09-25 20:16:48
-
152017-01-04 14:16:57
-
2019-11-15 14:53:22
-
2017-09-29 11:51:10
-
2018-07-18 21:28:06
-
2016-09-01 14:09:58
-
2016-08-31 11:14:58
-
2015-04-29 18:15:35
-
2015-11-04 15:39:07
-
2016-08-03 09:41:26
-
2019-03-16 14:18:14
-
2015-04-21 09:23:58
-
142015-07-10 12:41:08
-
2016-11-14 10:34:44
-
2019-05-21 15:12:19
-
2015-01-16 10:50:01
无更多相似问答 去提问

点击登录
-- 积分
-- E币
提问
—
收益
—
被采纳
—
我要提问
切换马甲
上一页
下一页
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
提醒
你的问题还没有最佳答案,是否结题,结题后将扣除20%的悬赏金
取消
确认
提醒
你的问题还没有最佳答案,是否结题,结题后将根据回答情况扣除相应悬赏金(1回答=1E币)
取消
确认