关于FEC驱动_FEC伍丰

关于FEC驱动_FEC伍丰转载说是网络,其实是网卡驱动。而且是针对于FREESCALE芯片的FEC端的驱动,我不知道别的芯片厂商的FEC模块是怎么样的,但就我接触过的几款FREESCALE的芯片来看,比如基于POWERPC的860T和ARM系列的MX27等,他们的FEC有一个明显的特点就是都是由BD和一个DMA缓冲组成,而这个DMA是专用的,也就是只是给FEC使用,区别于芯片内的DMAC模块。我们先来从fec.c这个与

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

转载

说是网络,其实是网卡驱动。而且是针对于FREESCALE芯片的FEC端的驱动,我不知道别的芯片厂商的FEC模块是怎么样的,
但就我接触过的几款FREESCALE的芯片来看,比如基于POWERPC的860T和ARM系列的MX27等,他们的FEC有一个明显的特点就是
都是由BD和一个DMA缓冲组成,而这个DMA是专用的,也就是只是给FEC使用,区别于芯片内的DMAC模块。我们先来从fec.c这
个与硬件直接相关的看起:
首先找到module_init(fec_enet_module_init);这里fec_enet_module_init为入口点
fec_enet_module_init()
    首先调用fec_arch_init,它调用gpio_fec_active设置GPIO为FEC模式,然后如果有电源管理的话,就调用
mxc_fec_power_on开启电源。接着调用clk_get,clk_enable, clk_put设置FEC的CLOCK,这里退出fec_arch_init函数,接
着循环FEC_MAX_PORTS次,也就是有几个FEC就循环几次,在这里我们只有一个FEC,所以这个循环不用管。接下来因为我们
用的是以太网,所以调用dev = alloc_etherdev(sizeof(struct fec_enet_private));申请一个以太网设备描述,其中
struct fec_enet_private是用来描述FEC专有的数据结构。如下:
/* The FEC buffer descriptors track the ring buffers. The rx_bd_base and
 * tx_bd_base always point to the base of the buffer descriptors. The
 * cur_rx and cur_tx point to the currently available buffer.
 * The dirty_tx tracks the current buffer that is being sent by the
 * controller. The cur_tx and dirty_tx are equal under both completely
 * empty and completely full conditions. The empty/ready indicator in
 * the buffer descriptor determines the actual condition.
 */
struct fec_enet_private {

    /* Hardware registers of the FEC device */
    volatile fec_t    *hwp;
    /* The saved address of a sent-in-place packet/buffer, for skfree(). */
    unsigned char *tx_bounce[TX_RING_SIZE];
    struct    sk_buff* tx_skbuff[TX_RING_SIZE];
    struct sk_buff* rx_skbuff[RX_RING_SIZE];
    ushort    skb_cur;
    ushort    skb_dirty;
    /* CPM dual port RAM relative addresses.
    */
    void * cbd_mem_base; /* save the virtual base address of rx&tx buffer descripter */
    cbd_t    *rx_bd_base;        /* Address of Rx and Tx buffers. */
    cbd_t    *tx_bd_base;
    cbd_t    *cur_rx, *cur_tx;        /* The next free ring entry */
    cbd_t    *dirty_tx;    /* The ring entries to be free()ed. */
    struct    net_device_stats stats;
    uint    tx_full;
    spinlock_t lock;
    uint    phy_id;
    uint    phy_id_done;
    uint    phy_status;
    uint    phy_speed;
    phy_info_t const    *phy;
    struct work_struct phy_task;
    uint    sequence_done;
    uint    mii_phy_task_queued;
    uint    phy_addr;
    int    index;
    int    opened;
    int    link;
    int    old_link;
    int    full_duplex;
    struct clk *clk;
};
    调用完这个函数后我们就有eth0这人设备了,其中一些结构的初始化是在这个函数里的一个回调ether_setup里设
置的,在这里我也把它帖出来吧。
/**
 * ether_setup – setup Ethernet network device
 * @dev: network device
 * Fill in the fields of the device structure with Ethernet-generic values.
 */
void ether_setup(struct net_device *dev)
{

    dev->change_mtu        = eth_change_mtu;
    dev->hard_header    = eth_header;
    dev->rebuild_header     = eth_rebuild_header;
    dev->set_mac_address     = eth_mac_addr;
    dev->hard_header_cache    = eth_header_cache;
    dev->header_cache_update= eth_header_cache_update;
    dev->hard_header_parse    = eth_header_parse;
    dev->type        = ARPHRD_ETHER;
    dev->hard_header_len     = ETH_HLEN;
    dev->mtu        = ETH_DATA_LEN;
    dev->addr_len        = ETH_ALEN;
    dev->tx_queue_len    = 1000;    /* Ethernet wants good queues */    
    dev->flags        = IFF_BROADCAST|IFF_MULTICAST;
    
    memset(dev->broadcast, 0xFF, ETH_ALEN);
}
    alloc_etherdev完了之后,调用fec_enet_init函数,这里才是真正芯片级的代码:
    fec_enet_init()
        上锁spin_lock_init(&(fep->lock)),调用__get_free_page申请一页的内存,这个返回的地址为虚拟地
址,然后将这个地址值赋给fep->cbc_mem_base,然后将fecp和fep->hwp指向FEC硬件寄存器,fecp->fec_ecntrl = 1,复位
FEC模块,等待10us后调用fec_get_mac从FLASH中读取MAC地址,调用cbd_base = (cbd_t *)fec_map_uncache(mem_addr,
PAGE_SIZE);将刚才申请的一页进行映射(mem_addr不是虚拟地址么?为什么这里还要映射??)作为BD的初始地址并将FEC
的rx_bd_base指向该地址,同时将tx_bd_base指向RX_RING_SIZE之后的地址,这个RX_RING_SIZE定义如下:
            /* The number of Tx and Rx buffers. These are allocated from the page
             * pool. The code may assume these are power of two, so it it best
             * to keep them that size.
             * We don’t need to allocate pages for the transmitter. We just use
             * the skbuffer directly.
             */
            #define FEC_ENET_RX_PAGES    8
            #define FEC_ENET_RX_FRSIZE    2048
            #define FEC_ENET_RX_FRPPG    (PAGE_SIZE / FEC_ENET_RX_FRSIZE)
            #define RX_RING_SIZE        (FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES)
            #define FEC_ENET_TX_FRSIZE    2048
            #define FEC_ENET_TX_FRPPG    (PAGE_SIZE / FEC_ENET_TX_FRSIZE)
            #define TX_RING_SIZE        16    /* Must be power of two */
            #define TX_RING_MOD_MASK    15    /* for this to work */
            
            #if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE)
            #error “FEC: descriptor ring size constants too large”
            #endif
        其中PAGE_SIZE是为4096,所以这个RX_RING_SIZE的值也为16,意思好像是说有16个FEC_ENET_RX_FRSIZE?
接下来循环初始化RX_RING_SIZE个frame,循环中,调用dev_alloc_skb(FEC_ENET_RX_FRSIZE);初始化skb,并将赋给fep-
>rx_skbuff[i],接下来将pskb->data进行对齐,这个对齐要求是通过
            #define FEC_ADDR_ALIGNMENT(x) ((unsigned char *)(((unsigned long )(x) +
(FEC_ALIGNMENT)) & (~FEC_ALIGNMENT)))
        来实现的,也就是说这个对齐要求是由datasheet里的FEC模块规定的。注意的是最后将这个地址进行物理
地址变换后赋给cbd_bufaddr的,即cbd_bufaddr = __pa(pskb->data);然后将BD的cbd_sc状态描述置为BD_ENET_RX_EMPTY空
闲。
        接下来将最后一个BD的cbd_sc状态描述置上BD_SC_WRAP标志,这估计是datasheet里规定的吧??接下来
初始化发送BD,这里看不懂,先帖上来先
            bdp = fep->tx_bd_base;
            for (i=0, j=FEC_ENET_TX_FRPPG; i<TX_RING_SIZE; i++) {

                if (j >= FEC_ENET_TX_FRPPG) {

                    mem_addr = __get_free_page(GFP_KERNEL);
                    j = 1;
                } else {

                    mem_addr += FEC_ENET_TX_FRSIZE;
                    j++;
                }
                fep->tx_bounce[i] = (unsigned char *) mem_addr;
        
                /* Initialize the BD for every fragment in the page.
                */
                bdp->cbd_sc = 0;
                bdp->cbd_bufaddr = 0;
                bdp++;
            }
        
            /* Set the last buffer to wrap.
            */
            bdp–;
            bdp->cbd_sc |= BD_SC_WRAP;
            
            接着调用
                /* Set receive and transmit descriptor base.
                */
                fecp->fec_r_des_start = __pa((uint)(fep->cbd_mem_base));
                fecp->fec_x_des_start = __pa((uint)(fep->cbd_mem_base + RX_RING_SIZE*sizeof
(cbd_t)));
            将发送同接收地址值写入寄存器中。下面调用fec_request_intrs申请两个中断,一个为FEC的中
断static irqreturn_t fec_enet_interrupt(int irq, void * dev_id),用作发送接收、MII及出错等中断使用,另一个为
PHY端的中断static irqreturn_t mii_link_interrupt(int irq, void * dev_id),用作PHY芯片检测LINK DOWN或AUTO-
NEGO DONE中断,下面
                /* Clear and enable interrupts */
                fecp->fec_ievent = FEC_ENET_MASK;
                fecp->fec_imask = FEC_ENET_TXF | FEC_ENET_TXB | FEC_ENET_RXF | FEC_ENET_RXB
| FEC_ENET_MII;
            
                fecp->fec_hash_table_high = 0;
                fecp->fec_hash_table_low = 0;
                fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
                fecp->fec_ecntrl = 2;
                fecp->fec_r_des_active = 0x01000000;
            都是设置硬件寄存器,接着设置
                /* The FEC Ethernet specific entries in the device structure. */
                dev->open = fec_enet_open;
                dev->hard_start_xmit = fec_enet_start_xmit;
                dev->tx_timeout = fec_timeout;
                dev->watchdog_timeo = TX_TIMEOUT;
                dev->stop = fec_enet_close;
                dev->get_stats = fec_enet_get_stats;
                dev->set_multicast_list = set_multicast_list;
            这里是重载DEV的一些实现,当我们敲入ifconfig eth0 up的时候就会调用fec_enet_open。这里
要说明的是fec_timeout这个函数,这个函数运行在SOFTIRQ上下文,被当作网络的watchdog超时函数。而
set_multicast_list函数还不清楚是用来做什么的????接下来
                for (i=0; i<NMII-1; i++)
                    mii_cmds[i].mii_next = &mii_cmds[i+1];
                mii_free = mii_cmds;
            这是初始化mii的命令队列,这个其实是一个静态数组,然后通过内部的链表变量将这个数组链
起来。mii_free是一个链表头,指向第一个可用的mii_cmd元素。接着调用fec_set_mii初始化MII的速度:
                static void __inline__ fec_set_mii(struct net_device *dev, struct
fec_enet_private *fep)
                {

                    u32 rate;
                    struct clk *clk;
                    volatile fec_t *fecp;
                    fecp = fep->hwp;
                    fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
                    fecp->fec_x_cntrl = 0x00;
                
                     /*
                     * Set MII speed to 2.5 MHz
                     */
                    clk = clk_get(NULL, “fec_clk”);
                    rate = clk_get_rate(clk);
                    clk_put(clk);
                
                    fep->phy_speed =
                        ((((rate / 2 + 4999999) / 2500000) / 2) & 0x3F) << 1;
                    fecp->fec_mii_speed = fep->phy_speed;
                    fec_restart(dev, 0);
                }
            设置完clk后,调用fec_restart重新设置FEC的参数:
                    /* This function is called to start or restart the FEC during a link
                     * change. This only happens when switching between half and full
                     * duplex.
                     */
                    static void
                    fec_restart(struct net_device *dev, int duplex)
                    {

                        struct fec_enet_private *fep;
                        volatile cbd_t *bdp;
                        volatile fec_t *fecp;
                        int i;
                    
                        OUTDEB(“entry!!!!!\n”);
                        fep = netdev_priv(dev);
                        fecp = fep->hwp;
                    
                        /* Whack a reset. We should wait for this.
                        */
                        fecp->fec_ecntrl = 1;
                        udelay(10);
                    
                         /* Enable interrupts we wish to service.
                          */
                        fecp->fec_imask = FEC_ENET_TXF | FEC_ENET_TXB | FEC_ENET_RXF
| FEC_ENET_RXB | FEC_ENET_MII;
                    
                        /* Clear any outstanding interrupt.
                         *
                         */
                        fecp->fec_ievent = FEC_ENET_MASK;
                    #if 0/*modified by Zenith @ 2010.1.21 for int bug*/
                        fec_enable_phy_intr();
                    #endif
                        /* Set station address.
                        */
                        fec_set_mac_address(dev);
                    
                        /* Reset all multicast.
                        */
                        fecp->fec_hash_table_high = 0;
                        fecp->fec_hash_table_low = 0;
                    
                        /* Set maximum receive buffer size.
                        */
                        fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
                    
                        fec_localhw_setup();
                    
                        /* Set receive and transmit descriptor base.
                        */
                         fecp->fec_r_des_start = __pa((uint)(fep->cbd_mem_base));
                        fecp->fec_x_des_start = __pa((uint)(fep->cbd_mem_base +
RX_RING_SIZE*sizeof(cbd_t)));
                        
                        fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
                        fep->cur_rx = fep->rx_bd_base;
                    
                        /* Reset SKB transmit buffers.
                        */
                        fep->skb_cur = fep->skb_dirty = 0;
                        for (i=0; i<=TX_RING_MOD_MASK; i++) {

                            if (fep->tx_skbuff[i] != NULL) {

                                dev_kfree_skb_any(fep->tx_skbuff[i]);
                                fep->tx_skbuff[i] = NULL;
                            }
                        }
                    
                        /* Initialize the receive buffer descriptors.
                        */
                        bdp = fep->rx_bd_base;
                        for (i=0; i<RX_RING_SIZE; i++) {

                    
                            /* Initialize the BD for every fragment in the page.
                            */
                            bdp->cbd_sc = BD_ENET_RX_EMPTY;
                            bdp++;
                        }
                    
                        /* Set the last buffer to wrap.
                        */
                        bdp–;
                        bdp->cbd_sc |= BD_SC_WRAP;
                    
                        /* …and the same for transmmit.
                        */
                        bdp = fep->tx_bd_base;
                        for (i=0; i<TX_RING_SIZE; i++) {

                    
                            /* Initialize the BD for every fragment in the page.
                            */
                            bdp->cbd_sc = 0;
                            bdp->cbd_bufaddr = 0;
                            bdp++;
                        }
                    
                        /* Set the last buffer to wrap.
                        */
                        bdp–;
                        bdp->cbd_sc |= BD_SC_WRAP;
                    
                        /* Enable MII mode.
                        */
                        if (duplex) {

                            fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;/* MII
enable */
                            fecp->fec_x_cntrl = 0x04;         /* FD
enable */
                        }
                        else {

                            /* MII enable|No Rcv on Xmit */
                            fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x06;
                            fecp->fec_x_cntrl = 0x00;
                        }
                        fep->full_duplex = duplex;
                    
                        /* Set MII speed.
                        */
                        fecp->fec_mii_speed = fep->phy_speed;
                    
                        /* And last, enable the transmit and receive processing.
                        */
                        fecp->fec_ecntrl = 2;
                        fecp->fec_r_des_active = 0x01000000;
                        
                        netif_start_queue(dev);
                    }
            这里的其实是一个内联函数:
                static inline void netif_start_queue(struct net_device *dev)
                {

                    clear_bit(__LINK_STATE_XOFF, &dev->state);
                }
            它清除state中的XOFF位。
        下面我们继续回到fec_enet_init函数中:
            /* Queue up command to detect the PHY and initialize the
             * remainder of the interface.
             */
            fep->phy_id_done = 0;
            fep->phy_addr = 0;
            mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy);
        这里是将命令mk_mii_read(MII_REG_PHYIR1)插入mii的命令队列,并设置回调函数mii_discover_phy。
    end fec_enet_init()
    
end fec_enet_module_init()
我们来看一下mii_queue的实现:
static int
mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_device *))
{

    struct fec_enet_private *fep;
    unsigned long    flags;
    mii_list_t    *mip;
    int        retval;
    /* Add PHY address to register command.
    */
    fep = netdev_priv(dev);
    regval |= fep->phy_addr << 23;
    retval = 0;
    spin_lock_irqsave(&fep->lock,flags);
    if ((mip = mii_free) != NULL) {

        mii_free = mip->mii_next;
        mip->mii_regval = regval;
        mip->mii_func = func;
        mip->mii_next = NULL;
        if (mii_head) {

            mii_tail->mii_next = mip;
            mii_tail = mip;
        }
        else {

            mii_head = mii_tail = mip;
            fep->hwp->fec_mii_data = regval;
        }
    }
    else {

        retval = 1;
    }
    spin_unlock_irqrestore(&fep->lock,flags);
    return(retval);
}
可以看到,它先是读取FEC硬件寄存器phy_addr的低八位,将它放入变量regval中,这里应该是取PHY的地址,然后先看下
mii_free队列中有无元素,也即是判断有无可用的MII命令队列,如果有,则把寄存器的值(即是要读写PHY的哪个寄存器)
及回调函数放入队列中,再判断mii_head有无元素,如果无的话就将mii_head指向当前这个元素,如果有的话,更新
mii_tail指向当前元素(mii_tail始终指向最后一个命令元素),所以当我们向MII命令队列插入第一个元素的时候,它就
直接读写PHY的那个寄存器(fep->hwp->fec_mii_data = regval;)。而我们前面FEC的MII初始化的时候已经置了MII的中断
,所以这里往fep->hwp->fec_mii_data寄存器写数据完后便会产生一个FEC中断,这个中断由fec_enet_interrupt函数里调
用fec_enet_mii来处理。
我们再来看下fec_enet_mii的实现:
/* called from interrupt context */
static void
fec_enet_mii(struct net_device *dev)
{

    struct    fec_enet_private *fep;
    volatile fec_t    *ep;
    mii_list_t    *mip;
    uint        mii_reg;
    fep = netdev_priv(dev);
    ep = fep->hwp;
    mii_reg = ep->fec_mii_data;
    spin_lock(&fep->lock);
    if ((mip = mii_head) == NULL) {

        printk(“MII and no head!\n”);
        goto unlock;
    }
    if (mip->mii_func != NULL)
        (*(mip->mii_func))(mii_reg, dev);
    mii_head = mip->mii_next;
    mip->mii_next = mii_free;
    mii_free = mip;
    if ((mip = mii_head) != NULL)
        ep->fec_mii_data = mip->mii_regval;
unlock:
    spin_unlock(&fep->lock);
}
可以看到,函数首先是读取FEC的硬件寄存器fec_mii_data,这里的值应该是PHY芯片通过MII接口返回上次要求读的寄存器
的值,然后如果有mip->mii_func的话就回调这个函数,接着移动mii_head和mii_free队列,最后再写入下一个要读(写)
的PHY的寄存器。
所以当我们在初始化函数中调用mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy);将mii_discover_phy
插入命令队列时,它先将要读的寄存器MII_REG_PHYIR1通过宏mk_mii_read转换成MII寄存器的格式,然后写入fec_mii_data
寄存器,表示我想读取PHY芯片的MII_REG_PHYIR1寄存器的值,而读寄存器写完后,FEC的MII模块会产生一个中断表示说这
个PHY寄存器的读已经完成,然后中断处理函数fec_enet_mii中,会读取PHY返回的刚才我想要读取的寄存器的值给
fec_mii_data寄存器,后来再调用刚才插入的那个mii_discover_phy函数,mii_discover_phy函数就会根据这个返回的ID来
判断是哪个厂家的PHY芯片。这里将mii_discover_phy再帖出来:
/* Scan all of the MII PHY addresses looking for someone to respond
 * with a valid ID. This usually happens quickly.
 */
static void
mii_discover_phy(uint mii_reg, struct net_device *dev)
{

    struct fec_enet_private *fep;
    volatile fec_t *fecp;
    uint phytype;
    fep = netdev_priv(dev);
    fecp = fep->hwp;
    if (fep->phy_addr < 32) {

        if ((phytype = (mii_reg & 0xffff)) != 0xffff && phytype != 0) {

            /* Got first part of ID, now get remainder.
            */
            fep->phy_id = phytype << 16;
            mii_queue(dev, mk_mii_read(MII_REG_PHYIR2),
                            mii_discover_phy3);
        }
        else {

            fep->phy_addr++;
            mii_queue(dev, mk_mii_read(MII_REG_PHYIR1),
                            mii_discover_phy);
        }
    } else {

        printk(“FEC: No PHY device found.\n”);
        /* Disable external MII interface */
        fecp->fec_mii_speed = fep->phy_speed = 0;
        fec_disable_phy_intr();
    }
}
至于判断fep->phy_addr < 32与否,这个是说一个FEC可以接多个PHY,每个PHY有一个地址,用5个BIT来表示,这里是从
0~31去自加,然后查询对应的PHY地址上是否有PHY设备。
初始化过程中fec_enet_init调用完了之后,dev这个变量已经设置得差不多了,接下来是调用register_netdev(dev) 来注
册一个网络设备,后面fec_device[i] = dev;将这个DEV放入FEC的设备表中。到此,module_init完成。。。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/169594.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • MTCNN工作原理「建议收藏」

    MTCNN工作原理「建议收藏」MTCNN工作原理MTCNN是什么MTCNN,Multi-taskconvolutionalneuralnetwork(多任务卷积神经网络),将人脸区域检测与人脸关键点检测放在了一起,基于cascade框架。总体可分为PNet、RNet、和ONet三层网络结构,MTCNN实现流程构建图像金字塔首先讲图像进行不同尺度的变换,构建图像金字塔,以适应不同大小的人脸的进行检测。…

  • 你要偷偷学python(所有人都能学的数据分析课)

    标题无意冒犯,就是觉得这个广告挺好玩的上面这张思维导图喜欢就拿走,反正我也学不了这么多文章目录前言欢迎来到我们的圈子并发与串行前言前期回顾:我要偷偷学Python(第十二天)第十二篇的项目还在持续更新中,哎,日理万机虽然谈不上,但是也是手忙脚乱。这不,自动表单生成是写完了,但是学校网络实在是受不了啊,2G,测试不了,就只能一直搁置在那边了。明天就可以去测试了,明天出学校去逛逛。今天的内容,可能很多小伙伴会没有听过,今天要讲多线程的概念,以及协程的使用。后面看看能不能讲一下scrapy框架..

  • c#窗体添加背景音乐_eclipse怎么添加背景音乐

    c#窗体添加背景音乐_eclipse怎么添加背景音乐一.在项目中新建一个文件夹,然后将音乐文件导入:二.添加音乐代码如下:usingSystem.Media;//在命名空间中添加stringegm=”../../music/3.wav”;//定义变量来存储音频路径SoundPlayerbgm=newSoundPlayer(egm);//控制声音播放bgm.Play();//开始播放音乐bgm.Stop();//停……

  • 医学图形图像处理(医学影像和医学图像处理)

    文章目录1图像和数字图像1图像和数字图像  数字图像:被定义为一个二维函数,f(x,y),其中x,y代表空间坐标,f代表点(x,y)处的强度或灰度级。和普通的笛卡尔坐标系有区别,在计算机中坐标系左上角为原点:  图像数字化:图像进入计算机后,对图像进行数字化(映射)。数字图像三要素:  (1)像素:大小决定了图像存储、显示的清晰度;  (2)灰度值:通常为0-255,因为在计算机中通常用一个字节来表示一个像素,即28。  (3)坐标  图像存储在计算机中会丢失信息,因为是从一个连续的

  • 全概率公式和贝叶斯公式分别用于什么场合_贝叶斯公式的例题

    全概率公式和贝叶斯公式分别用于什么场合_贝叶斯公式的例题1.全概率公式:首先建立一个完备事件组的思想,其实全概就是已知第一阶段求第二阶段,比如第一阶段分A、B、C三种,然后A、B、C中均有D发生的概率,最后让你求D的概率P(D)=P(A)*P(D|A)+P(B)*P(D|B)+P(C)*P(D|C)2.贝叶斯公式:其实原本应该叫逆概公式,为了纪念贝叶斯这样取名而已.在全概公式理解的基础上,贝叶斯其实就是已知第二阶段反推第一阶段,这时候关键是

    2022年10月27日
  • ZABBIX4.4 安装及配置

    ZABBIX4.4 安装及配置

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号