总线(bus)、驱动(driver)和设备(device)模型,比 如 I2C、SPI、USB 等总线。但是在 SOC 中哪些外设是没有总线这个概念的,需要用到plantform总线
时间: 2024-05-19 13:12:05 浏览: 116
在SOC中,一些外设可能没有与主处理器直接连接的总线,而是通过一种称为“平台总线”(platform bus)的机制来进行通信。平台总线是SOC中的一种内部总线,它连接了主处理器与外设控制器,并提供了一种标准的设备驱动程序接口。通常情况下,平台总线是由SOC厂商设计的,用于连接特定的外设和处理器,比如GPIO控制器、定时器、看门狗等。平台总线的作用是屏蔽硬件细节,使得驱动程序可以更加方便地访问外设,同时也可以提高系统的可移植性和可维护性。
需要注意的是,平台总线并不是一种通用的总线协议,不同的SOC厂商可能会采用不同的平台总线协议,因此在编写驱动程序时需要根据具体的硬件平台选择相应的平台总线协议。
相关问题
简述Linux的总线设备模型
Linux的总线设备模型是一种系统级架构设计,它允许硬件设备通过各种不同的通信协议连接到系统的总线上。这种模型基于层次结构,主要包括以下几个关键部分:
1. **硬件抽象层** (Hardware Abstraction Layer, HAL):它是硬件设备驱动程序与内核之间的桥梁,封装了硬件的具体细节,使得驱动可以以一致的方式处理所有类型的设备。
2. **总线接口控制器** (Bus Controller):如PCI、USB、SPI、I2C等,负责管理特定类型的总线,并提供数据传输和配置功能给设备驱动。
3. **设备树** (Device Tree):这是一种XML格式的数据结构,描述了板载硬件设备的位置、属性和连接关系,内核根据这个数据初始化硬件。
4. **设备文件** (Device Files):在设备节点目录下,每个实际物理设备对应一个或多个设备文件,用户空间应用程序通过操作这些文件来控制设备。
5. **设备驱动** (Kernel Driver):具体的设备驱动实现了与硬件交互的代码,负责设备的枚举、打开、读写等操作。
6. **虚拟设备** (Virtual Devices):通过软件模拟的设备,可以提供额外的功能或作为其他设备的代理,比如IDE转AHCI。
spi驱动st7796代码
ST7796是一款LCD控制器,其使用时需要通过SPI来与主机进行通信。所以,编写SPI驱动程序就成了使用该控制器的必要步骤。
以下是一份可供参考的ST7796的SPI驱动代码:
```c
#include <linux/spi/spi.h>
#include <linux/module.h>
/*定义SPI设备信息*/
#define SPI_BUS_NUM 2
static struct spi_device *st7796_spi_device;
/*SPI传输信息*/
static struct spi_transfer st7796_spi_transfers[2];
static unsigned char st7796_frame_control = 0;
static unsigned char st7796_display_mode = 0;
/* 将SPI传输结果输出到屏幕上 */
static void st7796_show_result(unsigned char *buf, int len)
{
int i;
for (i = 0; i < len; i++) {
printk(KERN_CRIT "%02X ", buf[i]);
}
printk(KERN_CRIT "\n");
}
/* 初始化SPI设备 */
static int st7796_spi_probe(struct spi_device *spi)
{
st7796_spi_device = spi;
return 0;
}
/* 取消SPI设备的使用 */
static int st7796_spi_remove(struct spi_device *spi)
{
st7796_spi_device = NULL;
return 0;
}
/* SPI传输完成后的回调函数 */
static void st7796_spi_complete(void *ref)
{
st7796_show_result((unsigned char *)ref, st7796_spi_transfers[1].len);
}
/*写出SPI传输信息*/
static void st7796_spi_write(const unsigned char *data, int len)
{
struct spi_message msg;
spi_message_init(&msg);
/* 实现 SPI 数据传输的 API */
st7796_spi_transfers[0].tx_buf = (void *) data;
st7796_spi_transfers[0].len = len;
st7796_spi_transfers[1].rx_buf = (void *)&st7796_frame_control;
st7796_spi_transfers[1].len = sizeof(st7796_frame_control);
st7796_spi_transfers[1].delay_usecs = 10;
spi_message_add_tail(&st7796_spi_transfers[0], &msg);
spi_message_add_tail(&st7796_spi_transfers[1], &msg);
spi_message_set_completion(&msg, st7796_spi_complete, (void *)data);
/* 将消息同步发送到 SPI 控制器 */
spi_sync(st7796_spi_device, &msg);
}
/*配置SPI参数*/
static int st7796_spi_setup(void)
{
int ret;
struct spi_master *master;
struct spi_device *spi;
/*获取SPI总线信息*/
master = spi_busnum_to_master(SPI_BUS_NUM);
if (!master) {
printk(KERN_CRIT "spi master not found");
return -ENODEV;
}
/*定义SPI设备*/
spi = spi_alloc_device(master);
if (!spi) {
printk(KERN_CRIT "can not alloate spi device");
return -ENOMEM;
}
/*初始化 SPI 设备对应的结构体*/
spi->bits_per_word = 8;
spi->max_speed_hz = 2 * 1000 * 1000;
spi->mode = SPI_MODE_0;
spi->chip_select = 0;
spi->controller_data = &st7796_spi_device;
/*配置 SPI 传输和回调函数*/
spi->setup = st7796_spi_setup;
spi->probe = st7796_spi_probe;
spi->remove = st7796_spi_remove;
/*将 spi_device 确定为所属的 spi_master 的一员*/
ret = spi_add_device(spi);
if (ret < 0) {
printk(KERN_CRIT "can not add spi device");
return ret;
}
st7796_spi_device = spi;
return 0;
}
/* 清除屏幕上的画面 */
static void st7796_clear_screen(void)
{
unsigned char data = 0x01;
st7796_spi_write(&data, sizeof(data)); /* 发送清屏指令 */
}
/*配置显示模式*/
static void st7796_display_config(void)
{
st7796_frame_control = 0x06;
st7796_display_mode = 0x2C;
/*先发送数据模式,再发送帧控制模式*/
st7796_spi_write(&st7796_display_mode, sizeof(st7796_display_mode));
st7796_spi_write(&st7796_frame_control, sizeof(st7796_frame_control));
}
static int __init st7796_init(void)
{
int ret;
ret = st7796_spi_setup(); /* 初始化SPI设备 */
if (ret < 0) {
printk(KERN_CRIT "setup spi error\n");
return -ENODEV;
}
st7796_clear_screen(); /* 清屏 */
st7796_display_config(); /* 配置显示模式 */
return 0;
}
static void __exit st7796_exit(void)
{
spi_unregister_device(st7796_spi_device);
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("xxx");
MODULE_DESCRIPTION("ST7796 SPI Driver");
MODULE_VERSION("1.0");
module_init(st7796_init);
module_exit(st7796_exit);
```
这份代码主要实现了SPI的驱动程序,通过定义SPI总线设备进行通信。在初始化之后,可以通过向ST7796发送指令来控制其显示画面。此外,还可以利用回调函数来处理SPI传输之后的响应信息。
值得指出的是,这份代码只是一个简单的示例,还需要根据具体的项目进行修改才能正常使用。用户可以依据此代码进行参考,以实现自己的SPI驱动程序。
阅读全文