#include <linux/kernel.h> #include <linux/types.h> #include <linux/i2c.h> unsigned char mac_read(unsigned char command) { int ret; unsigned char buf; struct i2c_adapter *a = i2c_get_adapter(1); struct i2c_msg msg[2] = { { .addr = 0x50, .flags = 0, .buf = &command, .len = 1 }, { .addr = 0x50, .flags = I2C_M_RD, .buf = &buf, .len = 1 } }; ret = i2c_transfer(a, msg, 2); if (ret < 0) { printk("[mac_write] i2c_transfer error\n"); } return buf; } EXPORT_SYMBOL(mac_read); int mac_write(unsigned char reg, unsigned char data) { int ret; unsigned char buf [] = { reg, data }; struct i2c_adapter *a = i2c_get_adapter(1); struct i2c_msg msg[1] = { { .addr = 0x50, .flags = 0, .buf = buf, .len = 2 } }; ret = i2c_transfer(a, msg, 1); if (ret < 0) { printk("[mac_write] i2c_transfer error\n"); } return ret; } EXPORT_SYMBOL(mac_write);
写这个程序之前我在思考是网卡先驱动获取mac先呢,还是i2c子系统的i2c适配器先初始化好呢?
加了些打印语句判断之后,证明我的板子是i2c子系统的i2c适配器先初始化好,于是可以堂而皇之的用i2c接口的api
如果不是就得用__raw_writew,__raw_readw这些底层寄存器操作函数,像单片机一样来读取mac地址,
不然网卡获取不到固定mac,ip在dhcp获取中就会变动,
写入不着急可以等到i2c子系统初始化好再说
先修改makefile添加该c文件的依赖,让它编译进内核
(这里我调试板子使用nfs的,内核存放于sd卡中,正常逻辑我每次改内核就得把sd拿出来拷贝一次,相当的麻烦
我把sd卡挂载在/media/card中,内核编译后uImage自动复制一份到nfs目录中,超级终端中利用cp命令将unfs目录中的Image复制到挂载的/media/card目录下,替换掉旧的uImage)
在网卡驱动中添加声明
extern unsigned char mac_read(unsigned char command);
extern int mac_write(unsigned char reg, unsigned char data);
在网卡平台设备的probe中这样引用
for (i = 0; i < 6; i++)
pdata->mac_addr[i] = mac_read(i+offset); //读方法的调用
printk("eth%s MAC addr:",(offset==1)?"0":"1");
printk("%pM\n", pdata->mac_addr);
双网卡的所以有个不同的offset偏移量,表示mac地址在24c02的偏移位置
下面有代码
if (!is_valid_ether_addr(priv->mac_addr)) { //判断mac地址是否存在,就是24c02是否写入了合适的mac地址了
/* Use random MAC if none passed */
random_ether_addr(priv->mac_addr); //没有的话会产生随机的mac地址
printk(KERN_WARNING "%s: using random MAC addr: %pM\n",
__func__, priv->mac_addr);
for (i = 0; i < 6; i++){
mac_write(offset+i,priv->mac_addr[i]); //那么就将随机分配的mac地址写入24c02中,省点事去往24c02烧mac地址
msleep(1); //加个延时 写太快 有时候会写失败
}
}
读方法会打印出来结果
写方法用i2c工具在应用层查看写入是否与自己期望值一样
Xcode4.2(iOS 5)以后启用了ARC技术,虽然4.2以后版本仍然可以不开启ARC,但是我们在建工程的时候有时为了不想管理内存然后就启用了ARC,但是再开发过程中需要用到第三开发类库,而这些第三方类库或是没做更新而不支持ARC,然后编译时就出现下列错误:
'release' is unavailable: not available in automatic reference counting mode ARC forbids explicit message send of 'release' 'autorelease' is unavailable: not available in automatic reference counting mode ARC forbids explicit message send of 'autorelease' 'retain' is unavailable: not available in automatic reference counting mode ARC forbids explicit message send of 'retain'
解决办法:
1.在targets->build phases中修改compiler Flags属性,添加:-fobjc-arc,就可以让旧的工程支持arc;
2.在targets->build phases中修改compiler Flags属性,添加:-fno-objc-arc,就可以让原来支持arc的工程不使用arc,对于大部分第三方类库来说都可以顺利编译通过
Gallery与衍生BaseAdapter
本范例的重点在于如何设置图片的宽高以及防止图片Layout的大小,在此我们改写一个继承自BaseAdapter的ImageAdapter容器来存放图片,通过ImageView.setScaleTyper()的方法来改变图片的显示,再通过setLayoutParams()方法来改变Layout的宽高。
主程序有两大重点:一是ImageAdapter继承BaseAdapter class的未实现方法的重写构造;二是Gallery的OnItemClick()方法与图片及Layout宽高设置。
下面是程序完整代码:
package com.example.test01; import android.app.Activity; importandroid.content.Context; importandroid.content.res.TypedArray; import android.os.Bundle; import android.view.Menu; import android.view.View; importandroid.view.ViewGroup; importandroid.widget.AdapterView.OnItemClickListener; importandroid.widget.AdapterView; importandroid.widget.BaseAdapter; importandroid.widget.Gallery; importandroid.widget.ImageView; import android.widget.Toast; public class MainActivityextends Activity { Gallery gallery01; //构建Integer array并取得预加载Drawable的图片id private Integer[] myImageIds = { R.drawable.a11, R.drawable.a12, R.drawable.a5, R.drawable.a7, R.drawable.a9, }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gallery01 = (Gallery)findViewById(R.id.gallery01); //添加ImageAdapter并设置给Gallery对象 gallery01.setAdapter(new ImageAdapter(this)); //设置一个itemClickListener并Toast被单击图片的位置 gallery01.setOnItemClickListener(newOnItemClickListener() { public void onItemClick(AdapterView<?>arg0, View arg1, int arg2,long arg3) { Toast.makeText(getApplicationContext(),getString(R.string.my_gallery_text_pre) + arg2 +getString(R.string.my_gallery_text_post), Toast.LENGTH_LONG).show(); } }); } //改写BaseAdapter自定义ImageAdapter class public class ImageAdapter extends BaseAdapter { //声明变量 int mGalleryItemBackground; private Context context; public ImageAdapter(Context c) { context = c; //使用在res/values/attrs.xml中的<declare-styleable>定义*Gallery属性 TypedArray a =obtainStyledAttributes(R.styleable.Gallery); //取得Gallery属性的Index id mGalleryItemBackground =a.getResourceId(R.styleable.Gallery_android_galleryItemBackground, 0); //让对象的styleable属性能够反复使用 a.recycle(); } public int getCount() { return myImageIds.length; } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } //重写的方法getView,返回一个View对象 public View getView(int position, View convertView,ViewGroup parent) { //产生ImageView对象 ImageView i = new ImageView(context); //设置图片给imageView对象 i.setImageResource(myImageIds[position]); //重新设置图片的高 i.setScaleType(ImageView.ScaleType.FIT_XY); //重新设置Layout的宽高 i.setLayoutParams(new Gallery.LayoutParams(136,88)); //设置Gallery的背景图 i.setBackgroundResource(mGalleryItemBackground); //返回imageView对象 return i; } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action barif it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }