当前位置:  编程技术>移动开发
本页文章导读:
    ▪【C跟指针】#if 0 #end if        【C和指针】#if 0 #end if一,“#if   0/  #if 1     ...     #endif”   的作用            1) code中定义的是一些调试版本的代码,此时code完全被编译器忽略。如果想让code生效,只需把#if .........
    ▪ Core Data浅谈系列之二 : 容易的CURD        Core Data浅谈系列之二 : 简单的CURD在上一篇中简单介绍了Core Data Stack,自上而下地对Core Data应用结构有个基本的认识,不过都是理论上的。这里就以上一篇的理论构建起一个可运行的Demo,执.........
    ▪ imx.536(cotex-a8核)的CAN驱动懂得一(probe)       imx.536(cotex-a8核)的CAN驱动理解一(probe)//理解imx536的can驱动还是从probe开始吧,2.6版本内核can驱动是归属于网络驱动 //所以我得先去把网络驱动几个重要结构体先找出来吧。前进吧!年轻人。 s.........

[1]【C跟指针】#if 0 #end if
    来源: 互联网  发布时间: 2014-02-18
【C和指针】#if 0 #end if

一,“#if   0/  #if 1     ...     #endif”   的作用

           1) code中定义的是一些调试版本的代码,此时code完全被编译器忽略。如果想让code生效,只需把#if 0改成#if 1

           2) #if 0还有一个重要的用途就是用来当成注释,如果你想要注释的程序很长,这个时候#if 0是最好的,保证不会犯错误

                  #if 1可以让其间的变量成为局部变量。

          3) 这个结构表示你先前写好的code,现在用不上了,又不想删除,就用这个方法,比注释方便。

二,例子

       

#include <iostream>

int main(void)
{
	int a = 0;
	#if 0
	a = 1;
	#endif
	
	printf("%d\n",a);
	return 0;
}

 


    
[2] Core Data浅谈系列之二 : 容易的CURD
    来源: 互联网  发布时间: 2014-02-18
Core Data浅谈系列之二 : 简单的CURD
在上一篇中简单介绍了Core Data Stack,自上而下地对Core Data应用结构有个基本的认识,不过都是理论上的。这里就以上一篇的理论构建起一个可运行的Demo,执行一些简单的增删改查操作。


(图片来自Apple)

首先,我们需要建立如上图的栈结构。因此,在ViewController里添加3个属性:
@interface ViewController : UIViewController

@property (nonatomic, retain) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain) NSPersistentStoreCoordinator *persistentStoreCoordinator;

@end

根据前文讨论的顺序,我们首先创建managedObjectModel(在那之前需要引入CoreData Framework):

- (NSManagedObjectModel *)managedObjectModel
{
    if (nil != _managedObjectModel) {
        return _managedObjectModel;
    }
    
    _managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
    return _managedObjectModel;
}
接着创建NSManagedObject的生存环境 —— NSManagedObjectContext:
- (NSManagedObjectContext *)managedObjectContext
{
    if (nil != _managedObjectContext) {
        return _managedObjectContext;
    }
    
    _managedObjectContext = [[NSManagedObjectContext alloc] init];
    return _managedObjectContext;
}
由于Demo会将数据存储到本地文件,所以还需要NSPersistentStoreCoordinator和NSManagedObjectContext配合。
下面是创建Core Data栈结构的完整代码:
#pragma mark - 
#pragma mark - Core Data Stack

- (NSManagedObjectModel *)managedObjectModel
{
    if (nil != _managedObjectModel) {
        return _managedObjectModel;
    }
    
    _managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
    return _managedObjectModel;
}

- (NSManagedObjectContext *)managedObjectContext
{
    if (nil != _managedObjectContext) {
        return _managedObjectContext;
    }
    
    _managedObjectContext = [[NSManagedObjectContext alloc] init];
    
    if (self.persistentStoreCoordinator) {
        [_managedObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator];
    }
    
    return _managedObjectContext;
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (nil != _persistentStoreCoordinator) {
        return _persistentStoreCoordinator;
    }
    
    NSString *storeType = NSSQLiteStoreType;
    NSString *storeName = @"cdNBA.sqlite";
    
    NSError *error = NULL;
    NSURL *storeURL = [NSURL fileURLWithPath:[[self applicationDocumentsDirectory] stringByAppendingPathComponent:storeName]];
    
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];
    if (![_persistentStoreCoordinator addPersistentStoreWithType:storeType configuration:nilURL:storeURL options:nil error:&error]) {
        NSLog(@"Error : %@\n", [error localizedDescription]);
        NSAssert1(YES, @"Failed to create store %@ with NSSQLiteStoreType", [storeURL path]);
    }
    
    return _persistentStoreCoordinator;
}

#pragma mark -
#pragma mark Application's Documents Directory

- (NSString *)applicationDocumentsDirectory
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
    return basePath;
}

在搭建完基础的Core Data栈结构后,就可以写一些简单的CURD代码了:

#pragma mark - 
#pragma mark - CURD Operations

- (BOOL)createTeamWithName:(NSString *)teamName city:(NSString *)teamCity
{
    if (!teamName || !teamCity) {
        return NO;
    }
    
    NSManagedObject *teamObject = [NSEntityDescription insertNewObjectForEntityForName:@"Team" inManagedObjectContext:self.managedObjectContext];
    [teamObject setValue:teamName forKey:@"name"];
    [teamObject setValue:teamCity forKey:@"city"];
    
    return YES;
}

- (NSArray *)fetchTeamList
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:[NSEntityDescription entityForName:@"Team" inManagedObjectContext:self.managedObjectContext]];
    
    NSError *error = NULL;
    NSArray *array = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    if (error) {
        NSLog(@"Error : %@\n", [error localizedDescription]);
    }
    
    [fetchRequest release], fetchRequest = nil;
    
    return array;
}

我们可以把读写的代码放到viewDidLoad函数中:

- (void)viewDidLoad
{
    [superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
    
    [self createTeamWithName:@"Heat"city:@"Miami"];
    [self createTeamWithName:@"Lakers"city:@"LA"];
    [self saveContext];
    
    NSArray *teamArray = [self fetchTeamList];
    if (teamArray) {
        for (NSManagedObject *teamObject in teamArray) {
            NSString *teamName = [teamObject valueForKey:@"name"];
            NSString *teamCity = [teamObject valueForKey:@"city"];
            NSLog(@"Team info : %@, %@\n", teamName, teamCity);
        }
    }
}

由于在context中创建的对象只是存在于内存中,所以我们还需要显式地把数据保存到sqlite文件里:

#pragma mark -
#pragma mark - Save Context

- (void)saveContext
{
    NSError *error = NULL;
    NSManagedObjectContext *moc = self.managedObjectContext;
    if (moc && [moc hasChanges] && ![moc save:&error]) {
        NSLog(@"Error %@, %@", error, [error localizedDescription]);
        abort();
    }
}
最后,就是跑一下Demo,检验一下结果。
执行过一次程序后,我们可以搜索下cdNBA.sqlite文件,然后查看里面的数据: 



同时,控制台也输出了数据:
2013-01-16 14:32:52.638 cdNBA[4717:c07] Team info : Heat, Miami
2013-01-16 14:32:52.639 cdNBA[4717:c07] Team info : Lakers, LA
Brief Talk About Core Data Series, Part 2 : Simple CURD 

Jason Lee @ Hangzhou
Blog : http://blog.csdn.net/jasonblog
Weibo : http://weibo.com/jasonmblog


    
[3] imx.536(cotex-a8核)的CAN驱动懂得一(probe)
    来源: 互联网  发布时间: 2014-02-18
imx.536(cotex-a8核)的CAN驱动理解一(probe)
//理解imx536的can驱动还是从probe开始吧,2.6版本内核can驱动是归属于网络驱动
//所以我得先去把网络驱动几个重要结构体先找出来吧。前进吧!年轻人。
static struct platform_driver flexcan_driver = {
	.driver = {
		   .name = FLEXCAN_DEVICE_NAME,
		   },
	.probe = flexcan_probe,
	.remove = flexcan_remove,
	.suspend = flexcan_suspend,
	.resume = flexcan_resume,
};

下面看probe

static int flexcan_probe(struct platform_device *pdev)
{
	//还是熟悉的struct net_device
	struct net_device *net;
	//这个函数估计得干大把大把的事吧,什么申请内存,什么初始化struct net_device及网络设备私有数据等
	net = flexcan_device_alloc(pdev, flexcan_setup);
	if (!net)
		return -ENOMEM;
	//注册网络设备
	if (register_netdev(net)) {
		flexcan_device_free(pdev);
		return -ENODEV;
	}
	return 0;
}
probe中主要是调用了flexcan_device_alloc,继续看flexcan_device_alloc

struct net_device *flexcan_device_alloc(struct platform_device *pdev,
					void (*setup) (struct net_device *dev))
{
	//can私有数据结构体
	struct flexcan_device *flexcan;
	struct net_device *net;
	int i, num;
	//申请内存,初始化net
	net = alloc_netdev(sizeof(*flexcan), "can%d", setup);
	if (net == NULL) {
		printk(KERN_ERR "Allocate netdevice for FlexCAN fail!\n");
		return NULL;
	}
	//flexcan指向net尾端,即私有数据结构体起始地址
	flexcan = netdev_priv(net);
	memset(flexcan, 0, sizeof(*flexcan));
	//互斥锁初始化
	mutex_init(&flexcan->mutex);
	//初始化内核定时器
	init_timer(&flexcan->timer);

	flexcan->dev = pdev;
	//注册中断,映射虚拟内存
	if (flexcan_device_attach(flexcan)) {
		printk(KERN_ERR "Attach FlexCAN fail!\n");
		free_netdev(net);
		return NULL;
	}
	//把板级配置文件中设置的struct flexcan_platform_data中的值,传递给flexcan
	flexcan_device_default(flexcan);
	//根据can的波特率去算br_presdiv,br_propseg,br_pseg1,br_pseg2这些变量的值
	//因为flexcan->bitrate值未确定,所以在我的板上,这个函数不起效果
	flexcan_set_bitrate(flexcan, flexcan->bitrate);
	//重新计算波特率,保存在flexcan
	flexcan_update_bitrate(flexcan);

	//ARRAY_SIZE作用是取数组元素个数
	num = ARRAY_SIZE(flexcan_dev_attr);
	//device_create_file,添加属性文件,我的理解最终会设置文件系统sys目录下一些设备属性文件
	//这些设备文件是在调用device_create时生成的。device_create这个函数什么时候调用的呢,这个就需要udev
	//udev是什么?udev是设备管理器,能自动生成设备节点。
	//在dm9000驱动里不知道为什么没看到这个函数?
	for (i = 0; i < num; i++) {
		if (device_create_file(&pdev->dev, flexcan_dev_attr + i)) {
			printk(KERN_ERR "Create attribute file fail!\n");
			break;
		}
	}
	//上面操作的反向操作
	if (i != num) {
		for (; i >= 0; i--)
			device_remove_file(&pdev->dev, flexcan_dev_attr + i);
		free_netdev(net);
		return NULL;
	}
	//保存net为设备私有数据
	dev_set_drvdata(&pdev->dev, net);
	return net;
}
flexcan_device_alloc中最重要的几个函数flexcan_device_attach,flexcan_device_default,flexcan_set_bitratef,lexcan_update_bitrate
下面看看这个函数的代码,看它们都干了什么?

static void flexcan_set_bitrate(struct flexcan_device *flexcan, int bitrate)
{
	/* TODO:: implement in future
	 * based on the bitrate to get the timing of
	 * presdiv, pseg1, pseg2, propseg
	 */
	int i, rate, div;
	bool found = false;
	struct time_segment *segment;
	rate = clk_get_rate(flexcan->clk);

	if (!bitrate)
		bitrate = DEFAULT_BITRATE;
	//如果时钟正好是波特率的整数倍
	if (rate % bitrate == 0) 
	{
		//根据时钟是波特率的倍数去推算br_presdiv,br_propseg,br_pseg1,br_pseg2
		div = rate / bitrate;
		for (i = TIME_SEGMENT_MID; i <= TIME_SEGMENT_MAX; i++) 
		{
			if (div % i == 0) {
				found = true;
				break;
			}
		}
		if (!found) {
			for (i = TIME_SEGMENT_MID - 1;
					    i >= TIME_SEGMENT_MIN; i--) {
				if (div % i == 0) {
					found = true;
					break;
				}
			}

		}
	}

	if (found) {
		//time_segments数组中列出了各种br_presdiv,br_propseg,br_pseg1,br_pseg2组合值
		//根据以上推算,确定i值,从而确定br_presdiv,br_propseg,br_pseg1,br_pseg2的值
		segment = &time_segments[i - TIME_SEGMENT_MIN];
		flexcan->br_presdiv = div/i - 1;
		flexcan->br_propseg = segment->propseg;
		flexcan->br_pseg1 = segment->pseg1;
		flexcan->br_pseg2 = segment->pseg2;
		flexcan->bitrate = bitrate;
	} else {
		pr_info("The bitrate %d can't supported with clock \
				    rate of %d \n", bitrate, rate);
	}
}


static void flexcan_update_bitrate(struct flexcan_device *flexcan)
{
	int rate, div;
	//板级配置文件中设置的
	struct flexcan_platform_data *plat_data;
	plat_data = flexcan->dev->dev.platform_data;
	//如果板级配置文件中,struct flexcan_platform_data中root_clk_id配置了
	if (plat_data->root_clk_id)
		rate = clk_get_rate(flexcan->clk);
	else 
	{
		//若struct flexcan_platform_data中root_clk_id未被配置,再看br_clksrc是否被配置成1	
		if (flexcan->br_clksrc)
			rate = clk_get_rate(flexcan->clk);
		//在我的imx536项目中,以上两个变量都未被配置,所以会执行以下代码
		else 
		{
			struct clk *clk;
			clk = clk_get(NULL, "ckih");
			if (!clk)
				return;
			//获取can时钟频率
			rate = clk_get_rate(clk);
			clk_put(clk);
		}
	}
	if (!rate)
		return;
	//计算can传输速率
	//其中br_presdiv,br_propseg,br_pseg1,br_pseg2,这些参数都是在板级配置文件中设置的
	//所以可以实现由用户自己配置CAN波特率
	div = (flexcan->br_presdiv + 1);
	div *=
	    (flexcan->br_propseg + flexcan->br_pseg1 + flexcan->br_pseg2 + 4);
	flexcan->bitrate = (rate + div - 1) / div;
}

static int flexcan_device_attach(struct flexcan_device *flexcan)
{
	int ret;
	struct resource *res;
	struct platform_device *pdev = flexcan->dev;
	struct flexcan_platform_data *plat_data = (pdev->dev).platform_data;
	struct clk *can_root_clk;

	//看到了熟悉的身影了
	res = platform_get_resource(flexcan->dev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENODEV;
	//内存映射
	flexcan->io_base = ioremap(res->start, res->end - res->start + 1);
	if (!flexcan->io_base)
		return -ENOMEM;
	//咋没直接注册中断?
	flexcan->irq = platform_get_irq(flexcan->dev, 0);
	if (!flexcan->irq) {
		ret = -ENODEV;
		goto no_irq_err;
	}

	ret = -EINVAL;
	if (plat_data) {
		if (plat_data->core_reg) {
			flexcan->core_reg = regulator_get(&pdev->dev,
							  plat_data->core_reg);
			if (!flexcan->core_reg)
				goto plat_err;
		}

		if (plat_data->io_reg) {
			flexcan->io_reg = regulator_get(&pdev->dev,
							plat_data->io_reg);
			if (!flexcan->io_reg)
				goto plat_err;
		}
	}
	flexcan->clk = clk_get(&(flexcan->dev)->dev, "can_clk");
	//如果板级配置文件中root_clk_id被配置了,can时钟源变成了root_clk_id
	if (plat_data->root_clk_id) 
	{
		can_root_clk = clk_get(NULL, plat_data->root_clk_id);
		clk_set_parent(flexcan->clk, can_root_clk);
	}
	flexcan->hwmb = (struct can_hw_mb *)(flexcan->io_base + CAN_MB_BASE);
	flexcan->rx_mask = (unsigned int *)(flexcan->io_base + CAN_RXMASK_BASE);

	return 0;
	//以后得多学学内核纠错处理了
	  plat_err:
	if (flexcan->core_reg) {
		regulator_put(flexcan->core_reg);
		flexcan->core_reg = NULL;
	}
      no_irq_err:
	if (flexcan->io_base)
		iounmap(flexcan->io_base);
	return ret;
}






    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3