K230 板载温度传感器驱动移植与开发
在嵌入式系统开发中,板载温度传感器是一个常见而实用的外设。它可以实时反映芯片工作时的温度状态,为系统的散热管理和安全保护提供依据。本文将记录我在
K230 平台 上移植和开发温度传感器驱动的过程,并通过
RT-Thread 的设备框架进行测试验证。
一、硬件背景
K230 芯片内部集成了一个 温度传感器模块 ,不需要外接额外器件即可直接读取芯片温度。
其工作原理大致为:
这意味着我们只需通过驱动代码正确访问寄存器,并进行一次数据转换,即可得到可用的温度信息。
二、驱动框架与寄存器说明
温度传感器驱动主要基于 RT-Thread 设备模型 实现,驱动文件为 drv_ts.c。
1. 寄存器定义
// Register offsets
#define REG_TSENW_OFFSET 0x000
#define REG_TSENR_OFFSET 0x004
// Bit positions for REG_TSENW
#define TSENW_TS_CONV_MODE_POS 1
#define TSENW_TS_EN_POS 0
// Bit positions for REG_TSENR
#define TSENR_TS_DOUT_VALID_POS 12
#define TSENR_TS_DOUT_MASK 0xFFF
**REG_TSENW 用于配置传感器的模式和启动;
REG_TSENR 用于读取采样结果。**
相关位定义:
2. 温度转换公式
原始 ADC 值并不是直接的摄氏温度,需要经过四阶多项式拟合:
static double
tsensor_calculate_temperature(uint16_t data)
{
return (1e-10 * pow(data, 4) * 1.01472
- 1e-6 * pow(data, 3) * 1.10063
+ 4.36150 * 1e-3 * pow(data, 2)
- 7.10128 * data
+ 3565.87);
}
这段公式会将 ADC 值映射为实际温度,单位为摄氏度。
三、驱动实现
驱动代码主要包括以下几个部分:
1. 启动与停止传感器
static rt_err_t tsensor_start(void)
{
uint32_t reg_val = readl(ts_base_addr + REG_TSENW_OFFSET);
reg_val |= (1 << TSENW_TS_EN_POS); // 开启传感器
writel(reg_val, ts_base_addr + REG_TSENW_OFFSET);
return RT_EOK;
}
static rt_err_t tsensor_stop(void)
{
uint32_t reg_val = readl(ts_base_addr + REG_TSENW_OFFSET);
reg_val &= ~(1 << TSENW_TS_EN_POS); // 关闭传感器
writel(reg_val, ts_base_addr + REG_TSENW_OFFSET);
return RT_EOK;
}
2. 数据读取
static int tsensor_read_data(uint16_t *data, uint32_t timeout_ms)
{
for (uint32_t attempt = 0; attempt < timeout_ms; attempt++)
{
if ((readl(ts_base_addr + REG_TSENR_OFFSET) >> TSENR_TS_DOUT_VALID_POS) & 0x1)
{
*data = readl(ts_base_addr + REG_TSENR_OFFSET) & TSENR_TS_DOUT_MASK;
return RT_EOK; // 成功读取
}
rt_thread_mdelay(1); // 轮询等待
}
return -RT_ETIMEOUT; // 超时
}
3. RT-Thread 设备接口封装
驱动最终以 "ts" 的名字注册为 RT-Thread 设备:
static const struct rt_device_ops ts_ops =
{
.open = ts_device_open,
.close = ts_device_close,
.read = ts_device_read,
.control = ts_device_control
};
static rt_err_t register_ts_device(void)
{
return rt_device_register(&ts_device, "ts", RT_DEVICE_FLAG_RDWR);
}
这样应用层就能通过标准 rt_device_* 接口访问温度传感器。
2. 参数配置
3. RT-Thread 设备接口
驱动将温度传感器封装为 RT-Thread 标准设备 ts:
注册设备的代码:
ret = rt_device_register(device,
"ts", RT_DEVICE_FLAG_RDWR);
注册完成后,应用层可通过 "ts" 这个设备名访问传感器。
四、驱动移植步骤
在 K230 平台上移植这个驱动大致分为以下几个步骤:
ts_base_addr = rt_ioremap((void *)TS_BASE_ADDR, TS_IO_SIZE);
将物理地址映射为内核虚拟地址。
rt_mutex_init(&ts_mutex,"dev_ts", RT_IPC_FLAG_PRIO);
保证多线程访问安全。
调用 register_ts_device() 将温度传感器注册到 RT-Thread 设备框架中。
使用 RT-Thread 的
INIT_DEVICE_EXPORT(rt_hw_ts_init);,在系统启动时自动执行初始化。
五、测试程序
驱动编译进系统后,可以通过 utest 框架编写单元测试。主要测试点有两个:
static void test_ts_read(void)
{
double temp = 0;
rt_device_t ts_dev = rt_device_find("ts");
rt_device_open(ts_dev, RT_DEVICE_OFLAG_RDWR);
for (int i = 0; i < 5; i++)
{
rt_device_read(ts_dev, 0, &temp, sizeof(double));
LOG_I("Temperature = %.2f C\n", temp);
rt_thread_mdelay(1000);
}
rt_device_close(ts_dev);
}
连续读取 5 次,打印温度。
日志输出示例:
六、运行结果与效果
在 K230-01studio 开发板上运行测试程序时,可以观察到:
这说明温度传感器驱动移植成功,并能在 RT-Thread 框架下稳定运行。
详细驱动可见
七、总结
通过本次驱动移植与开发,实现了以下目标:
温度传感器虽然只是一个小外设,但在实际应用中十分重要。例如:
举报
更多回帖