使用 Microchip SAM9X60 OTP 存储板卡的MAC地址和序列号

news2024/9/22 17:31:42

1. 介绍

     SAM9X60 处理器有部分OTP(One Time Programming) Aera 可用于存储user data,这样的话我们就可以将板卡 MAC Address和 SN 序列号写到固定的OTP User Area中。

     为什么要使用 OTP 区域存储MAC地址和序列号呢?答案是为了省钱。如果不使用OTP的话,可能要考虑采用 eeprom 等掉电非易失的存储保存这些固定信息,这样的话就多了一颗料的钱,还得占用I2C总线,PCB布线等。

     这里提一句,NXP i.MX6系列的处理器,对 OTP 区域的划分比Microchip的处理器要详细和更容易访问一些,没有那么多弯弯绕绕,感兴趣的小伙伴可以看一下i.MX6 Reference Manual.

2. MAC地址和SN 格式

假如格式如下:
在这里插入图片描述

3. SAM9X60 OTP Address

SAM9X60 处理器OTP相关的介绍。

Memory Mapping
在这里插入图片描述
查看SAM9X60 芯片手册 ‘23. OTP Memory Controller(OTPC)’章节的相关内容。

在这里插入图片描述
在这里插入图片描述
每一个Packet包含1个32-bit的Header和若干个32-bit的Payload(data)。

Payload 的 SIZE 自己可以在Header的寄存器中定义。

在这里插入图片描述
我们这里要存储1个MAC地址,1个SN序列号的话,为了方便操作和录入,这里就使用4个32bit的payload。Header地址从0x00开始,然后地址0x01 ~ 0x04分别代表payload0~payload4。
在这里插入图片描述

3.1. 写操作流程

在这里插入图片描述

OTPC_MR (0x4)写 0xFF0000   - devmem 0xEFF00004 32 0xFF0000

OTPC_CR (0x0)写 0x40

读 OTPC_ISR (0x1C)查看这个位EOR (bit8)是否是1

读 OTPC_HR (0x20)查看寄存器中的值是否有1,

读 OTPC_DR (0x24)查看寄存器中的值是否有1  (或者读 OTPC_SR (0x0C)寄存器,查看 ONEF bit9 这一位是否为1)

OTPC_MR (0x4)写 0x00000010 ,将OTPC_MR.ADDR 设置为 0,表示从0x0地址开始生成新的packet.这个操作可能触发自动 flush

OTPC_HR (0x20)写 0x301 ,表示我们要使用4个payload, packet类型是 REGULAR 普通的用户数据。

OTPC_AR (0x08)写 0x10000, 表示地址从0x0开始,并且再每次写入数据后,该地址会自动递增,就不用我们再手动增加写入的数据地址了。

OTPC_DR (0x24)写入第一个数据 0x41300001

OTPC_DR (0x24)写入第二个数据 0x00000220

OTPC_DR (0x24)写入第三个数据 0x55508000

OTPC_DR (0x24)写入第四个数据 0x0000001F

OTPC_DR (0x24)写入第五个数据 0x55508001

OTPC_DR (0x24)写入第六个数据 0x0000001F

数据写完之后,OTPC_CR (0x0)写 0x71670001 ,使能programming.

查看写操作是否结束,读 OTPC_ISR (0x1C) EOP bit0是否是1,或者读 OTPC_SR (0x0C) PGM bit0 是否是0

3.2. OTP Lock操作流程

数据写完之后进行Lock,操作如下:
在这里插入图片描述

3.3. 读操作流程

在这里插入图片描述

OTPC_MR (0x4) 寄存器中先写入 header 的地址 ,写入0x0

OTPC_CR.READ (0x0)必须设置为1,OTPC_CR这个寄存器是write-only的,仅仅写入 0x40即可,这样就可以读 user area 了。

等待 OTPC_ISR(0x1C)中 EOR(bit8) 这个位变为1 或者等待 OTPC_SR(0x0C)READ (bit6)这个位变成0,这就意味着整个packet 已经转移到临时寄存器中了

读 OTPC_HR (0x20)头寄存器,读取每一个paylaod word,paylaod word的地址必须已经写入到 OTPC_AR(0x08).DADDR 中。 OTPC_AR.DADDR的地址在读取 OTPC_DR 后会自动递增,所以在连续读取paylaod word数据时,只需要去读 OTPC_DR即可。

4. MAC Address/SN Programming and Read

4.1. Programming

编写的用于板卡 MAC&SN 录入的shell 脚本如下,仅供参考。

#!/bin/sh
 
#########################################################
### Programming MAC Address and SN into SAM9X60 OTP
###
### Author: Heat.Huang
### Date:   2022-5-7
#########################################################
 
function usage(){
    echo "Usage:"
    echo ""
    echo "Programming OTP:"
    echo "    $0 22041100001 00:60:2D:0C:84:27"
 
}
 
function prog_mac(){
    # get serial number
    SN=$1
    if [ ${#SN} -ne 11 ]; then
        echo "ERROR: The type of serial number is error."
        usage
        exit 1
    else
        SN_1=0x${SN:3:11}
        SN_2=0x00000${SN:0:3}
        echo "SN_1: $SN_1"
        echo "SN_2: $SN_2"
    fi
 
    # get mac address
    MAC_ADDR=$2
    if [ ${#MAC_ADDR} -ne 17 ]; then
        echo "ERROR:  The format of MAC adddress you program is error."
        usage
        exit 1
    else
        /sbin/ifconfig eth0 down
        /sbin/ifconfig eth0 hw ether "$MAC_ADDR"
        if [ $? -eq 0 ]; then
            echo "MAC address is valid, can be programmed OTP."
            /sbin/ifconfig eth0 up
        else
            echo "MAC address is not valid."
            /sbin/ifconfig eth0 up
            usage
            exit 1
        fi
        echo "Start programming OTP ......"
        MAC_ADDR_1=`echo $MAC_ADDR | awk '{split($0,addr,":");print addr[1]}'`
        MAC_ADDR_2=`echo $MAC_ADDR | awk '{split($0,addr,":");print addr[2]}'`
        MAC_ADDR_3=`echo $MAC_ADDR | awk '{split($0,addr,":");print addr[3]}'`
        MAC_ADDR_4=`echo $MAC_ADDR | awk '{split($0,addr,":");print addr[4]}'`
        MAC_ADDR_5=`echo $MAC_ADDR | awk '{split($0,addr,":");print addr[5]}'`
        MAC_ADDR_6=`echo $MAC_ADDR | awk '{split($0,addr,":");print addr[6]}'`
 
        HW_OCOTP_MAC0=0x${MAC_ADDR_3}${MAC_ADDR_4}${MAC_ADDR_5}${MAC_ADDR_6}
        HW_OCOTP_MAC1=0x0000${MAC_ADDR_1}${MAC_ADDR_2}
        echo "HW_OCOTP_MAC0: $HW_OCOTP_MAC0"
        echo "HW_OCOTP_MAC1: $HW_OCOTP_MAC1"
    fi 
 
    ##
    ## Steps for program OTPC
    ##
 
    ###
    ### Write Access
    ###
    # read RC register
    echo "Read PMC Clock Generator Main Oscillator Register"
    devmem 0xfffffc20
    # enable RC clock
    echo "Enable the main RC in CKGR_MOR register"
    devmem 0xfffffc20 32 0x01370829
    # read RC register again
    echo "Read PMC Clock Generator Main Oscillator Register again"
    devmem 0xfffffc20
 
    # write OTPC_MR.NPCKT to 0
    echo "write OTPC_MR.NPCKT to 0"
    devmem 0xeff00004 32 0x00000000
    # write OTPC_MR.ADDR to its maximum value
    echo "write OTPC_MR.ADDR to its maximum value"
    devmem 0xeff00004 32 0x00ff0000
    # write OTPC_CR.READ to 1 and wait for the read completion
    echo "write OTPC_CR.READ to 1 and wait for the read completion"
    devmem 0xeff00000 32 0x71670040
    sleep 1
 
    echo "check if End of Read (EOR bit8) is 1"
    devmem 0xeff0001c
    echo "check OTPC Header Register"
    devmem 0xeff00020
    echo "check OTPC Data Register if have data of one"
    devmem 0xeff00024
 
    # Write OTPC_MR.ADDR to 0 and set NPCKT
    devmem 0xeff00004 32 0x00000010
    # write the header value in OTPC_HR
    devmem 0xeff00020 32 0x00000301
    # set DADDR to 0
    devmem 0xeff00008 32 0x00010000
    # write serial number into payload0 and payload1
    devmem 0xeff00024 32 $SN_1
    devmem 0xeff00024 32 $SN_2
    # write eth0 mac address into payload2 and payload3
    devmem 0xeff00024 32 $HW_OCOTP_MAC0
    devmem 0xeff00024 32 $HW_OCOTP_MAC1
 
    # after write , enable OTPC programming
    devmem 0xeff00000 32 0x71670001
    sleep 1
    # check if programming is end
    devmem 0xeff0001c
    sleep 1
    # read the address of new generated packet
    val=`devmem 0xeff00004`
    echo "the address of new generated packet: $val"
    val=0x${val:2:4}0000
    # clear OTPC_MR.NPCKT
    devmem 0xeff00004 32 $val
 
    ###
    ### Read data from OTP to check if write ok
    ###
    devmem 0xeff00000 32 0x00000040
    devmem 0xeff0001c
    devmem 0xeff00020
    devmem 0xeff00008 32 0x00000000
    SN_1_OTP=`devmem 0xeff00024`
    echo "SN_1_OTP = $SN_1_OTP"
 
    SN_2_OTP=`devmem 0xeff00024`
    echo "SN_2_OTP = $SN_2_OTP"
 
    HW_OCOTP_MAC0_OTP=`devmem 0xeff00024`
    echo "HW_OCOTP_MAC0_OTP = $HW_OCOTP_MAC0_OTP"
    HW_OCOTP_MAC0_OTP=${HW_OCOTP_MAC0_OTP:2:9}
    # transfer HEX to DEC
    HW_OCOTP_MAC0_OTP=$((16#$HW_OCOTP_MAC0_OTP))
 
    HW_OCOTP_MAC1_OTP=`devmem 0xeff00024`
    echo "HW_OCOTP_MAC1_OTP = $HW_OCOTP_MAC1_OTP"
    HW_OCOTP_MAC1_OTP=${HW_OCOTP_MAC1_OTP:2:9}
    # transfer HEX to DEC
    HW_OCOTP_MAC1_OTP=$((16#$HW_OCOTP_MAC1_OTP))
 
    ## transfer writen value from HEX to DEC
    HW_OCOTP_MAC0=${HW_OCOTP_MAC0:2:9}
    # transfer HEX to DEC
    HW_OCOTP_MAC0=$((16#$HW_OCOTP_MAC0))
    HW_OCOTP_MAC1=${HW_OCOTP_MAC1:2:9}
    # transfer HEX to DEC
    HW_OCOTP_MAC1=$((16#$HW_OCOTP_MAC1))
 
    if [ "$SN_1_OTP" == "$SN_1" ] && [ "$SN_2_OTP" == "$SN_2" ] && [ $HW_OCOTP_MAC0_OTP -eq $HW_OCOTP_MAC0 ] && [ $HW_OCOTP_MAC1_OTP -eq $HW_OCOTP_MAC1 ]; then
        echo "Programming MAC ADDR and serial number succussful."
    else
        echo "Programming OTP FAIL."
    fi
 
    ###
    ### Lock the new generated packet
    ###
    echo "Lock the new generated packet"
    # write the address value of the header of the packet to lock in OTPC_MR.ADDR
    devmem 0xeff00004 32 $val
    # start a read by seeting OTPC_CR.READ and waiting for the read completion indicated by OTPC_ISR.EOR
    devmem 0xeff00000 32 0x00000040
    sleep 1
    # check if End of Read (EOR bit8) is 1
    devmem 0xeff0001c
    # Write 0x7167 in the OTPC_CR.KEY field and '1' in OTPC_CR.CKSGEN
    devmem 0xeff00000 32 0x71670002
    # the end of the lock operation is indicated by OTPC_ISR.EOL='1' and/or OTPC_SR.LOCK='0'
    lock_ret=`devmem 0xeff0001c`
    eol=${lock_ret:9}
    if [ $eol -eq 2 ]; then
        echo "Lock ok."
    else
        echo "Lock fail."
    fi
 
}
 
 
# Entry
if [ $# == 2 ];then
    prog_mac $@
else
    usage
    exit 1
fi
 
exit 0

4.2. Read

    又写了一个读取MAC地址和SN的shell脚本 get_Mac.sh,可以用于板子 Linux系统启动后,运行该脚本从OTP相应的Aera中读取MAC address,如果读取失败会随机生成一个MAC地址,然后通过ifconfig eth0 hw ether 命令配置网卡的IP。脚本还会从OTP读取序列号,并写入到文件 /images/data/SN 中。

get_Mac.sh 脚本源码如下。

#!/bin/sh
 
 
 
## add by heat
## Steps for set MAC address and get SN from OTPC
##
 
# read RC register
echo "read RC register"
/sbin/devmem 0xfffffc20
# enable RC clock
echo "enable the main RC in CKGR_MOR register"
/sbin/devmem 0xfffffc20 32 0x01370829
# read RC register again
echo "read RC register again"
/sbin/devmem 0xfffffc20
 
# write the address of header into OTPC_MR
/sbin/devmem 0xeff00004 32 0x00000000
# OTPC_CR.READ set to 1 to enable user area
/sbin/devmem 0xeff00000 32 0x00000040
# check OTPC_ISR.EOR if 0 to wait for start reading
/sbin/devmem 0xeff0001c
sleep 1
# read the header of the packet
/sbin/devmem 0xeff00020
# start address of payload
/sbin/devmem 0xeff00008 32 0x00000000
 
# start reading value from OTP
SN_TAIL=`/sbin/devmem 0xeff00024`
SN_HEAD=`/sbin/devmem 0xeff00024`
MAC0_TAIL=`/sbin/devmem 0xeff00024`
MAC0_HEAD=`/sbin/devmem 0xeff00024`
echo "SN_TAIL=$SN_TAIL"
echo "SN_HEAD=$SN_HEAD"
echo "MAC0_TAIL=$MAC0_TAIL"
echo "MAC0_HEAD=$MAC0_HEAD"
 
if [ $MAC0_TAIL == "0x00000000" ] && [ $MAC0_HEAD == "0x00000000" ]; then
    echo "Cannot get correct data from OTP address 0x0, try to read from OTP address 0x29"
    # write the address of header into OTPC_MR
    /sbin/devmem 0xeff00004 32 0x00290000
    # OTPC_CR.READ set to 1 to enable user area
    /sbin/devmem 0xeff00000 32 0x00000040
    # check OTPC_ISR.EOR if 0 to wait for start reading
    /sbin/devmem 0xeff0001c
    sleep 1
    # read the header of the packet
    /sbin/devmem 0xeff00020
    # start address of payload
    /sbin/devmem 0xeff00008 32 0x00000000
 
    # start reading value from OTP
    SN_TAIL=`/sbin/devmem 0xeff00024`
    SN_HEAD=`/sbin/devmem 0xeff00024`
    MAC0_TAIL=`/sbin/devmem 0xeff00024`
    MAC0_HEAD=`/sbin/devmem 0xeff00024`
    echo "SN_TAIL=$SN_TAIL"
    echo "SN_HEAD=$SN_HEAD"
    echo "MAC0_TAIL=$MAC0_TAIL"
    echo "MAC0_HEAD=$MAC0_HEAD"
fi
 
NONE_MAC0=false
NONE_MAC1=false
## analyse eth0 MAC address
if [ $MAC0_TAIL == "0x00000000" ] && [ $MAC0_HEAD == "0x00000000" ]; then
    echo "Cannot get correct MAC address form OTP"
    echo "Use Random MAC Address"
    MAC0_ADDR_RAND=`echo $RANDOM|md5sum`
    MAC0_ADDR_1=00
    MAC0_ADDR_2=1F
    MAC0_ADDR_3=55
    MAC0_ADDR_4=`echo $MAC0_ADDR_RAND|cut -c 1-2`
    MAC0_ADDR_5=`echo $MAC0_ADDR_RAND|cut -c 3-4`
    MAC0_ADDR_6=`echo $MAC0_ADDR_RAND|cut -c 5-6`
else
    case ${#MAC0_TAIL} in
        2)
        MAC0_OPT_SECTOR_TAIL="0x00000000"
        ;;
        3)
        MAC0_OPT_SECTOR_TAIL="0x0000000"`echo $MAC0_TAIL | cut -b 3`
        ;;
        4)
        MAC0_OPT_SECTOR_TAIL="0x000000"`echo $MAC0_TAIL | cut -b 3-4`
        ;;
        5)
        MAC0_OPT_SECTOR_TAIL="0x00000"`echo $MAC0_TAIL | cut -b 3-5`
        ;;
        6)
        MAC0_OPT_SECTOR_TAIL="0x0000"`echo $MAC0_TAIL | cut -b 3-6`
        ;;
        7)
        MAC0_OPT_SECTOR_TAIL="0x000"`echo $MAC0_TAIL | cut -b 3-7`
        ;;
        8)
        MAC0_OPT_SECTOR_TAIL="0x00"`echo $MAC0_TAIL | cut -b 3-8`
        ;;
        9)
        MAC0_OPT_SECTOR_TAIL="0x0"`echo $MAC0_TAIL | cut -b 3-9`
        ;;
        10)
        MAC0_OPT_SECTOR_TAIL=$MAC0_TAIL
        ;;
        *)
        NONE_MAC0=true
        ;;
    esac
    case ${#MAC0_HEAD} in
        2)
        MAC0_OPT_SECTOR_HEAD="0x0000"
        ;;
        3)
        MAC0_OPT_SECTOR_HEAD="0x000"`echo $MAC0_HEAD | cut -b 3`
        ;;
        4)
        MAC0_OPT_SECTOR_HEAD="0x00"`echo $MAC0_HEAD | cut -b 3-4`
        ;;
        5)
        MAC0_OPT_SECTOR_HEAD="0x0"`echo $MAC0_HEAD | cut -b 3-5`
        ;;
        6)
        MAC0_OPT_SECTOR_HEAD="0x0000"`echo $MAC0_HEAD | cut -b 3-6`
        ;;
        7)
        MAC0_OPT_SECTOR_HEAD="0x000"`echo $MAC0_HEAD | cut -b 3-7`
        ;;
        8)
        MAC0_OPT_SECTOR_HEAD="0x00"`echo $MAC0_HEAD | cut -b 3-8`
        ;;
        9)
        MAC0_OPT_SECTOR_HEAD="0x0"`echo $MAC0_HEAD | cut -b 3-9`
        ;;
        10)
        MAC0_OPT_SECTOR_HEAD=$MAC0_HEAD
        ;;
        *)
        NONE_MAC0=true
        ;;
    esac
 
    MAC0_ADDR_1=`echo ${MAC0_OPT_SECTOR_HEAD} | cut -b 7-8`
    MAC0_ADDR_2=`echo ${MAC0_OPT_SECTOR_HEAD} | cut -b 9-10`
    MAC0_ADDR_3=`echo ${MAC0_OPT_SECTOR_TAIL} | cut -b 3-4`
    MAC0_ADDR_4=`echo ${MAC0_OPT_SECTOR_TAIL} | cut -b 5-6`
    MAC0_ADDR_5=`echo ${MAC0_OPT_SECTOR_TAIL} | cut -b 7-8`
    MAC0_ADDR_6=`echo ${MAC0_OPT_SECTOR_TAIL} | cut -b 9-10`
 
    echo "Got correct MAC address form OTP"
 
fi
 
## set eth0 MAC address
echo "eth0 MAC: $MAC0_ADDR_1:$MAC0_ADDR_2:$MAC0_ADDR_3:$MAC0_ADDR_4:$MAC0_ADDR_5:$MAC0_ADDR_6"
/sbin/ifconfig eth0 down
/sbin/ifconfig eth0 hw ether "$MAC0_ADDR_1:$MAC0_ADDR_2:$MAC0_ADDR_3:$MAC0_ADDR_4:$MAC0_ADDR_5:$MAC0_ADDR_6"
/sbin/ifconfig eth0 up
 
## get SN from OTP
if [ $SN_TAIL == "0x00000000" ] && [ $SN_HEAD == "0x00000000" ]; then
    echo "Cannot get correct SN form OTP"
else
    echo "Got correct SN form OTP"
    SN_1=`printf "%08x" ${SN_TAIL}`
    SN_2=`printf "%03x" ${SN_HEAD}`
    echo "SN: ${SN_2}${SN_1}"
    echo "${SN_2}${SN_1}" > /images/data/SN
fi

没有做什么特别的操作,就是操作一堆寄存器。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1013403.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++内存池(1)理论基础及简单实现

一、内存池原理 1、我们先用生活中的例子来解释什么是内存池: (1)每个月月底钱花完时,或者急需要用钱时,你就打电话给你父母要钱,然后父母把钱通过微信或支付宝转给你。这种方式,每次要用钱…

如何在谷某地球飞行模拟中导入简单飞机开发的飞机模型

如何在谷某地球飞行模拟中导入简单飞机开发的飞机模型 简飞的飞友们!我并没有弃坑,只不过我不是你们想象的那样设计飞机。我之前写过一篇图文讲解如何在谷某地球里规划飞行航线: 手把手教你驾驶西锐SR-22小飞机在美国大峡谷中穿行https://b…

Docker 恶意挖矿镜像应急实例

01、概述 当网络流量监控发现某台运行多个docker容器的主机主动连接到一个疑似挖矿矿池的地址时,需要快速响应和排查,以阻止进一步的损害。 面对docker容器的场景下,如何快速分析和识别恶意挖矿容器?本文将分享一种应急响应思路,…

【基础篇】三、SpringBoot基础配置

文章目录 0、模块的复制1、配置文件格式2、yaml语法3、yaml数据读取方式4、关于封装自定义对象来读取yaml配置的思考4、多环境启动5、配置文件分类 0、模块的复制 平时要大量创建模块时,可以直接复制模块,打开project的目录: 复制粘贴&#…

LeetCode142.环形链表-II

这道题和上一道题几乎没有任何区别啊,为什么还是中等难度,我用上一道题的解法一分钟就写出来了,只不过返回的不是true和false而是节点,以下是我的代码: public class Solution {public ListNode detectCycle(ListNode…

接口自动化测试推荐用什么框架?

在推荐接口自动化测试框架时,需要考虑多个因素,包括项目需求、技术栈、团队经验和个人偏好。 以下是几个常用的接口自动化测试框架供你参考: Postman: Postman是一个功能强大且易于上手的接口测试工具,它提供了许多…

卡尔曼滤波应用在数据处理方面的应用

卡尔曼滤波应用到交通领域 滤波器介绍核心思想核心公式一维卡尔曼滤波器示例导入所需的库 滤波器介绍 卡尔曼滤波器是一种用于估计系统状态的数学方法,它以卡尔曼核心思想为基础,广泛应用于估计动态系统的状态和滤除测量中的噪声。以下是卡尔曼滤波器的核…

学Python的漫画漫步进阶 -- 第十步

学Python的漫画漫步进阶 -- 第十步 十、异常处理10.1 第一个异常——除零异常10.2 捕获异常10.2.1 try-except语句10.2.2 多个except代码块10.2.3 多重异常捕获10.2.4 try-except语句嵌套 10.3 使用finally代码块释放资源10.4 自定义异常类10.5 动动手——手动引发异常10.6 练一…

安卓可视大屏寻呼台 兼容标准sip协议

SV-A32i 安卓可视大屏寻呼台 兼容标准sip协议 A32i 是专门针对行业用户需求研发的一款可视大屏寻呼台产品,配备鹅颈麦克风,支持高清免提通话。基于 Android 9.0 系统,可支持第三方Android 应用安装使用,界面使用便捷。采用 10.1 英…

大模型与数据库:AI 时代的双向助推力

随着 AIGC 的时代到来,以 GPT 为首的大型语言模型(Large Language Model,LLM)已经成为当今人工智能领域最热门的话题之一。这些强大的模型不仅在内容创意生成、语言翻译和代码辅助等任务中表现出色,还对数据库的发展带…

DatenLord前沿技术分享 NO.35

达坦科技专注于打造新一代开源跨云存储平台DatenLord,通过软硬件深度融合的方式打通云云壁垒,致力于解决多云架构、多数据中心场景下异构存储、数据统一管理需求等问题,以满足不同行业客户对海量数据跨云、跨数据中心高性能访问的需求。在本周…

通过机器视觉对硬盘容器上盖的字符进行视觉识别,判断是否混料

 客户的需求  检测内容 硬盘容器上盖字符识别,以判断是否有混料。  检测要求 利用硬盘容器上盖表面字符,来判断是否有混料的情况发生,先识别全部字符。  视觉可行性分析 对贵司的样品进行了光学实验,并进行…

【操作系统】进程,线程和协程的哪些事儿

进程,线程和协程的哪些事儿 进程什么是进程?进程的状态进程的控制结构 线程为什么使用线程?什么是线程?线程与进程的比较线程的实现用户级线程内核级线程轻量级进程 协程协程是什么?协程的优势 区别进程与线程的区别协程与线程的…

【Spatial-Temporal Action Localization(三)】论文阅读2018年

文章目录 1. AVA: A Video Dataset of Spatio-temporally Localized Atomic Visual Actions 时空局部原子视觉动作的视频数据集摘要和结论模型框架思考不足之处时间信息对于识别 AVA 类别有多重要?定位与识别相比有何挑战性?哪些类别具有挑战性&#xff…

Python console cmd命令乱码(无论是os还是subprocess)

给我整无语了,花了一个多小时,根本没找到需要的答案。 网上全是改这样的 五花八门都有,我全部尝试并且还就再排列组合修改,累的。 在下文找到答案,直接os.system(chcp 65001),问题解决!引用文献…

IEC 61850扫盲

目录 1 简介 2 主要特点 2.1 信息分层 2.2 信息模型与通信协议独立 2.3 数据自描述 2.4 面向对象数据统一建模 2.5 带确认服务 2.6 不带确认的服务 2.7 VMD(虚拟制造设备) 2.8 GOOSE(Generic Object Oriented Substation Event&…

LeetCode(力扣)435. 无重叠区间Python

LeetCode435. 无重叠区间 题目链接代码 题目链接 https://leetcode.cn/problems/non-overlapping-intervals/ 代码 class Solution:def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:if not intervals:return 0intervals.sort(keylambda x: x[0])co…

ajax day4

1、promise链式调用 /*** 目标:把回调函数嵌套代码,改成Promise链式调用结构* 需求:获取默认第一个省,第一个市,第一个地区并展示在下拉菜单中*/let pname axios({url: http://hmajax.itheima.net/api/province,}).t…

徐亦达机器学习:Kalman Filter 卡尔曼滤波笔记 (一)

P ( x t P(x_t P(xt​| x t − 1 ) x_{t-1}) xt−1​) P ( y t P(y_t P(yt​| x t ) x_t) xt​) P ( x 1 ) P(x_1) P(x1​)Discrete State DM A X t − 1 , X t A_{X_{t-1},X_t} AXt−1​,Xt​​Any π \pi πLinear Gassian Kalman DM N ( A X t − 1 B , Q ) N(AX_{t-1}B,Q)…

open-interpreter +GTX1080+wxbot+codellama

https://github.com/KillianLucas/open-interpreter/ Open Interpreter(开放解释器) 可以让大语言模型(LLMs)在本地运行代码(比如 Python、JavaScript、Shell 等)。安装后,在终端上运行 $ inte…