内容简介:在嵌入式设备中使用的存储芯片一般多用的Flash芯片或者EEPROM芯片的,它们的擦写次数大概是10万-100万次,而且写入时间也是毫秒级别,再一些对关键参数存储要求较高的场景下,就需要使用铁电存储器了,铁电存储器的读写次数以亿级来算,而且写入时间可以达到纳秒级,存储非常可靠。我最近在我们一款采集设备上应用到了一款FM24CL64的8KB的铁电存储器,该芯片是I2C接口的,该设备是基于mtk7688主芯片,linux内核的openwrt系统,应用程序采用go语言开发,研究了一下该芯片的手册后,基于linux
用 go 语言来做嵌入式-读写铁电存储器
存储器介绍
在嵌入式设备中使用的存储芯片一般多用的Flash芯片或者EEPROM芯片的,它们的擦写次数大概是10万-100万次,而且写入时间也是毫秒级别,再一些对关键参数存储要求较高的场景下,就需要使用铁电存储器了,铁电存储器的读写次数以亿级来算,而且写入时间可以达到纳秒级,存储非常可靠。
项目背景
我最近在我们一款采集设备上应用到了一款FM24CL64的8KB的铁电存储器,该芯片是I2C接口的,该设备是基于mtk7688主芯片,linux内核的openwrt系统,应用程序采用go语言开发,研究了一下该芯片的手册后,基于 linux 的标准i2c接口,编写了go语言版本的铁电存储器读写代码,并成功应用到产品中。
驱动和测试程序
const(
I2C_SLAVE_FORCE=1798 //标准i2c接口提供的设置i2c从机地址的命令号
I2C_TIMEOUT=1794 //标准i2c接口提供的设置i2c总线操作超时命令号
I2C_RETRIES=1793 //标准i2c接口提供的设置i2c总线重试次数的命令号
)
type FM24xxFram struct{
Fd int //i2c设备接口文件句柄
Bus int //i2c总线编号 从0开始
Addr int //i2c从机地址
Timeout int //超时时间
Retry int //重试次数
}
func NewFM24cxxFram(bus,addr,timeout,retry int)*FM24xxFram{
return &FM24xxFram{
Fd:-1,
Bus:bus,
Addr:addr,
Timeout:timeout,
Retry,retry,
}
}
//返回尺寸大小,以字节为单位 8192
func (f *FM24xxFram)Size()int {
return 8192
}
//打开铁电存储器总线设备
func (f *FM24xxFram)Open()error{
fd,err:=syscall.Open(fmt.Sprintf("/dev/i2c-%d",f.Bus),os.O_RDWR,0777)
if err!=nil{
return err
}
f.Fd = fd
syscall.Syscall(syscall.SYS_IOCTL,uintptr(fd),I2C_SLAVE_FORCE,uintptr(f.Addr))
syscall.Syscall(syscall.SYS_IOCTL,uintptr(fd),I2C_TIMEOUT,f.Timeout)
syscall.Syscall(syscall.SYS_IOCTL,uintptr(fd),I2C_RETRIES,f.Retry)
return nil
}
//关闭设备
func (f *FM24xxFram)Close(){
if f.Fd != -1{
syscall.Close(f.Fd)
}
f.Fd = -1
}
/*
往铁电某个地址写入数据
addr: 铁电的存储地址 从0 - 8K
p :需要写入的数据内容
*/
func (f *FM24xxFram)Write(addr int,p []byte)(n int, err error){
writeBuf :=make([]byte,2)
writeBuf[0]=byte((addr>>8)&0xff)
writeBuf[1]=byte(addr&0xff)
if len(p) > 0{
writeBuf=append(writeBuf,p...)
}
return syscall.Write(f.Fd,writeBuf)
//return f.File.Write(writeBuf)
}
/**
从铁电读取某个地址的数据
addr: 铁电的存储地址
p: 存放读取的数据
*/
func (f *FM24xxFram)Read(addr int,p []byte)(n int, err error){
//先定位到存储器的某个地址.
if n,err=f.Write(addr,[]byte{});err!=nil{
return
}
return syscall.Read(f.Fd,p)
}
测试程序如下:
package main
import "testing"
const FM24XX_I2C_ADDR=0x50
func TestRead(t *testing.T) {
fm:=NewFM24cxxFram(0,FM24XX_I2C_ADDR, 3, 10 )
if err:=fm.Open();err!=nil{
t.Errorf("Open Fm failed %v",err)
return
}
if _,err:=fm.Write(0,[]byte{1,2,3,4,5});err!=nil{
t.Errorf("Write Fm failed %v",err)
return
}
buf:=make([]byte,5)
if _,err:=fm.Read(0,buf);err!=nil{
t.Errorf("Read Fm failed %v",err)
return
}
t.Logf("Read Data=%v",buf)
}
怎么来玩
有兴趣研究go在嵌入式下应用的朋友,可以在淘宝上买一块mt7688的开发板,上面有很多硬件资源【wifi/以太网/i2c/spi/usb/sd卡/gpio等等】可以用go来操作,我们已经用mt7688+go开发了多款用于工业和商用的嵌入式物联网设备了。
以上所述就是小编给大家介绍的《用go语言来做嵌入式-读写铁电存储器》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Clojure软件事务存储器
- 针对亚马逊云存储器S3 BUCKET的渗透测试
- 【Logisim实验】构建立即数-随机存储器-寄存器的传送
- 网关 Spring-Cloud-Gateway 源码解析 —— 路由(1.3)之 RouteDefinitionRepository 存储器
- 想用数据库“读写分离” 请先明白“读写分离”解决什么问题
- Java 读写锁浅析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
PHP for the World Wide Web, Second Edition (Visual QuickStart Gu
Larry Ullman / Peachpit Press / 2004-02-02 / USD 29.99
So you know HTML, even JavaScript, but the idea of learning an actual programming language like PHP terrifies you? Well, stop quaking and get going with this easy task-based guide! Aimed at beginning ......一起来看看 《PHP for the World Wide Web, Second Edition (Visual QuickStart Gu》 这本书的介绍吧!